Skip to main content

source_kv/
value_ser.rs

1use serde::{ser, Serialize};
2use indexmap::IndexMap;
3use crate::error::{Error, Result};
4use crate::de::Value;
5
6/// Serializes a Rust value into a `Value` enum.
7pub fn to_value<T>(value: &T) -> Result<Value>
8where
9    T: Serialize,
10{
11    value.serialize(ValueSerializer)
12}
13
14/// A serializer that converts Rust types into `Value` enum.
15struct ValueSerializer;
16
17impl ser::Serializer for ValueSerializer {
18    type Ok = Value;
19    type Error = Error;
20
21    type SerializeSeq = SeqSerializer;
22    type SerializeTuple = ser::Impossible<Value, Error>;
23    type SerializeTupleStruct = ser::Impossible<Value, Error>;
24    type SerializeTupleVariant = ser::Impossible<Value, Error>;
25    type SerializeMap = MapSerializer;
26    type SerializeStruct = StructSerializer;
27    type SerializeStructVariant = ser::Impossible<Value, Error>;
28
29    fn serialize_bool(self, v: bool) -> Result<Value> {
30        Ok(Value::Str(if v { "1" } else { "0" }.to_string()))
31    }
32
33    fn serialize_i8(self, v: i8) -> Result<Value> {
34        Ok(Value::Str(v.to_string()))
35    }
36
37    fn serialize_i16(self, v: i16) -> Result<Value> {
38        Ok(Value::Str(v.to_string()))
39    }
40
41    fn serialize_i32(self, v: i32) -> Result<Value> {
42        Ok(Value::Str(v.to_string()))
43    }
44
45    fn serialize_i64(self, v: i64) -> Result<Value> {
46        Ok(Value::Str(v.to_string()))
47    }
48
49    fn serialize_u8(self, v: u8) -> Result<Value> {
50        Ok(Value::Str(v.to_string()))
51    }
52
53    fn serialize_u16(self, v: u16) -> Result<Value> {
54        Ok(Value::Str(v.to_string()))
55    }
56
57    fn serialize_u32(self, v: u32) -> Result<Value> {
58        Ok(Value::Str(v.to_string()))
59    }
60
61    fn serialize_u64(self, v: u64) -> Result<Value> {
62        Ok(Value::Str(v.to_string()))
63    }
64
65    fn serialize_f32(self, v: f32) -> Result<Value> {
66        Ok(Value::Str(v.to_string()))
67    }
68
69    fn serialize_f64(self, v: f64) -> Result<Value> {
70        Ok(Value::Str(v.to_string()))
71    }
72
73    fn serialize_char(self, v: char) -> Result<Value> {
74        Ok(Value::Str(v.to_string()))
75    }
76
77    fn serialize_str(self, v: &str) -> Result<Value> {
78        Ok(Value::Str(v.to_string()))
79    }
80
81    fn serialize_bytes(self, _v: &[u8]) -> Result<Value> {
82        Err(Error::Message("Bytes serialization not supported".into()))
83    }
84
85    fn serialize_none(self) -> Result<Value> {
86        // Skip None values - they won't be included in the output
87        Err(Error::Message("None values are not supported in KeyValues format".into()))
88    }
89
90    fn serialize_some<T>(self, value: &T) -> Result<Value>
91    where
92        T: ?Sized + Serialize,
93    {
94        value.serialize(self)
95    }
96
97    fn serialize_unit(self) -> Result<Value> {
98        Ok(Value::Str(String::new()))
99    }
100
101    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
102        self.serialize_unit()
103    }
104
105    fn serialize_unit_variant(
106        self,
107        _name: &'static str,
108        _variant_index: u32,
109        variant: &'static str,
110    ) -> Result<Value> {
111        Ok(Value::Str(variant.to_string()))
112    }
113
114    fn serialize_newtype_struct<T>(
115        self,
116        _name: &'static str,
117        value: &T,
118    ) -> Result<Value>
119    where
120        T: ?Sized + Serialize,
121    {
122        value.serialize(self)
123    }
124
125    fn serialize_newtype_variant<T>(
126        self,
127        _name: &'static str,
128        _variant_index: u32,
129        _variant: &'static str,
130        _value: &T,
131    ) -> Result<Value>
132    where
133        T: ?Sized + Serialize,
134    {
135        Err(Error::Message("Newtype variant serialization not supported".into()))
136    }
137
138    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
139        Ok(SeqSerializer {
140            values: Vec::new(),
141        })
142    }
143
144    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
145        Err(Error::Message("Tuple serialization not supported".into()))
146    }
147
148    fn serialize_tuple_struct(
149        self,
150        _name: &'static str,
151        _len: usize,
152    ) -> Result<Self::SerializeTupleStruct> {
153        Err(Error::Message("Tuple struct serialization not supported".into()))
154    }
155
156    fn serialize_tuple_variant(
157        self,
158        _name: &'static str,
159        _variant_index: u32,
160        _variant: &'static str,
161        _len: usize,
162    ) -> Result<Self::SerializeTupleVariant> {
163        Err(Error::Message("Tuple variant serialization not supported".into()))
164    }
165
166    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
167        Ok(MapSerializer {
168            map: IndexMap::new(),
169            current_key: None,
170        })
171    }
172
173    fn serialize_struct(
174        self,
175        _name: &'static str,
176        _len: usize,
177    ) -> Result<Self::SerializeStruct> {
178        Ok(StructSerializer {
179            map: IndexMap::new(),
180        })
181    }
182
183    fn serialize_struct_variant(
184        self,
185        _name: &'static str,
186        _variant_index: u32,
187        _variant: &'static str,
188        _len: usize,
189    ) -> Result<Self::SerializeStructVariant> {
190        Err(Error::Message("Struct variant serialization not supported".into()))
191    }
192}
193
194/// Serializer for sequences (arrays).
195struct SeqSerializer {
196    values: Vec<Value>,
197}
198
199impl ser::SerializeSeq for SeqSerializer {
200    type Ok = Value;
201    type Error = Error;
202
203    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
204    where
205        T: ?Sized + Serialize,
206    {
207        self.values.push(value.serialize(ValueSerializer)?);
208        Ok(())
209    }
210
211    fn end(self) -> Result<Value> {
212        // For KeyValues, sequences are represented as multiple values with the same key
213        // This will be handled by the parent serializer
214        // For now, we return the first value or an error if empty
215        if self.values.len() == 1 {
216            Ok(self.values.into_iter().next().unwrap())
217        } else {
218            // Multiple values - this should be handled at a higher level
219            Err(Error::Message("Sequences with multiple values must be serialized with a key".into()))
220        }
221    }
222}
223
224/// Serializer for maps.
225struct MapSerializer {
226    map: IndexMap<String, Vec<Value>>,
227    current_key: Option<String>,
228}
229
230impl ser::SerializeMap for MapSerializer {
231    type Ok = Value;
232    type Error = Error;
233
234    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
235    where
236        T: ?Sized + Serialize,
237    {
238        let key_value = key.serialize(ValueSerializer)?;
239        match key_value {
240            Value::Str(s) => {
241                self.current_key = Some(s);
242                Ok(())
243            }
244            _ => Err(Error::Message("Map keys must be strings".into())),
245        }
246    }
247
248    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
249    where
250        T: ?Sized + Serialize,
251    {
252        let key = self.current_key.take()
253            .ok_or_else(|| Error::Message("serialize_value called without key".into()))?;
254        
255        let serialized_value = value.serialize(ValueSerializer)?;
256        self.map.entry(key)
257            .or_insert_with(Vec::new)
258            .push(serialized_value);
259        
260        Ok(())
261    }
262
263    fn end(self) -> Result<Value> {
264        Ok(Value::Obj(self.map))
265    }
266}
267
268/// Serializer for structs.
269struct StructSerializer {
270    map: IndexMap<String, Vec<Value>>,
271}
272
273impl ser::SerializeStruct for StructSerializer {
274    type Ok = Value;
275    type Error = Error;
276
277    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
278    where
279        T: ?Sized + Serialize,
280    {
281        // Skip None values (Option<T> fields)
282        let serialized_value = match value.serialize(ValueSerializer) {
283            Ok(v) => v,
284            Err(e) if e.to_string().contains("None values") => return Ok(()),
285            Err(e) => return Err(e),
286        };
287        
288        self.map.entry(key.to_string())
289            .or_insert_with(Vec::new)
290            .push(serialized_value);
291        
292        Ok(())
293    }
294
295    fn end(self) -> Result<Value> {
296        Ok(Value::Obj(self.map))
297    }
298}
299
300#[cfg(test)]
301mod tests {
302    use super::*;
303    use serde::Serialize;
304
305    #[test]
306    fn test_serialize_primitives() {
307        assert_eq!(to_value(&42).unwrap(), Value::Str("42".to_string()));
308        assert_eq!(to_value(&3.14f32).unwrap(), Value::Str("3.14".to_string()));
309        assert_eq!(to_value(&true).unwrap(), Value::Str("1".to_string()));
310        assert_eq!(to_value(&false).unwrap(), Value::Str("0".to_string()));
311        assert_eq!(to_value(&"hello").unwrap(), Value::Str("hello".to_string()));
312    }
313
314    #[test]
315    fn test_serialize_simple_struct() {
316        #[derive(Serialize)]
317        struct Simple {
318            name: String,
319            value: i32,
320        }
321
322        let s = Simple {
323            name: "test".to_string(),
324            value: 42,
325        };
326
327        let result = to_value(&s).unwrap();
328        
329        if let Value::Obj(map) = result {
330            assert_eq!(map.len(), 2);
331            assert_eq!(map.get("name").unwrap()[0], Value::Str("test".to_string()));
332            assert_eq!(map.get("value").unwrap()[0], Value::Str("42".to_string()));
333        } else {
334            panic!("Expected Value::Obj");
335        }
336    }
337
338    #[test]
339    fn test_serialize_nested_struct() {
340        #[derive(Serialize)]
341        struct Inner {
342            x: f32,
343        }
344
345        #[derive(Serialize)]
346        struct Outer {
347            inner: Inner,
348            name: String,
349        }
350
351        let outer = Outer {
352            inner: Inner { x: 1.5 },
353            name: "outer".to_string(),
354        };
355
356        let result = to_value(&outer).unwrap();
357        
358        if let Value::Obj(map) = result {
359            assert_eq!(map.len(), 2);
360            
361            if let Value::Obj(inner_map) = &map.get("inner").unwrap()[0] {
362                assert_eq!(inner_map.get("x").unwrap()[0], Value::Str("1.5".to_string()));
363            } else {
364                panic!("Expected nested Value::Obj");
365            }
366        } else {
367            panic!("Expected Value::Obj");
368        }
369    }
370
371    #[test]
372    fn test_serialize_with_option() {
373        #[derive(Serialize)]
374        struct WithOption {
375            required: String,
376            #[serde(skip_serializing_if = "Option::is_none")]
377            optional: Option<String>,
378        }
379
380        let with_some = WithOption {
381            required: "req".to_string(),
382            optional: Some("opt".to_string()),
383        };
384
385        let result = to_value(&with_some).unwrap();
386        if let Value::Obj(map) = result {
387            assert_eq!(map.len(), 2);
388            assert!(map.contains_key("optional"));
389        } else {
390            panic!("Expected Value::Obj");
391        }
392
393        let with_none = WithOption {
394            required: "req".to_string(),
395            optional: None,
396        };
397
398        let result = to_value(&with_none).unwrap();
399        if let Value::Obj(map) = result {
400            assert_eq!(map.len(), 1);
401            assert!(!map.contains_key("optional"));
402        } else {
403            panic!("Expected Value::Obj");
404        }
405    }
406}