-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfrom.rs
75 lines (69 loc) · 2.07 KB
/
from.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
extern crate cirru_edn;
use std::convert::TryFrom;
use std::{collections::HashMap, convert::TryInto, iter::FromIterator};
use cirru_edn::{Edn, EdnMapView, EdnTag};
#[derive(Debug, Clone, PartialEq)]
struct Cat {
name: String,
category: EdnTag,
weight: f64,
skills: Vec<EdnTag>,
counts: HashMap<String, i64>,
owner: Option<String>,
}
impl TryFrom<Edn> for Cat {
type Error = String;
fn try_from(value: Edn) -> Result<Self, Self::Error> {
let c = Cat {
name: value.view_map()?.str_get("name").unwrap_or(&Edn::Nil).try_into()?,
category: value.view_map()?.get_or_nil("category").try_into()?,
weight: value.view_map()?.get_or_nil("weight").try_into()?,
skills: value.view_map()?.get_or_nil("skills").try_into()?,
counts: value.view_map()?.get_or_nil("counts").try_into()?,
owner: {
let v = value.view_map()?.get_or_nil("owner");
if v == Edn::Nil {
None
} else {
Some(v.try_into()?)
}
},
};
Ok(c)
}
}
impl From<Cat> for Edn {
fn from(x: Cat) -> Edn {
Edn::Map(EdnMapView(HashMap::from_iter([
("name".into(), x.name.into()),
("category".into(), x.category.into()),
("weight".into(), x.weight.into()),
("skills".into(), x.skills.into()),
("counts".into(), x.counts.into()),
("owner".into(), x.owner.into()),
])))
}
}
fn main() -> Result<(), String> {
let data: Edn = Edn::Map(EdnMapView(HashMap::from_iter([
("name".into(), Edn::str("Kii")),
("category".into(), Edn::tag("ying")),
// ("weight".into(), Edn::Number(1.0)),
// (
// "skills".into(),
// Edn::List(vec![Edn::kwd("eating"), Edn::kwd("sleeping")]),
// ),
(
"counts".into(),
Edn::from(HashMap::from_iter([(Edn::from("a"), Edn::Number(1.))])),
),
// ("owner".into(), Edn::str("Kii")),
("owner".into(), Edn::Nil),
])));
let cat: Cat = data.try_into()?;
println!("new {:?}", cat);
assert_eq!(cat.name, "Kii");
let data2: Edn = cat.into();
assert_eq!(data2.view_map()?.get_or_nil("name"), Edn::str("Kii"));
Ok(())
}