asimov_module/
json.rs

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