Skip to main content

serde_structprop/
ser.rs

1//! Serde [`Serializer`](serde::Serializer) for the structprop format.
2//!
3//! The public entry point is [`to_string`].  Internally a `Serializer` walks
4//! the serde data model and writes structprop text directly into an output
5//! [`String`].
6//!
7//! # Type mapping
8//!
9//! | Rust / serde | Structprop output |
10//! |---|---|
11//! | `bool` | `true` or `false` scalar |
12//! | `i8`–`i64`, `u8`–`u64` | bare integer scalar (e.g. `42`, `-7`) |
13//! | `f32`, `f64` | bare float scalar (e.g. `3.14`) |
14//! | `char` | bare single-character scalar (quoted if the character is special) |
15//! | `String` / `&str` | bare scalar, or `"quoted"` if it contains spaces, tabs, newlines, carriage returns, `#`, `{`, `}`, `=`, or is empty |
16//! | `None` / `()` / unit struct | `null` scalar |
17//! | newtype struct | transparent — serializes as the inner value |
18//! | struct / map | `key { … }` block at the current indentation level |
19//! | `Vec<T>` / sequence / tuple / tuple struct | `= { … }` inline list |
20//! | unit enum variant | bare variant name scalar |
21//! | newtype enum variant | `variant_name = <scalar or list>` |
22//! | tuple enum variant | `variant_name = { … }` list |
23//! | struct enum variant | `variant_name { … }` block |
24
25use std::fmt::Write as FmtWrite;
26
27use crate::error::{Error, Result};
28use serde::ser::{self, Serialize};
29
30// ---------------------------------------------------------------------------
31// Public entry point
32// ---------------------------------------------------------------------------
33
34/// Serialize `value` into a structprop-formatted [`String`].
35///
36/// Top-level structs and maps produce a flat sequence of `key = value` /
37/// `key { … }` entries with no enclosing braces.  Sequences produce a bare
38/// `{\n … \n}` block.
39///
40/// # Errors
41///
42/// Returns [`Error::UnsupportedType`] if `T` contains raw byte slices, or
43/// [`Error::Message`] for any other serde-level serialization error.
44///
45/// # Examples
46///
47/// ```
48/// use serde::Serialize;
49/// use serde_structprop::to_string;
50///
51/// #[derive(Serialize)]
52/// struct Cfg { host: String, port: u16 }
53///
54/// let s = to_string(&Cfg { host: "localhost".into(), port: 8080 }).unwrap();
55/// assert!(s.contains("host = localhost"));
56/// assert!(s.contains("port = 8080"));
57/// ```
58pub fn to_string<T: Serialize>(value: &T) -> Result<String> {
59    let mut ser = Serializer::new(0);
60    value.serialize(&mut ser)?;
61    Ok(ser.output)
62}
63
64// ---------------------------------------------------------------------------
65// Serializer
66// ---------------------------------------------------------------------------
67
68/// Core serializer that accumulates structprop text in `output`.
69///
70/// `indent` is the current nesting depth; each level adds two spaces of
71/// leading whitespace to each emitted line.
72pub struct Serializer {
73    /// The accumulated output string.
74    pub(crate) output: String,
75    /// Current indentation level in spaces.
76    indent: usize,
77}
78
79impl Serializer {
80    /// Create a new [`Serializer`] starting at `indent` spaces of indentation.
81    fn new(indent: usize) -> Self {
82        Serializer {
83            output: String::new(),
84            indent,
85        }
86    }
87
88    /// Return a string of `self.indent` spaces.
89    fn pad(&self) -> String {
90        " ".repeat(self.indent)
91    }
92}
93
94// ---------------------------------------------------------------------------
95// Helpers
96// ---------------------------------------------------------------------------
97
98/// Wrap `s` in double quotes if it is empty or contains any of the following
99/// characters: space (` `), tab (`\t`), newline (`\n`), carriage return
100/// (`\r`), `#`, `{`, `}`, or `=`.  Otherwise return it unchanged.
101///
102/// Empty strings are always quoted so that they survive a round-trip: a bare
103/// empty value would produce `key = ` with no token after `=`, which the
104/// parser cannot recover from.
105///
106/// The structprop format has no escape sequences. A `"` character can appear
107/// inside a *bare* (unquoted) term, but not inside a *quoted* term. Therefore,
108/// strings that both require quoting (contain a special character) and contain
109/// a literal `"` will serialize to syntactically ambiguous output. Such strings
110/// cannot round-trip through this format.
111fn escape(s: &str) -> String {
112    if s.is_empty()
113        || s.chars()
114            .any(|c| matches!(c, ' ' | '\t' | '\n' | '\r' | '#' | '{' | '}' | '='))
115    {
116        format!("\"{s}\"")
117    } else {
118        s.to_owned()
119    }
120}
121
122// ---------------------------------------------------------------------------
123// serde::Serializer impl
124// ---------------------------------------------------------------------------
125
126impl<'a> ser::Serializer for &'a mut Serializer {
127    type Ok = ();
128    type Error = Error;
129
130    /// Compound serializer types.
131    type SerializeSeq = SeqSerializer<'a>;
132    /// Compound serializer types.
133    type SerializeTuple = SeqSerializer<'a>;
134    /// Compound serializer types.
135    type SerializeTupleStruct = SeqSerializer<'a>;
136    /// Compound serializer types.
137    type SerializeTupleVariant = SeqSerializer<'a>;
138    /// Compound serializer types.
139    type SerializeMap = MapSerializer<'a>;
140    /// Compound serializer types.
141    type SerializeStruct = MapSerializer<'a>;
142    /// Compound serializer types.
143    type SerializeStructVariant = MapSerializer<'a>;
144
145    fn serialize_bool(self, v: bool) -> Result<()> {
146        self.output.push_str(if v { "true" } else { "false" });
147        Ok(())
148    }
149
150    fn serialize_i8(self, v: i8) -> Result<()> {
151        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
152    }
153
154    fn serialize_i16(self, v: i16) -> Result<()> {
155        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
156    }
157
158    fn serialize_i32(self, v: i32) -> Result<()> {
159        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
160    }
161
162    fn serialize_i64(self, v: i64) -> Result<()> {
163        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
164    }
165
166    fn serialize_u8(self, v: u8) -> Result<()> {
167        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
168    }
169
170    fn serialize_u16(self, v: u16) -> Result<()> {
171        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
172    }
173
174    fn serialize_u32(self, v: u32) -> Result<()> {
175        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
176    }
177
178    fn serialize_u64(self, v: u64) -> Result<()> {
179        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
180    }
181
182    fn serialize_f32(self, v: f32) -> Result<()> {
183        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
184    }
185
186    fn serialize_f64(self, v: f64) -> Result<()> {
187        write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
188    }
189
190    fn serialize_char(self, v: char) -> Result<()> {
191        // Route through escape() so special characters are quoted.
192        self.output.push_str(&escape(&v.to_string()));
193        Ok(())
194    }
195
196    fn serialize_str(self, v: &str) -> Result<()> {
197        self.output.push_str(&escape(v));
198        Ok(())
199    }
200
201    fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
202        Err(Error::UnsupportedType("bytes"))
203    }
204
205    fn serialize_none(self) -> Result<()> {
206        self.output.push_str("null");
207        Ok(())
208    }
209
210    fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<()> {
211        value.serialize(self)
212    }
213
214    fn serialize_unit(self) -> Result<()> {
215        self.output.push_str("null");
216        Ok(())
217    }
218
219    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
220        self.serialize_unit()
221    }
222
223    fn serialize_unit_variant(
224        self,
225        _name: &'static str,
226        _index: u32,
227        variant: &'static str,
228    ) -> Result<()> {
229        self.serialize_str(variant)
230    }
231
232    fn serialize_newtype_struct<T: Serialize + ?Sized>(
233        self,
234        _name: &'static str,
235        value: &T,
236    ) -> Result<()> {
237        value.serialize(self)
238    }
239
240    fn serialize_newtype_variant<T: Serialize + ?Sized>(
241        self,
242        _name: &'static str,
243        _index: u32,
244        variant: &'static str,
245        value: &T,
246    ) -> Result<()> {
247        // Encode as `variant = <payload>` (scalar) or `variant { … }` (object block)
248        // so the parser produces Object({"variant": payload}), which is exactly what
249        // deserialize_enum expects for newtype variants.
250        let mut ms = MapSerializer {
251            ser: self,
252            current_key: None,
253            variant_name: None,
254        };
255        ms.write_kv(variant, value)
256    }
257
258    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
259        Ok(SeqSerializer {
260            parent: self,
261            items: Vec::new(),
262            variant: None,
263        })
264    }
265
266    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
267        self.serialize_seq(Some(len))
268    }
269
270    fn serialize_tuple_struct(
271        self,
272        _name: &'static str,
273        len: usize,
274    ) -> Result<Self::SerializeTupleStruct> {
275        self.serialize_seq(Some(len))
276    }
277
278    fn serialize_tuple_variant(
279        self,
280        _name: &'static str,
281        _index: u32,
282        variant: &'static str,
283        _len: usize,
284    ) -> Result<Self::SerializeTupleVariant> {
285        Ok(SeqSerializer {
286            parent: self,
287            items: Vec::new(),
288            variant: Some(variant.to_owned()),
289        })
290    }
291
292    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
293        Ok(MapSerializer {
294            ser: self,
295            current_key: None,
296            variant_name: None,
297        })
298    }
299
300    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
301        self.serialize_map(Some(len))
302    }
303
304    fn serialize_struct_variant(
305        self,
306        _name: &'static str,
307        _index: u32,
308        variant: &'static str,
309        _len: usize,
310    ) -> Result<Self::SerializeStructVariant> {
311        Ok(MapSerializer {
312            ser: self,
313            current_key: None,
314            variant_name: Some(variant.to_owned()),
315        })
316    }
317}
318
319// ---------------------------------------------------------------------------
320// SeqSerializer – handles sequences / arrays
321// ---------------------------------------------------------------------------
322
323/// [`ser::SerializeSeq`] (and related tuple impls) that collects rendered items
324/// then emits them as a `{ … }` block.
325pub struct SeqSerializer<'a> {
326    parent: &'a mut Serializer,
327    /// Each element serialized to a string, accumulated for deferred emission.
328    items: Vec<String>,
329    /// Set for tuple variants: the variant name to wrap the array under.
330    variant: Option<String>,
331}
332
333impl ser::SerializeSeq for SeqSerializer<'_> {
334    type Ok = ();
335    type Error = Error;
336
337    fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
338        let mut inner = Serializer::new(0);
339        value.serialize(&mut inner)?;
340        self.items.push(inner.output);
341        Ok(())
342    }
343
344    fn end(self) -> Result<()> {
345        let pad = self.parent.pad();
346        let inner_pad = " ".repeat(self.parent.indent + 2);
347        writeln!(self.parent.output, "{{").map_err(|e| Error::Message(e.to_string()))?;
348        for item in &self.items {
349            writeln!(self.parent.output, "{inner_pad}{item}")
350                .map_err(|e| Error::Message(e.to_string()))?;
351        }
352        writeln!(self.parent.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))
353    }
354}
355
356impl ser::SerializeTuple for SeqSerializer<'_> {
357    type Ok = ();
358    type Error = Error;
359
360    fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
361        ser::SerializeSeq::serialize_element(self, value)
362    }
363
364    fn end(self) -> Result<()> {
365        ser::SerializeSeq::end(self)
366    }
367}
368
369impl ser::SerializeTupleStruct for SeqSerializer<'_> {
370    type Ok = ();
371    type Error = Error;
372
373    fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
374        ser::SerializeSeq::serialize_element(self, value)
375    }
376
377    fn end(self) -> Result<()> {
378        ser::SerializeSeq::end(self)
379    }
380}
381
382impl ser::SerializeTupleVariant for SeqSerializer<'_> {
383    type Ok = ();
384    type Error = Error;
385
386    fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
387        ser::SerializeSeq::serialize_element(self, value)
388    }
389
390    fn end(self) -> Result<()> {
391        // Emit as `variant = { item1\n  item2\n … }` so the parser produces
392        // Object({"variant": Array([…])}), matching what deserialize_enum expects.
393        let variant = self.variant.ok_or_else(|| {
394            Error::Message("variant name missing in SerializeTupleVariant::end".into())
395        })?;
396        let pad = self.parent.pad();
397        let inner_pad = " ".repeat(self.parent.indent + 2);
398        writeln!(self.parent.output, "{pad}{} = {{", escape(&variant))
399            .map_err(|e| Error::Message(e.to_string()))?;
400        for item in &self.items {
401            writeln!(self.parent.output, "{inner_pad}{item}")
402                .map_err(|e| Error::Message(e.to_string()))?;
403        }
404        writeln!(self.parent.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))
405    }
406}
407
408// ---------------------------------------------------------------------------
409// KeySerializer – accepts only string keys; rejects everything else
410// ---------------------------------------------------------------------------
411
412/// A minimal serializer that collects a `str`/`String` map key and returns
413/// [`Error::KeyMustBeString`] for every other type, including `char` and
414/// unit-enum variants.  Only `serialize_str` (and `serialize_newtype_struct`
415/// delegating to it) succeed.
416struct KeySerializer(String);
417
418impl ser::Serializer for &mut KeySerializer {
419    type Ok = ();
420    type Error = Error;
421    type SerializeSeq = ser::Impossible<(), Error>;
422    type SerializeTuple = ser::Impossible<(), Error>;
423    type SerializeTupleStruct = ser::Impossible<(), Error>;
424    type SerializeTupleVariant = ser::Impossible<(), Error>;
425    type SerializeMap = ser::Impossible<(), Error>;
426    type SerializeStruct = ser::Impossible<(), Error>;
427    type SerializeStructVariant = ser::Impossible<(), Error>;
428
429    fn serialize_str(self, v: &str) -> Result<()> {
430        v.clone_into(&mut self.0);
431        Ok(())
432    }
433
434    fn serialize_bool(self, _v: bool) -> Result<()> {
435        Err(Error::KeyMustBeString)
436    }
437    fn serialize_i8(self, _v: i8) -> Result<()> {
438        Err(Error::KeyMustBeString)
439    }
440    fn serialize_i16(self, _v: i16) -> Result<()> {
441        Err(Error::KeyMustBeString)
442    }
443    fn serialize_i32(self, _v: i32) -> Result<()> {
444        Err(Error::KeyMustBeString)
445    }
446    fn serialize_i64(self, _v: i64) -> Result<()> {
447        Err(Error::KeyMustBeString)
448    }
449    fn serialize_u8(self, _v: u8) -> Result<()> {
450        Err(Error::KeyMustBeString)
451    }
452    fn serialize_u16(self, _v: u16) -> Result<()> {
453        Err(Error::KeyMustBeString)
454    }
455    fn serialize_u32(self, _v: u32) -> Result<()> {
456        Err(Error::KeyMustBeString)
457    }
458    fn serialize_u64(self, _v: u64) -> Result<()> {
459        Err(Error::KeyMustBeString)
460    }
461    fn serialize_f32(self, _v: f32) -> Result<()> {
462        Err(Error::KeyMustBeString)
463    }
464    fn serialize_f64(self, _v: f64) -> Result<()> {
465        Err(Error::KeyMustBeString)
466    }
467    fn serialize_char(self, _v: char) -> Result<()> {
468        Err(Error::KeyMustBeString)
469    }
470    fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
471        Err(Error::KeyMustBeString)
472    }
473    fn serialize_none(self) -> Result<()> {
474        Err(Error::KeyMustBeString)
475    }
476    fn serialize_some<T: Serialize + ?Sized>(self, _v: &T) -> Result<()> {
477        Err(Error::KeyMustBeString)
478    }
479    fn serialize_unit(self) -> Result<()> {
480        Err(Error::KeyMustBeString)
481    }
482    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
483        Err(Error::KeyMustBeString)
484    }
485    fn serialize_unit_variant(
486        self,
487        _name: &'static str,
488        _idx: u32,
489        _variant: &'static str,
490    ) -> Result<()> {
491        Err(Error::KeyMustBeString)
492    }
493    fn serialize_newtype_struct<T: Serialize + ?Sized>(
494        self,
495        _name: &'static str,
496        value: &T,
497    ) -> Result<()> {
498        value.serialize(self)
499    }
500    fn serialize_newtype_variant<T: Serialize + ?Sized>(
501        self,
502        _name: &'static str,
503        _idx: u32,
504        _variant: &'static str,
505        _value: &T,
506    ) -> Result<()> {
507        Err(Error::KeyMustBeString)
508    }
509    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
510        Err(Error::KeyMustBeString)
511    }
512    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
513        Err(Error::KeyMustBeString)
514    }
515    fn serialize_tuple_struct(
516        self,
517        _name: &'static str,
518        _len: usize,
519    ) -> Result<Self::SerializeTupleStruct> {
520        Err(Error::KeyMustBeString)
521    }
522    fn serialize_tuple_variant(
523        self,
524        _name: &'static str,
525        _idx: u32,
526        _variant: &'static str,
527        _len: usize,
528    ) -> Result<Self::SerializeTupleVariant> {
529        Err(Error::KeyMustBeString)
530    }
531    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
532        Err(Error::KeyMustBeString)
533    }
534    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
535        Err(Error::KeyMustBeString)
536    }
537    fn serialize_struct_variant(
538        self,
539        _name: &'static str,
540        _idx: u32,
541        _variant: &'static str,
542        _len: usize,
543    ) -> Result<Self::SerializeStructVariant> {
544        Err(Error::KeyMustBeString)
545    }
546}
547
548// ---------------------------------------------------------------------------
549// MapSerializer – handles maps and structs
550// ---------------------------------------------------------------------------
551
552/// [`ser::SerializeMap`] (and struct impls) that writes `key = value` /
553/// `key { … }` entries one at a time.
554pub struct MapSerializer<'a> {
555    ser: &'a mut Serializer,
556    /// The most recently serialized key, waiting for its value.
557    current_key: Option<String>,
558    /// If `Some`, wrap all emitted content in a `variant_name { … }` block.
559    variant_name: Option<String>,
560}
561
562impl MapSerializer<'_> {
563    /// Serialize a single `key = value` or `key { … }` entry into `self.ser`.
564    fn write_kv<T: Serialize + ?Sized>(&mut self, key: &str, value: &T) -> Result<()> {
565        let indent = self.ser.indent;
566        let pad = " ".repeat(indent);
567
568        // Serialize the value at the *current* indentation level.  This single
569        // call is sufficient for scalars and for array blocks, whose output is
570        // already formatted correctly:
571        //
572        //   scalar  →  no newlines, used directly as the RHS of `key = value`
573        //   array   →  `{\n<items at indent+2>\n<indent>}\n`, written inline
574        //               as `key = {…}` by `writeln!` below
575        //
576        // Only struct/map (multi-line, not starting with `{` or `"`) needs the
577        // content indented two levels deeper than the current key, so we
578        // re-serialize those at `indent+2`.  This is the only case where
579        // `Serialize` is invoked twice.
580        let mut first = Serializer::new(indent);
581        value.serialize(&mut first)?;
582        let rendered = first.output;
583
584        if rendered.contains('\n')
585            && !rendered.trim_start().starts_with('{')
586            && !rendered.trim_start().starts_with('"')
587        {
588            // Multi-line object block → `key {\n  <fields at indent+2>\n}\n`
589            // Re-serialize at the correct child indentation so nested fields
590            // sit two levels deeper than the enclosing key.  We must not
591            // blindly re-indent the first-pass output line-by-line because
592            // doing so would corrupt any quoted scalar whose value contains a
593            // literal newline (the continuation line is not a separate field).
594            writeln!(self.ser.output, "{pad}{} {{", escape(key))
595                .map_err(|e| Error::Message(e.to_string()))?;
596            let mut inner = Serializer::new(indent + 2);
597            value.serialize(&mut inner)?;
598            self.ser.output.push_str(&inner.output);
599            writeln!(self.ser.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))?;
600        } else if rendered.contains('\n') {
601            // Multi-line array block starting with `{`.
602            // The first-pass output is already at the right indentation
603            // (`{` inline, items at `indent+2`, `}` at `indent`), so we
604            // reuse it without a second `serialize` call.
605            writeln!(
606                self.ser.output,
607                "{pad}{} = {}",
608                escape(key),
609                rendered.trim_end()
610            )
611            .map_err(|e| Error::Message(e.to_string()))?;
612        } else {
613            // Scalar (no newlines, or a quoted scalar — both fit on one line).
614            let rendered = rendered.trim_end_matches('\n');
615            writeln!(self.ser.output, "{pad}{} = {rendered}", escape(key))
616                .map_err(|e| Error::Message(e.to_string()))?;
617        }
618        Ok(())
619    }
620}
621
622impl ser::SerializeMap for MapSerializer<'_> {
623    type Ok = ();
624    type Error = Error;
625
626    fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<()> {
627        let mut ks = KeySerializer(String::new());
628        key.serialize(&mut ks)?;
629        self.current_key = Some(ks.0);
630        Ok(())
631    }
632
633    fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
634        let key = self
635            .current_key
636            .take()
637            .ok_or_else(|| Error::Parse("serialize_value called before serialize_key".into()))?;
638        self.write_kv(&key, value)
639    }
640
641    fn end(self) -> Result<()> {
642        if let Some(variant) = self.variant_name {
643            // Wrap the content we already wrote in `variant { … }`.
644            let pad = " ".repeat(self.ser.indent.saturating_sub(2));
645            let header = format!("{pad}{} {{\n", escape(&variant));
646            let footer = format!("{pad}}}\n");
647            self.ser.output.insert_str(0, &header);
648            self.ser.output.push_str(&footer);
649        }
650        Ok(())
651    }
652}
653
654impl ser::SerializeStruct for MapSerializer<'_> {
655    type Ok = ();
656    type Error = Error;
657
658    fn serialize_field<T: Serialize + ?Sized>(
659        &mut self,
660        key: &'static str,
661        value: &T,
662    ) -> Result<()> {
663        self.write_kv(key, value)
664    }
665
666    fn end(self) -> Result<()> {
667        ser::SerializeMap::end(self)
668    }
669}
670
671impl ser::SerializeStructVariant for MapSerializer<'_> {
672    type Ok = ();
673    type Error = Error;
674
675    fn serialize_field<T: Serialize + ?Sized>(
676        &mut self,
677        key: &'static str,
678        value: &T,
679    ) -> Result<()> {
680        self.write_kv(key, value)
681    }
682
683    fn end(self) -> Result<()> {
684        ser::SerializeMap::end(self)
685    }
686}