1use std::collections::BTreeMap;
15use std::fmt;
16
17use serde::de::{self, MapAccess, SeqAccess, Visitor};
18use serde::ser::{SerializeMap, SerializeSeq};
19use serde::{Deserialize, Deserializer, Serialize, Serializer};
20
21use crate::{Format, Path, PathComponent, Record, Value};
22
23impl Serialize for Path {
24 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
25 serializer.collect_str(self)
26 }
27}
28
29impl<'de> Deserialize<'de> for Path {
30 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
31 let s = String::deserialize(deserializer)?;
32 Path::parse(&s).map_err(de::Error::custom)
33 }
34}
35
36impl Serialize for PathComponent {
37 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
38 serializer.serialize_str(self.as_str())
39 }
40}
41
42impl<'de> Deserialize<'de> for PathComponent {
43 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
44 let s = String::deserialize(deserializer)?;
45 PathComponent::try_new(s).map_err(de::Error::custom)
46 }
47}
48
49impl Serialize for Format {
50 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
51 serializer.serialize_str(self.as_str())
52 }
53}
54
55impl<'de> Deserialize<'de> for Format {
56 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
57 let s = String::deserialize(deserializer)?;
58 Ok(Format::new(s))
59 }
60}
61
62impl Serialize for Value {
63 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
64 match self {
65 Value::Null => serializer.serialize_unit(),
66 Value::Bool(b) => serializer.serialize_bool(*b),
67 Value::Integer(i) => serializer.serialize_i64(*i),
68 Value::Unsigned(i) => serializer.serialize_u64(*i),
69 Value::Float(f) => serializer.serialize_f64(*f),
70 Value::String(s) => serializer.serialize_str(s),
71 Value::Bytes(b) => serializer.serialize_bytes(b),
72 Value::Array(arr) => {
73 let mut seq = serializer.serialize_seq(Some(arr.len()))?;
74 for item in arr {
75 seq.serialize_element(item)?;
76 }
77 seq.end()
78 }
79 Value::Map(map) => {
80 let mut m = serializer.serialize_map(Some(map.len()))?;
81 for (k, v) in map {
82 m.serialize_entry(k, v)?;
83 }
84 m.end()
85 }
86 }
87 }
88}
89
90struct ValueVisitor;
91
92impl<'de> Visitor<'de> for ValueVisitor {
93 type Value = Value;
94
95 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 f.write_str("a StructFS value")
97 }
98
99 fn visit_unit<E>(self) -> Result<Value, E> {
100 Ok(Value::Null)
101 }
102
103 fn visit_none<E>(self) -> Result<Value, E> {
104 Ok(Value::Null)
105 }
106
107 fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Value, D::Error> {
108 Value::deserialize(deserializer)
109 }
110
111 fn visit_bool<E>(self, b: bool) -> Result<Value, E> {
112 Ok(Value::Bool(b))
113 }
114
115 fn visit_i64<E>(self, i: i64) -> Result<Value, E> {
116 Ok(Value::Integer(i))
117 }
118
119 fn visit_u64<E: de::Error>(self, u: u64) -> Result<Value, E> {
120 Ok(Value::from(u))
121 }
122
123 fn visit_f64<E>(self, f: f64) -> Result<Value, E> {
124 Ok(Value::from(f))
125 }
126
127 fn visit_str<E>(self, s: &str) -> Result<Value, E> {
128 Ok(Value::String(s.to_string()))
129 }
130
131 fn visit_string<E>(self, s: String) -> Result<Value, E> {
132 Ok(Value::String(s))
133 }
134
135 fn visit_bytes<E>(self, b: &[u8]) -> Result<Value, E> {
136 Ok(Value::Bytes(b.to_vec()))
137 }
138
139 fn visit_byte_buf<E>(self, b: Vec<u8>) -> Result<Value, E> {
140 Ok(Value::Bytes(b))
141 }
142
143 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Value, A::Error> {
144 let mut arr = Vec::new();
145 while let Some(item) = seq.next_element()? {
146 arr.push(item);
147 }
148 Ok(Value::Array(arr))
149 }
150
151 fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Value, A::Error> {
152 let mut map = BTreeMap::new();
153 while let Some((k, v)) = access.next_entry::<String, Value>()? {
154 if map.contains_key(&k) {
155 return Err(de::Error::custom("duplicate map key"));
156 }
157 map.insert(k, v);
158 }
159 Ok(Value::Map(map))
160 }
161}
162
163impl<'de> Deserialize<'de> for Value {
164 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
165 deserializer.deserialize_any(ValueVisitor)
166 }
167}
168
169#[derive(Serialize, Deserialize)]
172enum RecordRepr {
173 #[serde(rename = "raw")]
174 Raw { bytes: Vec<u8>, format: Format },
175 #[serde(rename = "parsed")]
176 Parsed(Value),
177}
178
179impl Serialize for Record {
180 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
181 let repr = match self {
182 Record::Raw { bytes, format } => RecordRepr::Raw {
183 bytes: bytes.to_vec(),
184 format: format.clone(),
185 },
186 Record::Parsed(v) => RecordRepr::Parsed(v.clone()),
187 };
188 repr.serialize(serializer)
189 }
190}
191
192impl<'de> Deserialize<'de> for Record {
193 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
194 Ok(match RecordRepr::deserialize(deserializer)? {
195 RecordRepr::Raw { bytes, format } => Record::raw(bytes, format),
196 RecordRepr::Parsed(v) => Record::Parsed(v),
197 })
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use crate::path;
205
206 #[test]
207 fn path_roundtrip() {
208 let p = path!("users/123/name");
209 let json = serde_json::to_string(&p).unwrap();
210 assert_eq!(json, "\"users/123/name\"");
211 let back: Path = serde_json::from_str(&json).unwrap();
212 assert_eq!(back, p);
213 }
214
215 #[test]
216 fn empty_path_roundtrip() {
217 let p = path!();
218 let json = serde_json::to_string(&p).unwrap();
219 assert_eq!(json, "\"\"");
220 let back: Path = serde_json::from_str(&json).unwrap();
221 assert!(back.is_empty());
222 }
223
224 #[test]
225 fn invalid_path_rejected() {
226 let result: Result<Path, _> = serde_json::from_str("\"bad-component\"");
227 assert!(result.is_err());
228 }
229
230 #[test]
231 fn path_component_roundtrip() {
232 let c = PathComponent::try_new("alice").unwrap();
233 let json = serde_json::to_string(&c).unwrap();
234 let back: PathComponent = serde_json::from_str(&json).unwrap();
235 assert_eq!(back, c);
236
237 let result: Result<PathComponent, _> = serde_json::from_str("\"bad name\"");
238 assert!(result.is_err());
239 }
240
241 #[test]
242 fn format_roundtrip() {
243 let json = serde_json::to_string(&Format::JSON).unwrap();
244 assert_eq!(json, "\"application/json\"");
245 let back: Format = serde_json::from_str(&json).unwrap();
246 assert_eq!(back, Format::JSON);
247 }
248
249 #[test]
250 fn value_roundtrip_via_json() {
251 let mut map = BTreeMap::new();
252 map.insert("name".to_string(), Value::from("Alice"));
253 map.insert("age".to_string(), Value::from(30i64));
254 map.insert("score".to_string(), Value::Float(0.5));
255 map.insert("active".to_string(), Value::Bool(true));
256 map.insert("nothing".to_string(), Value::Null);
257 map.insert(
258 "tags".to_string(),
259 Value::Array(vec![Value::from("a"), Value::from("b")]),
260 );
261 let value = Value::Map(map);
262
263 let json = serde_json::to_string(&value).unwrap();
264 let back: Value = serde_json::from_str(&json).unwrap();
265 assert_eq!(back, value);
266 }
267
268 #[test]
269 fn value_interops_with_serde_json() {
270 let value = Value::Map({
272 let mut m = BTreeMap::new();
273 m.insert("x".to_string(), Value::Integer(1));
274 m
275 });
276 let json: serde_json::Value = serde_json::to_value(&value).unwrap();
277 assert_eq!(json, serde_json::json!({"x": 1}));
278 }
279
280 #[test]
281 fn value_bytes_become_arrays_in_json() {
282 let value = Value::Bytes(vec![1, 2, 3]);
285 let json = serde_json::to_string(&value).unwrap();
286 assert_eq!(json, "[1,2,3]");
287 let back: Value = serde_json::from_str(&json).unwrap();
288 assert_eq!(
289 back,
290 Value::Array(vec![
291 Value::Integer(1),
292 Value::Integer(2),
293 Value::Integer(3)
294 ])
295 );
296 }
297
298 #[test]
299 fn u64_range_preserved() {
300 let result: Result<Value, _> = serde_json::from_str("18446744073709551615");
301 assert_eq!(result.unwrap(), Value::Unsigned(u64::MAX));
302 }
303
304 #[test]
305 fn record_parsed_roundtrip() {
306 let record = Record::parsed(Value::from("hello"));
307 let json = serde_json::to_string(&record).unwrap();
308 assert_eq!(json, "{\"parsed\":\"hello\"}");
309 let back: Record = serde_json::from_str(&json).unwrap();
310 assert!(back.is_parsed());
311 assert_eq!(back.as_value(), Some(&Value::from("hello")));
312 }
313
314 #[test]
315 fn record_raw_roundtrip() {
316 let record = Record::raw(bytes::Bytes::from_static(b"{}"), Format::JSON);
317 let json = serde_json::to_string(&record).unwrap();
318 let back: Record = serde_json::from_str(&json).unwrap();
319 assert!(back.is_raw());
320 assert_eq!(back.format(), Format::JSON);
321 assert_eq!(back.as_bytes().map(|b| b.as_ref()), Some(b"{}".as_ref()));
322 }
323}