Skip to main content

serde_key_value_vec_map/
lib.rs

1use serde::{
2    self,
3    de::{Deserializer, MapAccess, Visitor},
4    ser::{SerializeMap, Serializer},
5    Deserialize, Serialize,
6};
7use std::{fmt, marker::PhantomData};
8
9pub trait KeyValueLike {
10    type Key;
11    type Value;
12
13    fn from_key_value(key: Self::Key, value: Self::Value) -> Self;
14    fn key(&self) -> &Self::Key;
15    fn value(&self) -> &Self::Value;
16}
17
18struct KeyValueVecMapVisitor<T: KeyValueLike> {
19    marker: PhantomData<fn() -> Vec<T>>,
20}
21
22impl<T: KeyValueLike> KeyValueVecMapVisitor<T> {
23    fn new() -> Self {
24        Self {
25            marker: PhantomData,
26        }
27    }
28}
29
30impl<'de, T: KeyValueLike, K, V> Visitor<'de> for KeyValueVecMapVisitor<T>
31where
32    T: KeyValueLike<Key = K, Value = V>,
33    K: Deserialize<'de>,
34    V: Deserialize<'de>,
35{
36    type Value = Vec<T>;
37
38    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
39        formatter.write_str("key value map")
40    }
41
42    fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
43    where
44        M: MapAccess<'de>,
45    {
46        let mut vec = Vec::with_capacity(access.size_hint().unwrap_or(0));
47
48        while let Some((key, value)) = access.next_entry()? {
49            vec.push(T::from_key_value(key, value));
50        }
51
52        Ok(vec)
53    }
54}
55
56pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<Vec<T>, D::Error>
57where
58    D: Deserializer<'de>,
59    T: KeyValueLike<Key = K, Value = V>,
60    K: Deserialize<'de>,
61    V: Deserialize<'de>,
62{
63    deserializer.deserialize_map(KeyValueVecMapVisitor::new())
64}
65
66pub fn serialize<S, T, K, V>(pairs: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
67where
68    S: Serializer,
69    T: KeyValueLike<Key = K, Value = V>,
70    K: Serialize,
71    V: Serialize,
72{
73    let mut map = serializer.serialize_map(Some(pairs.len()))?;
74    for pair in pairs {
75        map.serialize_entry(pair.key(), pair.value())?;
76    }
77    map.end()
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_deserialize_with() {
86        let json = r#"
87        {
88            "temperature": 40,
89            "pressure": 123
90        }
91    "#;
92
93        #[derive(Debug, Eq, PartialEq)]
94        struct SingleMeasurement {
95            name: String,
96            value: u32,
97        }
98
99        impl KeyValueLike for SingleMeasurement {
100            type Key = String;
101            type Value = u32;
102            fn from_key_value(key: Self::Key, value: Self::Value) -> Self {
103                Self { name: key, value }
104            }
105            fn key(&self) -> &Self::Key {
106                &self.name
107            }
108            fn value(&self) -> &Self::Value {
109                &self.value
110            }
111        }
112
113        #[derive(Deserialize)]
114        struct S {
115            #[serde(flatten)]
116            #[serde(with = "crate")]
117            measurements: Vec<SingleMeasurement>,
118        }
119
120        let s: S = serde_json::from_str(json).unwrap();
121
122        assert_eq!(
123            s.measurements,
124            vec![
125                SingleMeasurement {
126                    name: "temperature".into(),
127                    value: 40
128                },
129                SingleMeasurement {
130                    name: "pressure".into(),
131                    value: 123
132                },
133            ]
134        );
135    }
136
137    #[test]
138    fn test_serialize_with() {
139        #[derive(Debug, Eq, PartialEq)]
140        struct SingleMeasurement {
141            name: String,
142            value: u32,
143        }
144
145        impl KeyValueLike for SingleMeasurement {
146            type Key = String;
147            type Value = u32;
148            fn from_key_value(key: Self::Key, value: Self::Value) -> Self {
149                Self { name: key, value }
150            }
151            fn key(&self) -> &Self::Key {
152                &self.name
153            }
154            fn value(&self) -> &Self::Value {
155                &self.value
156            }
157        }
158
159        #[derive(Serialize)]
160        struct S {
161            #[serde(flatten)]
162            #[serde(with = "crate")]
163            measurements: Vec<SingleMeasurement>,
164        }
165
166        let s = S {
167            measurements: vec![
168                SingleMeasurement {
169                    name: "temperature".into(),
170                    value: 40,
171                },
172                SingleMeasurement {
173                    name: "pressure".into(),
174                    value: 123,
175                },
176            ],
177        };
178
179        assert_eq!(
180            &serde_json::to_string(&s).unwrap(),
181            r#"{"temperature":40,"pressure":123}"#
182        );
183    }
184}