1use enumflags2::{bitflags, BitFlags};
2use serde_json::Value;
3
4#[bitflags]
6#[repr(u8)]
7#[derive(Copy, Clone, Debug, PartialEq)]
8pub enum Strip {
9 Nulls,
10 Empties,
11}
12
13#[inline]
31pub fn strip(mask: BitFlags<Strip, u8>, mut value: Value) -> Option<Value> {
32 match strip_mut_inner(mask, &mut value) {
33 false => None,
34 true => Some(value),
35 }
36}
37
38fn strip_mut_inner(mask: BitFlags<Strip, u8>, value: &mut Value) -> bool {
39 match value {
40 Value::Null => !mask.intersects(Strip::Nulls),
41 Value::Object(ref mut o) => {
42 o.retain(|_, v| strip_mut_inner(mask, v));
43 !(o.is_empty() && mask.intersects(Strip::Empties))
44 }
45 Value::Array(a) => {
46 let mut null_count = 0;
49 for value in a.iter_mut() {
50 if !strip_mut_inner(mask, value) {
51 *value = Value::Null;
52 null_count += 1;
53 }
54 }
55 if null_count == a.len() {
56 a.clear();
57 }
58
59 !(a.is_empty() && mask.intersects(Strip::Empties))
60 }
61 _ => true,
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use serde_json::json;
69
70 #[test]
71 fn strip_it() {
72 assert_eq!(strip(Strip::Nulls.into(), json!(null)), None);
73 assert_eq!(strip(Strip::Nulls | Strip::Empties, json!(null)), None);
74 assert_eq!(strip(Strip::Nulls.into(), json!({})), Some(json!({})));
75 assert_eq!(strip(Strip::Nulls | Strip::Empties, json!({})), None);
76 assert_eq!(
77 strip(
78 Strip::Nulls | Strip::Empties,
79 json!({"key":{"value":"value", "null":null}, "arr":[null]})
80 ),
81 Some(json!({"key":{"value":"value"}}))
82 );
83 assert_eq!(
84 strip(
85 Strip::Nulls | Strip::Empties,
86 json!({"key":{"value":"value", "null":null}, "arr":[null, 1]})
87 ),
88 Some(json!({"key":{"value":"value"}, "arr":[null, 1]}))
89 );
90 assert_eq!(
91 strip(
92 Strip::Nulls | Strip::Empties,
93 json!({"key":{"value":"value", "null":null}, "arr":[]})
94 ),
95 Some(json!({"key":{"value":"value"}}))
96 );
97 assert_eq!(
98 strip(
99 Strip::Empties.into(),
100 json!({"key":{"value":null, "null":null}, "arr":[null], "empty":[]})
101 ),
102 Some(json!({"key":{"value":null, "null":null}, "arr":[null]}))
103 );
104 }
105}