1use super::{AttributeKey, AttributeValue, Attributes};
2use crate::EntityState;
3use serde::{de::MapAccess, ser::SerializeMap, Deserialize, Serialize};
4use std::{collections::BTreeMap, fmt, marker::PhantomData};
5
6impl<'a, K, V, E> Serialize for Attributes<'a, K, V, E>
7where
8 K: AttributeKey<'a>,
9 V: AttributeValue<'a>,
10 E: EntityState<'a, K, V>,
11{
12 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
13 where
14 S: serde::Serializer,
15 {
16 let mut map = serializer.serialize_map(Some(self.0.len()))?;
17 for (key, value) in self.0.iter() {
18 map.serialize_entry(key.borrow(), value.borrow())?;
19 }
20 map.end()
21 }
22}
23
24struct AttributesVisitor<'a, K, V, E>
25where
26 K: AttributeKey<'a>,
27 V: AttributeValue<'a>,
28 E: EntityState<'a, K, V>,
29{
30 marker: PhantomData<Attributes<'a, K, V, E>>,
31}
32
33impl<'a, 'de: 'a, K, V, E> serde::de::Visitor<'de> for AttributesVisitor<'a, K, V, E>
34where
35 K: AttributeKey<'a> + 'a,
36 V: AttributeValue<'a> + 'a,
37 E: EntityState<'a, K, V>,
38{
39 type Value = Attributes<'a, K, V, E>;
40
41 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
42 formatter.write_str("a map")
43 }
44
45 #[inline]
46 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
47 where
48 A: MapAccess<'de>,
49 {
50 let mut values = BTreeMap::new();
52
53 while let Some((AttributeKeyWrapper { value: key, .. }, AttributeValueWrapper { value, .. })) =
54 map.next_entry()?
55 {
56 values.insert(key, value);
57 }
58
59 Ok(Attributes(values, PhantomData))
60 }
61}
62
63impl<'a, 'de: 'a, K, V, E> Deserialize<'de> for Attributes<'a, K, V, E>
64where
65 K: AttributeKey<'a> + 'a,
66 V: AttributeValue<'a> + 'a,
67 E: EntityState<'a, K, V>,
68{
69 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70 where
71 D: serde::Deserializer<'de>,
72 {
73 deserializer.deserialize_map(AttributesVisitor {
74 marker: PhantomData,
75 })
76 }
77}
78
79struct AttributeKeyWrapper<'a, K> {
80 value: K,
81 marker: PhantomData<&'a ()>,
82}
83struct AttributeKeyVisitor<'a, K> {
84 marker: PhantomData<fn() -> &'a K>,
85}
86impl<'a, 'de: 'a, K> serde::de::Visitor<'de> for AttributeKeyVisitor<'a, K>
87where
88 K: AttributeKey<'a>,
89{
90 type Value = AttributeKeyWrapper<'a, K>;
91
92 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
93 formatter.write_str("a string")
94 }
95
96 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
99 where
100 E: serde::de::Error,
101 {
102 Ok(AttributeKeyWrapper {
103 value: K::from_cow(std::borrow::Cow::Borrowed(value)),
104 marker: PhantomData,
105 })
106 }
107
108 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
111 where
112 E: serde::de::Error,
113 {
114 Ok(AttributeKeyWrapper {
115 value: K::from_cow(std::borrow::Cow::Owned(value.to_owned())),
116 marker: PhantomData,
117 })
118 }
119
120 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
123 where
124 E: serde::de::Error,
125 {
126 Ok(AttributeKeyWrapper {
127 value: K::from_cow(std::borrow::Cow::Owned(value)),
128 marker: PhantomData,
129 })
130 }
131}
132impl<'a, 'de: 'a, K: 'a> Deserialize<'de> for AttributeKeyWrapper<'a, K>
133where
134 K: AttributeKey<'a>,
135{
136 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
137 where
138 D: serde::Deserializer<'de>,
139 {
140 deserializer.deserialize_str(AttributeKeyVisitor {
141 marker: PhantomData,
142 })
143 }
144}
145
146struct AttributeValueWrapper<'a, V> {
147 value: V,
148 marker: PhantomData<&'a ()>,
149}
150struct AttributeValueVisitor<'a, V> {
151 marker: PhantomData<fn() -> &'a V>,
152}
153impl<'a, 'de: 'a, V> serde::de::Visitor<'de> for AttributeValueVisitor<'a, V>
154where
155 V: AttributeValue<'a>,
156{
157 type Value = AttributeValueWrapper<'a, V>;
158
159 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
160 formatter.write_str("a string")
161 }
162
163 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
166 where
167 E: serde::de::Error,
168 {
169 Ok(AttributeValueWrapper {
170 value: V::from_cow(std::borrow::Cow::Borrowed(value)),
171 marker: PhantomData,
172 })
173 }
174
175 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
178 where
179 E: serde::de::Error,
180 {
181 Ok(AttributeValueWrapper {
182 value: V::from_cow(std::borrow::Cow::Owned(value.to_owned())),
183 marker: PhantomData,
184 })
185 }
186
187 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
190 where
191 E: serde::de::Error,
192 {
193 Ok(AttributeValueWrapper {
194 value: V::from_cow(std::borrow::Cow::Owned(value)),
195 marker: PhantomData,
196 })
197 }
198}
199
200impl<'a, 'de: 'a, V: 'a> Deserialize<'de> for AttributeValueWrapper<'a, V>
201where
202 V: AttributeValue<'a>,
203{
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: serde::Deserializer<'de>,
207 {
208 deserializer.deserialize_str(AttributeValueVisitor {
209 marker: PhantomData,
210 })
211 }
212}
213
214#[cfg(test)]
215mod tests {
216 use std::borrow::Cow;
217
218 use assert_matches::assert_matches;
219
220 use crate::EntityStateValue;
221
222 use super::*;
223 use serde_test::{assert_tokens, Token};
224
225 struct FakeEntityType;
226 impl EntityStateValue for FakeEntityType {}
227 impl<'a> EntityState<'a, Cow<'a, str>, Cow<'a, str>> for FakeEntityType {
228 type State = FakeEntityType;
229
230 fn get(&self) -> &Self::State {
231 todo!()
232 }
233
234 fn get_mut(&mut self) -> &mut Self::State {
235 todo!()
236 }
237
238 fn attributes(&self) -> &Attributes<'a, Cow<'a, str>, Cow<'a, str>, Self> {
239 todo!()
240 }
241
242 fn attributes_mut(&mut self) -> &mut Attributes<'a, Cow<'a, str>, Cow<'a, str>, Self> {
243 todo!()
244 }
245 }
246
247 #[test]
248 fn serde() {
249 let mut attributes: Attributes<Cow<str>, Cow<str>, FakeEntityType> = Attributes::default();
250 attributes.insert(Cow::Borrowed("k1"), Cow::Borrowed("v1"));
251 attributes.insert(Cow::Borrowed("k2"), Cow::Borrowed("v2"));
252
253 assert_tokens(
254 &attributes,
255 &[
256 Token::Map { len: Some(2) },
257 Token::Str("k1"),
258 Token::Str("v1"),
259 Token::Str("k2"),
260 Token::Str("v2"),
261 Token::MapEnd,
262 ],
263 )
264 }
265
266 #[test]
267 fn json_borrows() {
268 let json = r#"{"k1":"v1","k2":"v2"}"#;
269 let attributes: Attributes<Cow<str>, Cow<str>, FakeEntityType> =
270 serde_json::from_str(json).expect("should parse");
271
272 assert_matches!(attributes.get_inner("k1"), Some(Cow::Borrowed("v1")));
273 assert_matches!(attributes.get_inner("k2"), Some(Cow::Borrowed("v2")));
274 }
275}