json_node/
to_json_node.rs

1use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
2use std::error::Error;
3
4use crate::{JsonNode, JsonPropertyMap};
5
6/// A trait for converting a type into a `JsonNode`.
7pub trait ToJsonNode {
8    /// Converts the type into a `JsonNode`.
9    ///
10    /// # Implementing the Trait
11    ///
12    /// ```
13    /// use json_node::{JsonNode, JsonPropertyMap, ToJsonNode};
14    ///     
15    /// // Define some struct you want to convert into a `JsonNode`.
16    /// struct Person {
17    ///     name: String,
18    ///     age: i64,
19    /// }
20    /// 
21    /// // Implement the trait for your struct.
22    /// impl ToJsonNode for Person {
23    ///     fn to_json_node(&self) -> JsonNode {
24    ///         // Create a `JsonNode::Object` with the properties of your struct.
25    ///         JsonNode::Object(JsonPropertyMap::from([
26    ///             // The key is the name of the property. The value is the value of the property.
27    ///             ("name".to_owned(), JsonNode::String(self.name.clone())),
28    ///             // You can convert any type that implements `ToJsonNode` into a `JsonNode`.
29    ///             ("age".to_owned(), self.age.to_json_node()),
30    ///         ]))
31    ///     }
32    /// }
33    /// 
34    /// let person = Person {
35    ///     name: "John Doe".to_owned(),
36    ///     age: 42,
37    /// };
38    /// 
39    /// let person_node = person.to_json_node();
40    /// let person_node_json = person_node.to_json_string();
41    /// assert_eq!(
42    ///     person_node_json,
43    ///     r#"{"name":"John Doe","age":42}"#
44    /// );
45    /// ```
46    fn to_json_node(&self) -> JsonNode;
47}
48
49impl ToJsonNode for String {
50    fn to_json_node(&self) -> JsonNode {
51        JsonNode::String(self.clone())
52    }
53}
54
55impl ToJsonNode for &str {
56    fn to_json_node(&self) -> JsonNode {
57        JsonNode::String(self.to_string())
58    }
59}
60
61impl ToJsonNode for i32 {
62    fn to_json_node(&self) -> JsonNode {
63        JsonNode::Integer(i64::from(*self))
64    }
65}
66
67impl ToJsonNode for i64 {
68    fn to_json_node(&self) -> JsonNode {
69        JsonNode::Integer(*self)
70    }
71}
72
73impl ToJsonNode for f32 {
74    fn to_json_node(&self) -> JsonNode {
75        JsonNode::Float(f64::from(*self))
76    }
77}
78
79impl ToJsonNode for f64 {
80    fn to_json_node(&self) -> JsonNode {
81        JsonNode::Float(*self)
82    }
83}
84
85impl ToJsonNode for u32 {
86    fn to_json_node(&self) -> JsonNode {
87        JsonNode::Integer(i64::from(*self))
88    }
89}
90
91impl ToJsonNode for bool {
92    fn to_json_node(&self) -> JsonNode {
93        JsonNode::Boolean(*self)
94    }
95}
96
97impl ToJsonNode for Option<String> {
98    fn to_json_node(&self) -> JsonNode {
99        match self {
100            Some(value) => JsonNode::String(value.clone()),
101            None => JsonNode::Null,
102        }
103    }
104}
105
106impl ToJsonNode for Option<&str> {
107    fn to_json_node(&self) -> JsonNode {
108        match self {
109            Some(value) => JsonNode::String(value.to_string()),
110            None => JsonNode::Null,
111        }
112    }
113}
114
115impl ToJsonNode for Option<i32> {
116    fn to_json_node(&self) -> JsonNode {
117        match self {
118            Some(value) => JsonNode::Integer(i64::from(*value)),
119            None => JsonNode::Null,
120        }
121    }
122}
123
124impl ToJsonNode for Option<i64> {
125    fn to_json_node(&self) -> JsonNode {
126        match self {
127            Some(value) => JsonNode::Integer(*value),
128            None => JsonNode::Null,
129        }
130    }
131}
132
133impl ToJsonNode for Option<f32> {
134    fn to_json_node(&self) -> JsonNode {
135        match self {
136            Some(value) => JsonNode::Float(f64::from(*value)),
137            None => JsonNode::Null,
138        }
139    }
140}
141
142impl ToJsonNode for Option<f64> {
143    fn to_json_node(&self) -> JsonNode {
144        match self {
145            Some(value) => JsonNode::Float(*value),
146            None => JsonNode::Null,
147        }
148    }
149}
150
151impl ToJsonNode for Option<u32> {
152    fn to_json_node(&self) -> JsonNode {
153        match self {
154            Some(value) => JsonNode::Integer(i64::from(*value)),
155            None => JsonNode::Null,
156        }
157    }
158}
159
160impl ToJsonNode for Option<bool> {
161    fn to_json_node(&self) -> JsonNode {
162        match self {
163            Some(value) => JsonNode::Boolean(*value),
164            None => JsonNode::Null,
165        }
166    }
167}
168
169impl<E: Error> ToJsonNode for Result<String, E> {
170    fn to_json_node(&self) -> JsonNode {
171        match self {
172            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
173                ("type".to_string(), "ok".to_json_node()),
174                ("value".to_string(), value.to_json_node()),
175            ])),
176            Err(_) => JsonNode::Object(JsonPropertyMap::from([
177                ("type".to_string(), "error".to_json_node()),
178                ("error".to_string(), "Could not convert to JSON".to_json_node()),
179            ])),
180        }
181    }
182}
183
184impl<E: Error> ToJsonNode for Result<&str, E> {
185    fn to_json_node(&self) -> JsonNode {
186        match self {
187            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
188                ("type".to_string(), "ok".to_json_node()),
189                ("value".to_string(), value.to_json_node()),
190            ])),
191            Err(_) => JsonNode::Object(JsonPropertyMap::from([
192                ("type".to_string(), "error".to_json_node()),
193                ("error".to_string(), "Could not convert to JSON".to_json_node()),
194            ])),
195        }
196    }
197}
198
199impl<E: Error> ToJsonNode for Result<i32, E> {
200    fn to_json_node(&self) -> JsonNode {
201        match self {
202            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
203                ("type".to_string(), "ok".to_json_node()),
204                ("value".to_string(), value.to_json_node()),
205            ])),
206            Err(_) => JsonNode::Object(JsonPropertyMap::from([
207                ("type".to_string(), "error".to_json_node()),
208                ("error".to_string(), "Could not convert to JSON".to_json_node()),
209            ])),
210        }
211    }
212}
213
214impl<E: Error> ToJsonNode for Result<i64, E> {
215    fn to_json_node(&self) -> JsonNode {
216        match self {
217            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
218                ("type".to_string(), "ok".to_json_node()),
219                ("value".to_string(), value.to_json_node()),
220            ])),
221            Err(_) => JsonNode::Object(JsonPropertyMap::from([
222                ("type".to_string(), "error".to_json_node()),
223                ("error".to_string(), "Could not convert to JSON".to_json_node()),
224            ])),
225        }
226    }
227}
228
229impl<E: Error> ToJsonNode for Result<f32, E> {
230    fn to_json_node(&self) -> JsonNode {
231        match self {
232            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
233                ("type".to_string(), "ok".to_json_node()),
234                ("value".to_string(), value.to_json_node()),
235            ])),
236            Err(_) => JsonNode::Object(JsonPropertyMap::from([
237                ("type".to_string(), "error".to_json_node()),
238                ("error".to_string(), "Could not convert to JSON".to_json_node()),
239            ])),
240        }
241    }
242}
243
244impl<E: Error> ToJsonNode for Result<f64, E> {
245    fn to_json_node(&self) -> JsonNode {
246        match self {
247            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
248                ("type".to_string(), "ok".to_json_node()),
249                ("value".to_string(), value.to_json_node()),
250            ])),
251            Err(_) => JsonNode::Object(JsonPropertyMap::from([
252                ("type".to_string(), "error".to_json_node()),
253                ("error".to_string(), "Could not convert to JSON".to_json_node()),
254            ])),
255        }
256    }
257}
258
259impl<E: Error> ToJsonNode for Result<u32, E> {
260    fn to_json_node(&self) -> JsonNode {
261        match self {
262            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
263                ("type".to_string(), "ok".to_json_node()),
264                ("value".to_string(), value.to_json_node()),
265            ])),
266            Err(_) => JsonNode::Object(JsonPropertyMap::from([
267                ("type".to_string(), "error".to_json_node()),
268                ("error".to_string(), "Could not convert to JSON".to_json_node()),
269            ])),
270        }
271    }
272}
273
274impl<E: Error> ToJsonNode for Result<bool, E> {
275    fn to_json_node(&self) -> JsonNode {
276        match self {
277            Ok(value) => JsonNode::Object(JsonPropertyMap::from([
278                ("type".to_string(), "ok".to_json_node()),
279                ("value".to_string(), value.to_json_node()),
280            ])),
281            Err(_) => JsonNode::Object(JsonPropertyMap::from([
282                ("type".to_string(), "error".to_json_node()),
283                ("error".to_string(), "Could not convert to JSON".to_json_node()),
284            ])),
285        }
286    }
287}
288
289impl<T: ToJsonNode, const COUNT: usize> ToJsonNode for [T; COUNT] {
290    fn to_json_node(&self) -> JsonNode {
291        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
292    }
293}
294
295impl<T: ToJsonNode> ToJsonNode for [T] {
296    fn to_json_node(&self) -> JsonNode {
297        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
298    }
299}
300
301impl<T: ToJsonNode> ToJsonNode for Vec<T> {
302    fn to_json_node(&self) -> JsonNode {
303        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
304    }
305}
306
307impl<T: ToJsonNode> ToJsonNode for VecDeque<T> {
308    fn to_json_node(&self) -> JsonNode {
309        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
310    }
311}
312
313impl<T: ToJsonNode> ToJsonNode for LinkedList<T> {
314    fn to_json_node(&self) -> JsonNode {
315        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
316    }
317}
318
319impl<T: ToJsonNode> ToJsonNode for HashSet<T> {
320    fn to_json_node(&self) -> JsonNode {
321        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
322    }
323}
324
325impl<T: ToJsonNode> ToJsonNode for BTreeSet<T> {
326    fn to_json_node(&self) -> JsonNode {
327        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
328    }
329}
330
331impl<T: ToJsonNode> ToJsonNode for BinaryHeap<T> {
332    fn to_json_node(&self) -> JsonNode {
333        JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
334    }
335}
336
337impl<T: ToJsonNode> ToJsonNode for Vec<(String, T)> {
338    fn to_json_node(&self) -> JsonNode {
339        JsonNode::Object(
340            self.iter()
341                .map(|(key, value)| (key.clone(), value.to_json_node()))
342                .collect(),
343        )
344    }
345}
346
347impl<T: ToJsonNode> ToJsonNode for VecDeque<(String, T)> {
348    fn to_json_node(&self) -> JsonNode {
349        JsonNode::Object(
350            self.iter()
351                .map(|(key, value)| (key.clone(), value.to_json_node()))
352                .collect(),
353        )
354    }
355}
356
357impl<T: ToJsonNode> ToJsonNode for LinkedList<(String, T)> {
358    fn to_json_node(&self) -> JsonNode {
359        JsonNode::Object(
360            self.iter()
361                .map(|(key, value)| (key.clone(), value.to_json_node()))
362                .collect(),
363        )
364    }
365}
366
367impl<T: ToJsonNode> ToJsonNode for HashSet<(String, T)> {
368    fn to_json_node(&self) -> JsonNode {
369        JsonNode::Object(
370            self.iter()
371                .map(|(key, value)| (key.clone(), value.to_json_node()))
372                .collect(),
373        )
374    }
375}
376
377impl<T: ToJsonNode> ToJsonNode for BTreeSet<(String, T)> {
378    fn to_json_node(&self) -> JsonNode {
379        JsonNode::Object(
380            self.iter()
381                .map(|(key, value)| (key.clone(), value.to_json_node()))
382                .collect(),
383        )
384    }
385}
386
387impl<T: ToJsonNode> ToJsonNode for BinaryHeap<(String, T)> {
388    fn to_json_node(&self) -> JsonNode {
389        JsonNode::Object(
390            self.iter()
391                .map(|(key, value)| (key.clone(), value.to_json_node()))
392                .collect(),
393        )
394    }
395}
396
397impl<V: ToJsonNode> ToJsonNode for HashMap<String, V> {
398    fn to_json_node(&self) -> JsonNode {
399        JsonNode::Object(
400            self.iter()
401                .map(|(key, value)| (key.clone(), value.to_json_node()))
402                .collect::<JsonPropertyMap>(),
403        )
404    }
405}
406
407impl<V: ToJsonNode> ToJsonNode for BTreeMap<String, V> {
408    fn to_json_node(&self) -> JsonNode {
409        JsonNode::Object(
410            self.iter()
411                .map(|(key, value)| (key.clone(), value.to_json_node()))
412                .collect::<JsonPropertyMap>(),
413        )
414    }
415}
416
417#[cfg(test)]
418mod tests {
419    #[test]
420    fn it_works() {
421        use crate::{JsonNode, JsonPropertyMap, ToJsonNode};
422        
423        // Define some struct you want to convert into a `JsonNode`.
424        struct Person {
425            name: String,
426            age: i64,
427        }
428        
429        // Implement the trait for your struct.
430        impl ToJsonNode for Person {
431            fn to_json_node(&self) -> JsonNode {
432                // Create a `JsonNode::Object` with the properties of your struct.
433                JsonNode::Object(JsonPropertyMap::from([
434                    // The key is the name of the property. The value is the value of the property.
435                    ("name".to_owned(), JsonNode::String(self.name.clone())),
436                    // You can convert any type that implements `ToJsonNode` into a `JsonNode`.
437                    ("age".to_owned(), self.age.to_json_node()),
438                ]))
439            }
440        }
441
442        let person = Person {
443            name: "John Doe".to_owned(),
444            age: 42,
445        };
446
447        let person_node = person.to_json_node();
448        let person_node_json = person_node.to_json_string();
449        assert_eq!(
450            person_node_json,
451            r#"{"name":"John Doe","age":42}"#
452        );
453    }
454}