serde_saphyr/
serializer_options.rs

1//! Serializer options for YAML emission.
2//!
3//! Controls indentation and optional anchor name generation for the serializer.
4//!
5//! Example: use 4-space indentation and a custom anchor naming scheme.
6//!
7//! ```rust
8//! use serde::Serialize;
9//!
10//! #[derive(Serialize)]
11//! struct Item { a: i32, b: bool }
12//!
13//! let mut buf = String::new();
14//! let opts = serde_saphyr::SerializerOptions {
15//!     indent_step: 4,
16//!     anchor_generator: Some(|id| format!("id{}/", id)),
17//!     ..Default::default()
18//! };
19//! serde_saphyr::to_fmt_writer_with_options(&mut buf, &Item { a: 1, b: true }, opts).unwrap();
20//! assert!(buf.contains("a: 1"));
21//! ```
22
23use crate::ser_error::Error;
24
25#[derive(Clone, Copy)]
26pub struct SerializerOptions {
27    /// If true, empty maps are emitted as braces {} and empty lists as []  (this is the default). 
28    /// Such form is equally valid YAML, allows to tell empty from null and may be easier for a 
29    /// human to grasp.
30    pub empty_as_braces: bool,
31    /// Number of spaces to indent per nesting level when emitting block-style collections.
32    /// 0 value is invalid and will result and error when trying to deserialize, because
33    /// no indentation would produce invalid YAML otherwise.
34    pub indent_step: usize,
35    /// Optional custom anchor-name generator.
36    ///
37    /// Receives a monotonically increasing `usize` id (starting at 1) and returns the
38    /// anchor name to emit. If `None`, the built-in generator yields names like `a1`, `a2`, ...
39    pub anchor_generator: Option<fn(usize) -> String>,
40    /// Threshold for block-string wrappers ([crate::LitStr]/[crate::FoldStr] and owned variants
41    /// [crate::LitString]/[crate::FoldString]).
42    ///
43    /// If the string contains a newline, block style is always used. Otherwise, when the
44    /// string is single-line and its length is strictly less than this threshold, the
45    /// serializer emits a normal YAML scalar (no block style). Longer strings use block
46    /// styles `|` or `>` depending on the wrapper. See the type docs for
47    /// [crate::LitStr], [crate::FoldStr], [crate::LitString] and [crate::FoldString] for
48    /// examples.
49    pub min_fold_chars: usize,
50    /// Maximum width (in characters) for lines in folded block scalars (`>`).
51    ///
52    /// Lines are wrapped at whitespace so that each emitted line is at most this many
53    /// characters long (excluding indentation). If no whitespace is present within the
54    /// limit, a hard break is performed.
55    pub folded_wrap_chars: usize,
56    /// When enabled, serialize simple enums that become a single scalar (unit variants)
57    /// using YAML tags, e.g. `!!Enum Variant` instead of a plain scalar `Variant`.
58    /// Deserializer does not need this setting as both cases will be understood.
59    pub tagged_enums: bool,
60
61    /// When enabled, strings containing more than folded_wrap_chars (80 by default) are written
62    /// in wrapped multistring folded form (>), and strings containing new lines are written in
63    /// literal form (|), selecting format depending on the number of empty lines at the end.
64    pub prefer_block_scalars: bool,
65}
66
67// Below this length, block-string wrappers serialize as regular scalars
68// instead of YAML block styles. This keeps short values compact.
69pub(crate) const MIN_FOLD_CHARS: usize = 32;
70/// Maximum width (in characters) for lines inside folded block scalars.
71/// Lines will be wrapped at whitespace so that each emitted line is at most
72/// this many characters long (excluding indentation). If no whitespace is
73/// available within the limit, a hard break is performed.
74pub(crate) const FOLDED_WRAP_CHARS: usize = 80;
75
76impl SerializerOptions {
77    pub(crate) fn consistent(&self) -> Result<(), Error> {
78        if self.indent_step == 0 {
79            return Err(Error::InvalidOptions("Invalid indent step must be positive".to_string()));
80        }
81        Ok(())
82    }
83}
84
85impl Default for SerializerOptions {
86    fn default() -> Self {
87        // Defaults mirror internal constants used by the serializer.
88        Self {
89            indent_step: 2,
90            anchor_generator: None,
91            min_fold_chars: MIN_FOLD_CHARS,
92            folded_wrap_chars: FOLDED_WRAP_CHARS,
93            tagged_enums: false,
94            empty_as_braces: true,
95            prefer_block_scalars: true
96        }
97    }
98}