1use crate::dumper::{dumps, DumpOptions};
2use crate::error::{Error, ErrorKind};
3use crate::value::Value;
4
5use serde::ser::{self, Serialize};
6
7pub fn to_string<T: Serialize>(value: &T) -> Result<String, Error> {
9 let v = value.serialize(ValueSerializer)?;
10 Ok(dumps(&v, &DumpOptions::default()))
11}
12
13pub fn to_string_with_options<T: Serialize>(
15 value: &T,
16 options: &DumpOptions,
17) -> Result<String, Error> {
18 let v = value.serialize(ValueSerializer)?;
19 Ok(dumps(&v, options))
20}
21
22struct ValueSerializer;
23
24impl ser::Serializer for ValueSerializer {
25 type Ok = Value;
26 type Error = Error;
27 type SerializeSeq = SeqSerializer;
28 type SerializeTuple = SeqSerializer;
29 type SerializeTupleStruct = SeqSerializer;
30 type SerializeTupleVariant = TupleVariantSerializer;
31 type SerializeMap = MapSerializer;
32 type SerializeStruct = MapSerializer;
33 type SerializeStructVariant = StructVariantSerializer;
34
35 fn serialize_bool(self, v: bool) -> Result<Value, Error> {
36 Ok(Value::String(v.to_string()))
37 }
38
39 fn serialize_i8(self, v: i8) -> Result<Value, Error> {
40 Ok(Value::String(v.to_string()))
41 }
42
43 fn serialize_i16(self, v: i16) -> Result<Value, Error> {
44 Ok(Value::String(v.to_string()))
45 }
46
47 fn serialize_i32(self, v: i32) -> Result<Value, Error> {
48 Ok(Value::String(v.to_string()))
49 }
50
51 fn serialize_i64(self, v: i64) -> Result<Value, Error> {
52 Ok(Value::String(v.to_string()))
53 }
54
55 fn serialize_u8(self, v: u8) -> Result<Value, Error> {
56 Ok(Value::String(v.to_string()))
57 }
58
59 fn serialize_u16(self, v: u16) -> Result<Value, Error> {
60 Ok(Value::String(v.to_string()))
61 }
62
63 fn serialize_u32(self, v: u32) -> Result<Value, Error> {
64 Ok(Value::String(v.to_string()))
65 }
66
67 fn serialize_u64(self, v: u64) -> Result<Value, Error> {
68 Ok(Value::String(v.to_string()))
69 }
70
71 fn serialize_f32(self, v: f32) -> Result<Value, Error> {
72 Ok(Value::String(v.to_string()))
73 }
74
75 fn serialize_f64(self, v: f64) -> Result<Value, Error> {
76 Ok(Value::String(v.to_string()))
77 }
78
79 fn serialize_char(self, v: char) -> Result<Value, Error> {
80 Ok(Value::String(v.to_string()))
81 }
82
83 fn serialize_str(self, v: &str) -> Result<Value, Error> {
84 Ok(Value::String(v.to_string()))
85 }
86
87 fn serialize_bytes(self, _v: &[u8]) -> Result<Value, Error> {
88 Err(Error::new(
89 ErrorKind::UnsupportedType,
90 "NestedText does not support byte arrays",
91 ))
92 }
93
94 fn serialize_none(self) -> Result<Value, Error> {
95 Ok(Value::String(String::new()))
96 }
97
98 fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Value, Error> {
99 value.serialize(self)
100 }
101
102 fn serialize_unit(self) -> Result<Value, Error> {
103 Ok(Value::String(String::new()))
104 }
105
106 fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
107 Ok(Value::String(String::new()))
108 }
109
110 fn serialize_unit_variant(
111 self,
112 _name: &'static str,
113 _variant_index: u32,
114 variant: &'static str,
115 ) -> Result<Value, Error> {
116 Ok(Value::String(variant.to_string()))
117 }
118
119 fn serialize_newtype_struct<T: ?Sized + Serialize>(
120 self,
121 _name: &'static str,
122 value: &T,
123 ) -> Result<Value, Error> {
124 value.serialize(self)
125 }
126
127 fn serialize_newtype_variant<T: ?Sized + Serialize>(
128 self,
129 _name: &'static str,
130 _variant_index: u32,
131 variant: &'static str,
132 value: &T,
133 ) -> Result<Value, Error> {
134 let inner = value.serialize(ValueSerializer)?;
135 Ok(Value::Dict(vec![(variant.to_string(), inner)]))
136 }
137
138 fn serialize_seq(self, len: Option<usize>) -> Result<SeqSerializer, Error> {
139 Ok(SeqSerializer {
140 items: Vec::with_capacity(len.unwrap_or(0)),
141 })
142 }
143
144 fn serialize_tuple(self, len: usize) -> Result<SeqSerializer, Error> {
145 self.serialize_seq(Some(len))
146 }
147
148 fn serialize_tuple_struct(
149 self,
150 _name: &'static str,
151 len: usize,
152 ) -> Result<SeqSerializer, Error> {
153 self.serialize_seq(Some(len))
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<TupleVariantSerializer, Error> {
163 Ok(TupleVariantSerializer {
164 variant: variant.to_string(),
165 items: Vec::with_capacity(len),
166 })
167 }
168
169 fn serialize_map(self, len: Option<usize>) -> Result<MapSerializer, Error> {
170 Ok(MapSerializer {
171 pairs: Vec::with_capacity(len.unwrap_or(0)),
172 next_key: None,
173 })
174 }
175
176 fn serialize_struct(
177 self,
178 _name: &'static str,
179 len: usize,
180 ) -> Result<MapSerializer, Error> {
181 self.serialize_map(Some(len))
182 }
183
184 fn serialize_struct_variant(
185 self,
186 _name: &'static str,
187 _variant_index: u32,
188 variant: &'static str,
189 len: usize,
190 ) -> Result<StructVariantSerializer, Error> {
191 Ok(StructVariantSerializer {
192 variant: variant.to_string(),
193 pairs: Vec::with_capacity(len),
194 })
195 }
196}
197
198struct SeqSerializer {
200 items: Vec<Value>,
201}
202
203impl ser::SerializeSeq for SeqSerializer {
204 type Ok = Value;
205 type Error = Error;
206
207 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
208 self.items.push(value.serialize(ValueSerializer)?);
209 Ok(())
210 }
211
212 fn end(self) -> Result<Value, Error> {
213 Ok(Value::List(self.items))
214 }
215}
216
217impl ser::SerializeTuple for SeqSerializer {
218 type Ok = Value;
219 type Error = Error;
220
221 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
222 ser::SerializeSeq::serialize_element(self, value)
223 }
224
225 fn end(self) -> Result<Value, Error> {
226 ser::SerializeSeq::end(self)
227 }
228}
229
230impl ser::SerializeTupleStruct for SeqSerializer {
231 type Ok = Value;
232 type Error = Error;
233
234 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
235 ser::SerializeSeq::serialize_element(self, value)
236 }
237
238 fn end(self) -> Result<Value, Error> {
239 ser::SerializeSeq::end(self)
240 }
241}
242
243struct TupleVariantSerializer {
245 variant: String,
246 items: Vec<Value>,
247}
248
249impl ser::SerializeTupleVariant for TupleVariantSerializer {
250 type Ok = Value;
251 type Error = Error;
252
253 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
254 self.items.push(value.serialize(ValueSerializer)?);
255 Ok(())
256 }
257
258 fn end(self) -> Result<Value, Error> {
259 Ok(Value::Dict(vec![(
260 self.variant,
261 Value::List(self.items),
262 )]))
263 }
264}
265
266struct MapSerializer {
268 pairs: Vec<(String, Value)>,
269 next_key: Option<String>,
270}
271
272impl ser::SerializeMap for MapSerializer {
273 type Ok = Value;
274 type Error = Error;
275
276 fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Error> {
277 let key_value = key.serialize(ValueSerializer)?;
278 let key_str = match key_value {
279 Value::String(s) => s,
280 _ => {
281 return Err(Error::new(
282 ErrorKind::UnsupportedType,
283 "map keys must be strings",
284 ))
285 }
286 };
287 self.next_key = Some(key_str);
288 Ok(())
289 }
290
291 fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
292 let key = self.next_key.take().expect("serialize_value called before serialize_key");
293 self.pairs.push((key, value.serialize(ValueSerializer)?));
294 Ok(())
295 }
296
297 fn end(self) -> Result<Value, Error> {
298 Ok(Value::Dict(self.pairs))
299 }
300}
301
302impl ser::SerializeStruct for MapSerializer {
303 type Ok = Value;
304 type Error = Error;
305
306 fn serialize_field<T: ?Sized + Serialize>(
307 &mut self,
308 key: &'static str,
309 value: &T,
310 ) -> Result<(), Error> {
311 self.pairs
312 .push((key.to_string(), value.serialize(ValueSerializer)?));
313 Ok(())
314 }
315
316 fn end(self) -> Result<Value, Error> {
317 Ok(Value::Dict(self.pairs))
318 }
319}
320
321struct StructVariantSerializer {
323 variant: String,
324 pairs: Vec<(String, Value)>,
325}
326
327impl ser::SerializeStructVariant for StructVariantSerializer {
328 type Ok = Value;
329 type Error = Error;
330
331 fn serialize_field<T: ?Sized + Serialize>(
332 &mut self,
333 key: &'static str,
334 value: &T,
335 ) -> Result<(), Error> {
336 self.pairs
337 .push((key.to_string(), value.serialize(ValueSerializer)?));
338 Ok(())
339 }
340
341 fn end(self) -> Result<Value, Error> {
342 Ok(Value::Dict(vec![(
343 self.variant,
344 Value::Dict(self.pairs),
345 )]))
346 }
347}
348
349impl ser::Error for Error {
351 fn custom<T: std::fmt::Display>(msg: T) -> Self {
352 Error::new(ErrorKind::UnsupportedType, msg.to_string())
353 }
354}
355
356#[cfg(test)]
357mod tests {
358 use super::*;
359 use serde::Serialize;
360
361 #[test]
362 fn test_serialize_struct() {
363 #[derive(Serialize)]
364 struct Config {
365 name: String,
366 age: u32,
367 }
368 let config = Config {
369 name: "Alice".to_string(),
370 age: 30,
371 };
372 let s = to_string(&config).unwrap();
373 assert_eq!(s, "name: Alice\nage: 30\n");
374 }
375
376 #[test]
377 fn test_serialize_vec() {
378 let v = vec!["hello", "world"];
379 let s = to_string(&v).unwrap();
380 assert_eq!(s, "- hello\n- world\n");
381 }
382
383 #[test]
384 fn test_serialize_bool() {
385 #[derive(Serialize)]
386 struct Flags {
387 debug: bool,
388 }
389 let flags = Flags { debug: true };
390 let s = to_string(&flags).unwrap();
391 assert_eq!(s, "debug: true\n");
392 }
393
394 #[test]
395 fn test_serialize_option() {
396 #[derive(Serialize)]
397 struct MaybeValue {
398 present: Option<String>,
399 absent: Option<String>,
400 }
401 let v = MaybeValue {
402 present: Some("hello".to_string()),
403 absent: None,
404 };
405 let s = to_string(&v).unwrap();
406 assert_eq!(s, "present: hello\nabsent:\n");
407 }
408
409 #[test]
410 fn test_serialize_enum() {
411 #[derive(Serialize)]
412 enum Color {
413 Red,
414 }
415 let s = to_string(&Color::Red).unwrap();
416 assert_eq!(s, "> Red\n");
417 }
418
419 #[test]
420 fn test_serialize_nested() {
421 #[derive(Serialize)]
422 struct Outer {
423 items: Vec<String>,
424 }
425 let v = Outer {
426 items: vec!["a".to_string(), "b".to_string()],
427 };
428 let s = to_string(&v).unwrap();
429 assert_eq!(s, "items:\n - a\n - b\n");
430 }
431}