1use serde::{ser, Serialize};
2use indexmap::IndexMap;
3use crate::error::{Error, Result};
4use crate::de::Value;
5
6pub fn to_value<T>(value: &T) -> Result<Value>
8where
9 T: Serialize,
10{
11 value.serialize(ValueSerializer)
12}
13
14struct 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 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
194struct 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 if self.values.len() == 1 {
216 Ok(self.values.into_iter().next().unwrap())
217 } else {
218 Err(Error::Message("Sequences with multiple values must be serialized with a key".into()))
220 }
221 }
222}
223
224struct 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
268struct 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 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}