1use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
2use std::error::Error;
3
4use crate::{JsonNode, JsonPropertyMap};
5
6pub trait ToJsonNode {
8 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 struct Person {
425 name: String,
426 age: i64,
427 }
428
429 impl ToJsonNode for Person {
431 fn to_json_node(&self) -> JsonNode {
432 JsonNode::Object(JsonPropertyMap::from([
434 ("name".to_owned(), JsonNode::String(self.name.clone())),
436 ("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}