Skip to content

Commit 91f8ca2

Browse files
committed
Add .get for Tagged type that resolves namespaces.
1 parent 9c15470 commit 91f8ca2

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

examples/get-nth.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,26 @@ fn maybe_forty_two<'a>(edn: &'a Edn<'a>) -> Option<&'a Edn<'a>> {
1616
.nth(2)
1717
}
1818

19+
fn namespace_get() {
20+
// (def edn-data (edn/read-string "#:thingy {:foo \"bar\" :baz/bar \"qux\" 42 24}"))
21+
let edn_data = edn::read_string(r#"#:thingy {:foo "bar" :baz/bar "qux" 42 24}"#).unwrap();
22+
23+
// (get edn-data 42) -> 24
24+
assert_eq!(edn_data.get(&Edn::Int(42)), Some(&Edn::Int(24)));
25+
// (get edn-data :foo) -> nil
26+
assert_eq!(edn_data.get(&Edn::Key("foo")), None);
27+
// (get edn-data :thingy/foo) -> "bar"
28+
assert_eq!(edn_data.get(&Edn::Key("thingy/foo")), Some(&Edn::Str("bar")));
29+
// (get edn-data :baz/bar) -> "qux"
30+
assert_eq!(edn_data.get(&Edn::Key("baz/bar")), Some(&Edn::Str("qux")));
31+
}
32+
1933
fn main() {
2034
let e = edn::read_string("{:foo {猫 {{:foo :bar} [1 2 42 3]}}}").unwrap();
2135
let edn = maybe_forty_two(&e).unwrap();
2236
assert_eq!(edn, &Edn::Int(42));
37+
38+
namespace_get();
2339
}
2440

2541
#[test]

src/edn.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,36 @@ impl Edn<'_> {
8080
if let Some(l) = m.get(e) {
8181
return Some(l);
8282
}
83+
} else if let Edn::Tagged(tag, m) = self {
84+
if let Edn::Key(e) = e {
85+
// Break out early if there's no namespaces
86+
if !e.contains('/') {
87+
return None;
88+
}
89+
90+
// ignore the leading ':'
91+
if !tag.starts_with(':') {
92+
return None;
93+
}
94+
let tag = tag.get(1..)?;
95+
96+
// check if the Key starts with the saved Tag
97+
if e.starts_with(tag) {
98+
let (_, key) = e.rsplit_once(tag)?;
99+
100+
// ensure there's a '/' and strip it
101+
if key.chars().nth(0) != Some('/') {
102+
return None;
103+
}
104+
let key = key.get(1..)?;
105+
106+
return m.get(&Edn::Key(key));
107+
}
108+
return m.get(&Edn::Key(e));
109+
}
110+
111+
// Cover cases where it's not a keyword
112+
return m.get(e);
83113
}
84114
None
85115
}

0 commit comments

Comments
 (0)