serde_intermediate/ser/
text.rs

1use crate::error::*;
2use serde::Serialize;
3use std::io::Write;
4
5pub fn to_vec<T>(value: &T, config: TextConfig) -> Result<Vec<u8>>
6where
7    T: Serialize + ?Sized,
8{
9    let mut result = Vec::with_capacity(256);
10    value.serialize(&mut TextSerializer::new(&mut result, config))?;
11    Ok(result)
12}
13
14pub fn to_vec_compact<T>(value: &T) -> Result<Vec<u8>>
15where
16    T: Serialize + ?Sized,
17{
18    to_vec(value, TextConfig::default())
19}
20
21pub fn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>>
22where
23    T: Serialize + ?Sized,
24{
25    to_vec(
26        value,
27        TextConfig::default().with_style(TextConfigStyle::default_pretty()),
28    )
29}
30
31pub fn to_string<T>(value: &T, config: TextConfig) -> Result<String>
32where
33    T: Serialize + ?Sized,
34{
35    Ok(unsafe { String::from_utf8_unchecked(to_vec(value, config)?) })
36}
37
38pub fn to_string_compact<T>(value: &T) -> Result<String>
39where
40    T: Serialize + ?Sized,
41{
42    to_string(value, TextConfig::default())
43}
44
45pub fn to_string_pretty<T>(value: &T) -> Result<String>
46where
47    T: Serialize + ?Sized,
48{
49    to_string(
50        value,
51        TextConfig::default().with_style(TextConfigStyle::default_pretty()),
52    )
53}
54
55#[derive(Debug, Clone)]
56pub struct TextConfig {
57    pub style: TextConfigStyle,
58    pub numbers_with_type: bool,
59}
60
61impl Default for TextConfig {
62    fn default() -> Self {
63        Self {
64            style: TextConfigStyle::Default,
65            numbers_with_type: true,
66        }
67    }
68}
69
70impl TextConfig {
71    pub fn with_style(mut self, style: TextConfigStyle) -> Self {
72        self.style = style;
73        self
74    }
75
76    pub fn with_numbers_with_type(mut self, mode: bool) -> Self {
77        self.numbers_with_type = mode;
78        self
79    }
80}
81
82#[derive(Debug, Default, Clone)]
83pub enum TextConfigStyle {
84    #[default]
85    Default,
86    Pretty {
87        level: usize,
88        indent: Option<usize>,
89    },
90}
91
92impl TextConfigStyle {
93    pub fn pretty(indent: Option<usize>) -> Self {
94        Self::Pretty { indent, level: 0 }
95    }
96
97    pub fn default_pretty() -> Self {
98        Self::Pretty {
99            indent: Some(2),
100            level: 0,
101        }
102    }
103
104    pub fn is_pretty(&self) -> bool {
105        matches!(self, Self::Pretty { .. })
106    }
107}
108
109#[derive(Debug, Default, Clone)]
110pub struct TextSerializer<W>
111where
112    W: Write,
113{
114    stream: W,
115    config: TextConfig,
116}
117
118impl<W> TextSerializer<W>
119where
120    W: Write,
121{
122    pub fn new(stream: W, config: TextConfig) -> Self {
123        Self { stream, config }
124    }
125
126    pub fn into_inner(self) -> W {
127        self.stream
128    }
129
130    fn push_level(&mut self) {
131        if let TextConfigStyle::Pretty { level, .. } = &mut self.config.style {
132            *level += 1;
133        }
134    }
135
136    fn pop_level(&mut self) {
137        if let TextConfigStyle::Pretty { level, .. } = &mut self.config.style {
138            if *level > 0 {
139                *level -= 1;
140            }
141        }
142    }
143
144    fn map_result<T>(result: std::io::Result<T>) -> Result<T> {
145        result.map_err(|e| Error::Message(format!("{}", e)))
146    }
147
148    fn write_whitespace(&mut self) -> Result<()> {
149        if self.config.style.is_pretty() {
150            Self::map_result(write!(&mut self.stream, " "))
151        } else {
152            Ok(())
153        }
154    }
155
156    fn write_separator(&mut self) -> Result<()> {
157        if let TextConfigStyle::Pretty { indent, .. } = &self.config.style {
158            if indent.is_none() {
159                return self.write_raw(", ");
160            }
161        }
162        self.write_raw(",")
163    }
164
165    fn write_new_line_indent(&mut self) -> Result<()> {
166        #[allow(clippy::collapsible_match)]
167        if let TextConfigStyle::Pretty { level, indent, .. } = &mut self.config.style {
168            if let Some(indent) = *indent {
169                Self::map_result(write!(
170                    &mut self.stream,
171                    "\n{:indent$}",
172                    "",
173                    indent = (*level) * indent
174                ))?;
175            }
176        }
177        Ok(())
178    }
179
180    fn write_raw(&mut self, value: &str) -> Result<()> {
181        Self::map_result(write!(&mut self.stream, "{}", value))
182    }
183
184    fn write_from_string(&mut self, value: impl ToString, typename: &str) -> Result<()> {
185        Self::map_result(write!(
186            &mut self.stream,
187            "{}_{}",
188            value.to_string(),
189            typename
190        ))
191    }
192
193    fn write_str(&mut self, value: &str) -> Result<()> {
194        Self::map_result(write!(&mut self.stream, "{:?}", value))
195    }
196
197    fn write_bytes(&mut self, value: &[u8]) -> Result<()> {
198        Self::map_result(write!(&mut self.stream, "0x"))?;
199        for byte in value {
200            Self::map_result(write!(&mut self.stream, "{:02x}", byte))?;
201        }
202        Ok(())
203    }
204}
205
206macro_rules! impl_serialize_number {
207    ($name:ident, $type:ident) => {
208        fn $name(self, v: $type) -> Result<Self::Ok> {
209            self.write_from_string(v, stringify!($type))
210        }
211    };
212}
213
214impl<'a, W> serde::ser::Serializer for &'a mut TextSerializer<W>
215where
216    W: Write,
217{
218    type Ok = ();
219    type Error = Error;
220    type SerializeSeq = SeqSerializer<'a, W>;
221    type SerializeTuple = TupleSerializer<'a, W>;
222    type SerializeTupleStruct = TupleStructSerializer<'a, W>;
223    type SerializeTupleVariant = TupleVariantSerializer<'a, W>;
224    type SerializeMap = MapSerializer<'a, W>;
225    type SerializeStruct = StructSerializer<'a, W>;
226    type SerializeStructVariant = StructVariantSerializer<'a, W>;
227
228    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
229        if v {
230            self.write_raw("true")
231        } else {
232            self.write_raw("false")
233        }
234    }
235
236    impl_serialize_number!(serialize_i8, i8);
237    impl_serialize_number!(serialize_i16, i16);
238    impl_serialize_number!(serialize_i32, i32);
239    impl_serialize_number!(serialize_i64, i64);
240    impl_serialize_number!(serialize_i128, i128);
241    impl_serialize_number!(serialize_u8, u8);
242    impl_serialize_number!(serialize_u16, u16);
243    impl_serialize_number!(serialize_u32, u32);
244    impl_serialize_number!(serialize_u64, u64);
245    impl_serialize_number!(serialize_u128, u128);
246    impl_serialize_number!(serialize_f32, f32);
247    impl_serialize_number!(serialize_f64, f64);
248
249    fn serialize_char(self, v: char) -> Result<Self::Ok> {
250        TextSerializer::<W>::map_result(write!(&mut self.stream, "'{}'", v))
251    }
252
253    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
254        self.write_str(v)
255    }
256
257    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
258        self.write_bytes(v)
259    }
260
261    fn serialize_none(self) -> Result<Self::Ok> {
262        self.write_raw("?")
263    }
264
265    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
266    where
267        T: ?Sized + Serialize,
268    {
269        self.write_raw("?")?;
270        self.write_whitespace()?;
271        self.write_raw("=")?;
272        self.write_whitespace()?;
273        value.serialize(self)
274    }
275
276    fn serialize_unit(self) -> Result<Self::Ok> {
277        self.write_raw("!")
278    }
279
280    fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok> {
281        self.write_raw("#!")
282    }
283
284    fn serialize_unit_variant(
285        self,
286        _: &'static str,
287        _: u32,
288        variant: &'static str,
289    ) -> Result<Self::Ok> {
290        self.write_raw("@")?;
291        self.write_raw(variant)?;
292        self.write_whitespace()?;
293        self.write_raw("!")
294    }
295
296    fn serialize_newtype_struct<T>(self, _: &'static str, value: &T) -> Result<Self::Ok>
297    where
298        T: ?Sized + Serialize,
299    {
300        self.write_raw("$")?;
301        self.write_whitespace()?;
302        self.write_raw("=")?;
303        self.write_whitespace()?;
304        value.serialize(self)
305    }
306
307    fn serialize_newtype_variant<T>(
308        self,
309        _: &'static str,
310        _: u32,
311        variant: &'static str,
312        value: &T,
313    ) -> Result<Self::Ok>
314    where
315        T: ?Sized + Serialize,
316    {
317        self.write_raw("@")?;
318        self.write_raw(variant)?;
319        self.write_whitespace()?;
320        self.write_raw("$")?;
321        self.write_whitespace()?;
322        self.write_raw("=")?;
323        self.write_whitespace()?;
324        value.serialize(self)
325    }
326
327    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
328        self.write_raw("[")?;
329        self.push_level();
330        Ok(SeqSerializer {
331            stream: self,
332            first: true,
333        })
334    }
335
336    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
337        self.write_raw("(")?;
338        self.push_level();
339        Ok(TupleSerializer {
340            stream: self,
341            first: true,
342        })
343    }
344
345    fn serialize_tuple_struct(
346        self,
347        _: &'static str,
348        _: usize,
349    ) -> Result<Self::SerializeTupleStruct> {
350        self.write_raw("#")?;
351        self.write_whitespace()?;
352        self.write_raw("(")?;
353        self.push_level();
354        Ok(TupleStructSerializer {
355            stream: self,
356            first: true,
357        })
358    }
359
360    fn serialize_tuple_variant(
361        self,
362        _: &'static str,
363        _: u32,
364        variant: &'static str,
365        _: usize,
366    ) -> Result<Self::SerializeTupleVariant> {
367        self.write_raw("@")?;
368        self.write_raw(variant)?;
369        self.write_whitespace()?;
370        self.write_raw("(")?;
371        self.push_level();
372        Ok(TupleVariantSerializer {
373            stream: self,
374            first: true,
375        })
376    }
377
378    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
379        self.write_raw("{")?;
380        self.push_level();
381        Ok(MapSerializer {
382            stream: self,
383            first: true,
384        })
385    }
386
387    fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
388        self.write_raw("#")?;
389        self.write_whitespace()?;
390        self.write_raw("{")?;
391        self.push_level();
392        Ok(StructSerializer {
393            stream: self,
394            first: true,
395        })
396    }
397
398    fn serialize_struct_variant(
399        self,
400        _: &'static str,
401        _: u32,
402        variant: &'static str,
403        _: usize,
404    ) -> Result<Self::SerializeStructVariant> {
405        self.write_raw("@")?;
406        self.write_raw(variant)?;
407        self.write_whitespace()?;
408        self.write_raw("#")?;
409        self.write_whitespace()?;
410        self.write_raw("{")?;
411        self.push_level();
412        Ok(StructVariantSerializer {
413            stream: self,
414            first: true,
415        })
416    }
417}
418
419pub struct SeqSerializer<'a, W>
420where
421    W: Write,
422{
423    stream: &'a mut TextSerializer<W>,
424    first: bool,
425}
426
427impl<W> serde::ser::SerializeSeq for SeqSerializer<'_, W>
428where
429    W: Write,
430{
431    type Ok = ();
432    type Error = Error;
433
434    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
435    where
436        T: ?Sized + Serialize,
437    {
438        if self.first {
439            self.first = false;
440        } else {
441            self.stream.write_separator()?;
442        }
443        self.stream.write_new_line_indent()?;
444        value.serialize(&mut *self.stream)
445    }
446
447    fn end(self) -> Result<Self::Ok> {
448        self.stream.pop_level();
449        self.stream.write_new_line_indent()?;
450        self.stream.write_raw("]")
451    }
452}
453
454pub struct TupleSerializer<'a, W>
455where
456    W: Write,
457{
458    stream: &'a mut TextSerializer<W>,
459    first: bool,
460}
461
462impl<W> serde::ser::SerializeTuple for TupleSerializer<'_, W>
463where
464    W: Write,
465{
466    type Ok = ();
467    type Error = Error;
468
469    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
470    where
471        T: ?Sized + Serialize,
472    {
473        if self.first {
474            self.first = false;
475        } else {
476            self.stream.write_separator()?;
477        }
478        self.stream.write_new_line_indent()?;
479        value.serialize(&mut *self.stream)
480    }
481
482    fn end(self) -> Result<Self::Ok> {
483        self.stream.pop_level();
484        self.stream.write_new_line_indent()?;
485        self.stream.write_raw(")")
486    }
487}
488
489pub struct TupleStructSerializer<'a, W>
490where
491    W: Write,
492{
493    stream: &'a mut TextSerializer<W>,
494    first: bool,
495}
496
497impl<W> serde::ser::SerializeTupleStruct for TupleStructSerializer<'_, W>
498where
499    W: Write,
500{
501    type Ok = ();
502    type Error = Error;
503
504    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
505    where
506        T: ?Sized + Serialize,
507    {
508        if self.first {
509            self.first = false;
510        } else {
511            self.stream.write_separator()?;
512        }
513        self.stream.write_new_line_indent()?;
514        value.serialize(&mut *self.stream)
515    }
516
517    fn end(self) -> Result<Self::Ok> {
518        self.stream.pop_level();
519        self.stream.write_new_line_indent()?;
520        self.stream.write_raw(")")
521    }
522}
523
524pub struct TupleVariantSerializer<'a, W>
525where
526    W: Write,
527{
528    stream: &'a mut TextSerializer<W>,
529    first: bool,
530}
531
532impl<W> serde::ser::SerializeTupleVariant for TupleVariantSerializer<'_, W>
533where
534    W: Write,
535{
536    type Ok = ();
537    type Error = Error;
538
539    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
540    where
541        T: ?Sized + Serialize,
542    {
543        if self.first {
544            self.first = false;
545        } else {
546            self.stream.write_separator()?;
547        }
548        self.stream.write_new_line_indent()?;
549        value.serialize(&mut *self.stream)
550    }
551
552    fn end(self) -> Result<Self::Ok> {
553        self.stream.pop_level();
554        self.stream.write_new_line_indent()?;
555        self.stream.write_raw(")")
556    }
557}
558
559pub struct MapSerializer<'a, W>
560where
561    W: Write,
562{
563    stream: &'a mut TextSerializer<W>,
564    first: bool,
565}
566
567impl<W> serde::ser::SerializeMap for MapSerializer<'_, W>
568where
569    W: Write,
570{
571    type Ok = ();
572    type Error = Error;
573
574    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
575    where
576        T: ?Sized + Serialize,
577    {
578        if self.first {
579            self.first = false;
580        } else {
581            self.stream.write_separator()?;
582        }
583        self.stream.write_new_line_indent()?;
584        key.serialize(&mut *self.stream)
585    }
586
587    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
588    where
589        T: ?Sized + Serialize,
590    {
591        self.stream.write_raw(":")?;
592        self.stream.write_whitespace()?;
593        value.serialize(&mut *self.stream)
594    }
595
596    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
597    where
598        K: ?Sized + Serialize,
599        V: ?Sized + Serialize,
600    {
601        if self.first {
602            self.first = false;
603        } else {
604            self.stream.write_separator()?;
605        }
606        self.stream.write_new_line_indent()?;
607        key.serialize(&mut *self.stream)?;
608        self.stream.write_raw(":")?;
609        self.stream.write_whitespace()?;
610        value.serialize(&mut *self.stream)
611    }
612
613    fn end(self) -> Result<Self::Ok> {
614        self.stream.pop_level();
615        self.stream.write_new_line_indent()?;
616        self.stream.write_raw("}")
617    }
618}
619
620pub struct StructSerializer<'a, W>
621where
622    W: Write,
623{
624    stream: &'a mut TextSerializer<W>,
625    first: bool,
626}
627
628impl<W> serde::ser::SerializeStruct for StructSerializer<'_, W>
629where
630    W: Write,
631{
632    type Ok = ();
633    type Error = Error;
634
635    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
636    where
637        T: ?Sized + Serialize,
638    {
639        if self.first {
640            self.first = false;
641        } else {
642            self.stream.write_separator()?;
643        }
644        self.stream.write_new_line_indent()?;
645        self.stream.write_raw(key)?;
646        self.stream.write_raw(":")?;
647        self.stream.write_whitespace()?;
648        value.serialize(&mut *self.stream)
649    }
650
651    fn end(self) -> Result<()> {
652        self.stream.pop_level();
653        self.stream.write_new_line_indent()?;
654        self.stream.write_raw("}")
655    }
656}
657
658pub struct StructVariantSerializer<'a, W>
659where
660    W: Write,
661{
662    stream: &'a mut TextSerializer<W>,
663    first: bool,
664}
665
666impl<W> serde::ser::SerializeStructVariant for StructVariantSerializer<'_, W>
667where
668    W: Write,
669{
670    type Ok = ();
671    type Error = Error;
672
673    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
674    where
675        T: ?Sized + Serialize,
676    {
677        if self.first {
678            self.first = false;
679        } else {
680            self.stream.write_separator()?;
681        }
682        self.stream.write_new_line_indent()?;
683        self.stream.write_raw(key)?;
684        self.stream.write_raw(":")?;
685        self.stream.write_whitespace()?;
686        value.serialize(&mut *self.stream)
687    }
688
689    fn end(self) -> Result<()> {
690        self.stream.pop_level();
691        self.stream.write_new_line_indent()?;
692        self.stream.write_raw("}")
693    }
694}