Skip to main content

asimov_module/
json.rs

1// This is free and unencumbered software released into the public domain.
2
3//! JSON Utilities
4//!
5//! See: https://github.com/serde-rs/json/issues/513
6//! ```rust
7//! use asimov_module::json::SkipNulls;
8//!
9//! let text = serde_json::to_string(&SkipNulls(serde_json::json!({
10//!     "a": 1,
11//!     "b": null,
12//!     "c": 3
13//! })));
14//!
15//! assert!(text.is_ok());
16//! assert_eq!(text.unwrap(), r#"{"a":1,"c":3}"#);
17//! ```
18
19use serde::{
20    Deserialize,
21    ser::{Serialize, SerializeMap, SerializeSeq, Serializer},
22};
23use serde_json::Value;
24
25#[derive(Debug, Deserialize)]
26pub struct SkipNulls(pub Value);
27
28impl Serialize for SkipNulls {
29    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30    where
31        S: Serializer,
32    {
33        match &self.0 {
34            Value::Null => serializer.serialize_unit(),
35            Value::Array(input) => {
36                let mut output = serializer.serialize_seq(Some(input.len()))?;
37                for element in input {
38                    if let Value::Null = element {
39                        continue;
40                    } else {
41                        output.serialize_element(&SkipNulls(element.clone()))?;
42                    }
43                }
44                output.end()
45            },
46            Value::Object(input) => {
47                let mut output = serializer.serialize_map(Some(input.len()))?;
48                for (key, value) in input {
49                    if let Value::Null = value {
50                        continue;
51                    } else {
52                        output.serialize_entry(&key, &SkipNulls(value.clone()))?;
53                    }
54                }
55                output.end()
56            },
57            value => value.serialize(serializer),
58        }
59    }
60}