serde_key_value_vec_map/
lib.rs1use 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}