observable_tree/
model.rs

1use std::{
2    collections::{BTreeMap, HashMap},
3    convert::{TryFrom, TryInto},
4};
5
6/// Available types to use as `BTree` values.
7#[derive(Debug, Clone, PartialEq)]
8pub enum Types {
9    Char(char),
10    Integer(isize),
11    UInteger(usize),
12    String(String),
13    Float(f64),
14    Boolean(bool),
15    Vector(Vec<Types>),
16    HashMap(HashMap<String, Types>),
17    BTreeMap(BTreeMap<String, Types>),
18    KeyValue(String, Box<Types>),
19    Nil,
20}
21
22impl From<char> for Types {
23    fn from(t: char) -> Self {
24        Types::Char(t)
25    }
26}
27
28impl From<isize> for Types {
29    fn from(t: isize) -> Self {
30        Types::Integer(t)
31    }
32}
33
34impl From<i32> for Types {
35    fn from(t: i32) -> Self {
36        Types::Integer(t as isize)
37    }
38}
39
40impl From<i64> for Types {
41    fn from(t: i64) -> Self {
42        Types::Integer(t as isize)
43    }
44}
45
46impl From<usize> for Types {
47    fn from(t: usize) -> Self {
48        Types::UInteger(t)
49    }
50}
51
52impl From<String> for Types {
53    fn from(t: String) -> Self {
54        Types::String(t)
55    }
56}
57
58impl From<&str> for Types {
59    fn from(t: &str) -> Self {
60        Types::String(t.to_owned())
61    }
62}
63
64impl From<f64> for Types {
65    fn from(t: f64) -> Self {
66        Types::Float(t)
67    }
68}
69
70impl From<bool> for Types {
71    fn from(t: bool) -> Self {
72        Types::Boolean(t)
73    }
74}
75
76impl<T: Into<Types>> From<Vec<T>> for Types {
77    fn from(t: Vec<T>) -> Self {
78        let aux = t.into_iter().map(|e| e.into()).collect::<Vec<Types>>();
79        Types::Vector(aux)
80    }
81}
82
83impl<T: Into<Types>> From<HashMap<String, T>> for Types {
84    fn from(t: HashMap<String, T>) -> Self {
85        let aux = t
86            .into_iter()
87            .map(|(k, v)| (k, v.into()))
88            .collect::<HashMap<String, Types>>();
89        Types::HashMap(aux)
90    }
91}
92
93impl<T: Into<Types>> From<BTreeMap<String, T>> for Types {
94    fn from(t: BTreeMap<String, T>) -> Self {
95        let aux = t
96            .into_iter()
97            .map(|(k, v)| (k, v.into()))
98            .collect::<BTreeMap<String, Types>>();
99        Types::BTreeMap(aux)
100    }
101}
102
103impl<T: Into<Types>> From<(String, T)> for Types {
104    fn from(t: (String, T)) -> Self {
105        let (k, v) = t;
106        let (k, v): (String, Box<Types>) = (k, Box::new(v.into()));
107
108        Types::KeyValue(k, v)
109    }
110}
111
112impl<T: Into<Types>> From<Option<T>> for Types {
113    fn from(t: Option<T>) -> Self {
114        match t {
115            None => Types::Nil,
116            Some(v) => v.into(),
117        }
118    }
119}
120
121impl TryInto<isize> for Types {
122    type Error = String;
123
124    fn try_into(self) -> Result<isize, Self::Error> {
125        match self {
126            Types::Integer(t) => Ok(t),
127            _ => Err(format!("Could not convert {:?} to isize", self)),
128        }
129    }
130}
131
132impl TryInto<usize> for Types {
133    type Error = String;
134
135    fn try_into(self) -> Result<usize, Self::Error> {
136        match self {
137            Types::UInteger(t) => Ok(t),
138            _ => Err(format!("Could not convert {:?} to usize", self)),
139        }
140    }
141}
142
143impl TryInto<char> for Types {
144    type Error = String;
145
146    fn try_into(self) -> Result<char, Self::Error> {
147        match self {
148            Types::Char(t) => Ok(t),
149            _ => Err(format!("Could not convert {:?} to char", self)),
150        }
151    }
152}
153
154impl TryInto<f64> for Types {
155    type Error = String;
156
157    fn try_into(self) -> Result<f64, Self::Error> {
158        match self {
159            Types::Float(t) => Ok(t),
160            _ => Err(format!("Could not convert {:?} to f64", self)),
161        }
162    }
163}
164
165impl TryInto<bool> for Types {
166    type Error = String;
167
168    fn try_into(self) -> Result<bool, Self::Error> {
169        match self {
170            Types::Boolean(t) => Ok(t),
171            _ => Err(format!("Could not convert {:?} to bool", self)),
172        }
173    }
174}
175
176impl TryInto<String> for Types {
177    type Error = String;
178
179    fn try_into(self) -> Result<String, Self::Error> {
180        match self {
181            Types::String(t) => Ok(t),
182            _ => Err(format!("Could not convert {:?} to String", self)),
183        }
184    }
185}
186
187impl<T: TryFrom<Types>> TryInto<(String, T)> for Types {
188    type Error = String;
189
190    fn try_into(self) -> Result<(String, T), Self::Error> {
191        let err = format!("Could not convert {:?} to KeyValue", self);
192        match self {
193            Types::KeyValue(k, v) => Ok((k, (*v).try_into().map_err(|_| err.clone())?)),
194            _ => Err(format!("Could not convert {:?} to KeyValue", self)),
195        }
196    }
197}
198
199impl<T: TryFrom<Types>> TryInto<Vec<T>> for Types {
200    type Error = String;
201
202    fn try_into(self) -> Result<Vec<T>, Self::Error> {
203        let err = format!("Could not convert {:?} to Vec<T>", self);
204        match self {
205            Types::Vector(t) => t
206                .into_iter()
207                .map(|e| e.try_into().map_err(|_| err.clone()))
208                .collect::<Result<Vec<T>, String>>(),
209            _ => Err(err),
210        }
211    }
212}
213
214impl<T: TryFrom<Types>> TryInto<HashMap<String, T>> for Types {
215    type Error = String;
216
217    fn try_into(self) -> Result<HashMap<String, T>, Self::Error> {
218        let err = format!("Could not convert {:?} to HashMap<String, T>", self);
219        match self {
220            Types::HashMap(t) => {
221                let mut has_error = false;
222                let hm = t
223                    .into_iter()
224                    .map(|(k, v)| (k, v.try_into().map_err(|_| err.clone())))
225                    .fold(
226                        HashMap::new(),
227                        |mut acc, (k, v): (String, Result<T, String>)| {
228                            if let Ok(t) = v {
229                                acc.insert(k, t);
230                            } else {
231                                has_error = true;
232                            }
233                            acc
234                        },
235                    );
236
237                if has_error {
238                    Err(err)
239                } else {
240                    Ok(hm)
241                }
242            }
243            _ => Err(err),
244        }
245    }
246}
247
248impl<T: TryFrom<Types>> TryInto<BTreeMap<String, T>> for Types {
249    type Error = String;
250
251    fn try_into(self) -> Result<BTreeMap<String, T>, Self::Error> {
252        let err = format!("Could not convert {:?} to BTreeMap<String, T>", self);
253        match self {
254            Types::BTreeMap(t) => {
255                let mut has_error = false;
256                let hm = t
257                    .into_iter()
258                    .map(|(k, v)| (k, v.try_into().map_err(|_| err.clone())))
259                    .fold(
260                        BTreeMap::new(),
261                        |mut acc, (k, v): (String, Result<T, String>)| {
262                            if let Ok(t) = v {
263                                acc.insert(k, t);
264                            } else {
265                                has_error = true;
266                            }
267                            acc
268                        },
269                    );
270
271                if has_error {
272                    Err(err)
273                } else {
274                    Ok(hm)
275                }
276            }
277            _ => Err(err),
278        }
279    }
280}