1- //! Configurable formatting for serde-json serialization
1+ //! Configurable formatting for serde_json serialization
22//!
33//! The `serde-json-fmt` crate lets you create custom [`serde_json`] formatters
44//! with the indentation, separators, and ASCII requirements of your choice.
@@ -79,6 +79,20 @@ use smartstring::alias::CompactString;
7979use std:: fmt;
8080use std:: io:: { self , Write } ;
8181
82+ /// A [`Formatter`][serde_json::ser::Formatter] builder for configuring JSON
83+ /// serialization options.
84+ ///
85+ /// This type is the "entry point" to `serde-json-fmt`'s functionality. To
86+ /// perform custom-formatted JSON serialization, start by creating a
87+ /// `JsonOptions` instance by calling either [`JsonOptions::new()`] or
88+ /// [`JsonOptions::pretty()`], then call the various configuration methods as
89+ /// desired, then either pass your [`serde::Serialize`] value to one of the
90+ /// [`format_to_string()`][JsonOptions::format_to_string],
91+ /// [`format_to_vec()`][JsonOptions::format_to_vec], and
92+ /// [`format_to_writer()`][JsonOptions::format_to_writer] convenience methods
93+ /// or else (for lower-level usage) call [`build()`][JsonOptions::build] or
94+ /// [`as_formatter()`][JsonOptions::as_formatter] to acquire a
95+ /// [`serde_json::ser::Formatter`] instance.
8296#[ derive( Clone , Debug , Eq , Hash , PartialEq ) ]
8397pub struct JsonOptions {
8498 indent : Option < CompactString > ,
@@ -88,8 +102,14 @@ pub struct JsonOptions {
88102}
89103
90104impl JsonOptions {
91- // Uses serde-json's default/"compact" formatting
92- // Note that this format omits spaces from the comma & colon separators
105+ /// Create a new `JsonOptions` instance that starts out configured to use
106+ /// `serde_json`'s "compact" format. Specifically, the instance is
107+ /// configured as follows:
108+ ///
109+ /// - `indent(None)`
110+ /// - `comma(",")`
111+ /// - `colon(":")`
112+ /// - `ascii(false)`
93113 pub fn new ( ) -> Self {
94114 JsonOptions {
95115 indent : None ,
@@ -99,7 +119,14 @@ impl JsonOptions {
99119 }
100120 }
101121
102- // Uses serde-json's "pretty" formatting
122+ /// Create a new `JsonOptions` instance that starts out configured to use
123+ /// `serde_json`'s "pretty" format. Specifically, the instance is
124+ /// configured as follows:
125+ ///
126+ /// - `indent(Some(" "))` (two spaces)
127+ /// - `comma(",")`
128+ /// - `colon(": ")`
129+ /// - `ascii(false)`
103130 pub fn pretty ( ) -> Self {
104131 JsonOptions {
105132 indent : Some ( " " . into ( ) ) ,
@@ -109,56 +136,77 @@ impl JsonOptions {
109136 }
110137 }
111138
139+ /// Set whether non-ASCII characters in strings should be serialized as
140+ /// ASCII using `\uXXXX` escape sequences. If `flag` is `true`, then all
141+ /// non-ASCII characters will be escaped; if `flag` is `false`, then
142+ /// non-ASCII characters will be serialized as themselves.
112143 pub fn ascii ( mut self , flag : bool ) -> Self {
113144 self . ascii = flag;
114145 self
115146 }
116147
117- // Set the comma/list item separator
118- // Errors when given an invalid separator (i.e., one that is not of the
119- // form `/\A\s*,\s*\Z/`)
148+ /// Set the string to use as the item separator in lists & objects.
149+ ///
150+ /// `s` must contain exactly one comma (`,`) character; all other
151+ /// characters must be space characters, tabs, line feeds, and/or carriage
152+ /// returns.
153+ ///
154+ /// # Errors
155+ ///
156+ /// Returns `Err` if `s` does not meet the above requirements.
120157 pub fn comma < S : AsRef < str > > ( mut self , s : S ) -> Result < Self , Error > {
121158 self . comma = validate_string ( s, Some ( ',' ) ) ?;
122159 Ok ( self )
123160 }
124161
125- // Set the colon/key-value separator
126- // Errors when given an invalid separator (i.e., one that is not of the
127- // form `/\A\s*:\s*\Z/`)
162+ /// Set the string to use as the key-value separator in objects.
163+ ///
164+ /// `s` must contain exactly one colon (`:`) character; all other
165+ /// characters must be space characters, tabs, line feeds, and/or carriage
166+ /// returns.
167+ ///
168+ /// # Errors
169+ ///
170+ /// Returns `Err` if `s` does not meet the above requirements.
128171 pub fn colon < S : AsRef < str > > ( mut self , s : S ) -> Result < Self , Error > {
129172 self . colon = validate_string ( s, Some ( ':' ) ) ?;
130173 Ok ( self )
131174 }
132175
133- // Sets the indentation
134- // - `None` means to not insert any newlines, while `Some("")` means to
135- // insert newlines but not indent.
136- // - Problem: passing `None` will require specifying the type of `S`;
137- // users should be advised to use `indent_width()` in this case instead
138- // - Errors if the string is not all JSON whitespace
176+ /// Set the string used for indentation.
177+ ///
178+ /// If `s` is `None`, then no indentation or newlines will be inserted when
179+ /// serializing. If `s` is `Some("")` (an empty string), then newlines
180+ /// will be inserted, but nothing will be indented. If `s` contains any
181+ /// other string, the string must consist entirely of space characters,
182+ /// tabs, line feeds, and/or carriage returns.
183+ ///
184+ /// # Errors
185+ ///
186+ /// Returns `Err` if `s` contains a string that contains any character
187+ /// other than those listed above.
139188 pub fn indent < S : AsRef < str > > ( mut self , s : Option < S > ) -> Result < Self , Error > {
140189 self . indent = s. map ( |s| validate_string ( s, None ) ) . transpose ( ) ?;
141190 Ok ( self )
142191 }
143192
193+ /// Set the string used for indentation to the given number of spaces.
194+ ///
195+ /// This method is a convenience wrapper around
196+ /// [`indent()`][JsonOptions::indent] that calls it with a string
197+ /// consisting of the given number of space characters, or with `None` if
198+ /// `n` is `None`.
144199 pub fn indent_width ( self , n : Option < usize > ) -> Self {
145200 self . indent ( n. map ( |i| CompactString :: from ( " " ) . repeat ( i) ) )
146201 . unwrap ( )
147202 }
148203
149- pub fn build ( self ) -> JsonFormatterOwned {
150- JsonFormatterOwned :: new ( self )
151- }
152-
153- pub fn as_formatter ( & self ) -> JsonFormatter < ' _ > {
154- JsonFormatter :: new ( internal:: JsonOptionsRef {
155- indent : self . indent . as_ref ( ) . map ( |s| s. as_bytes ( ) ) ,
156- comma : self . comma . as_bytes ( ) ,
157- colon : self . colon . as_bytes ( ) ,
158- ascii : self . ascii ,
159- } )
160- }
161-
204+ /// Format a [`serde::Serialize`] value to a [`String`] as JSON using the
205+ /// configured formatting options.
206+ ///
207+ /// # Errors
208+ ///
209+ /// Has the same error conditions as [`serde_json::to_string()`].
162210 pub fn format_to_string < T : ?Sized + Serialize > (
163211 & self ,
164212 value : & T ,
@@ -167,6 +215,27 @@ impl JsonOptions {
167215 . map ( |v| String :: from_utf8 ( v) . unwrap ( ) )
168216 }
169217
218+ /// Format a [`serde::Serialize`] value to a [`Vec<u8>`] as JSON using the
219+ /// configured formatting options.
220+ ///
221+ /// # Errors
222+ ///
223+ /// Has the same error conditions as [`serde_json::to_vec()`].
224+ pub fn format_to_vec < T : ?Sized + Serialize > (
225+ & self ,
226+ value : & T ,
227+ ) -> Result < Vec < u8 > , serde_json:: Error > {
228+ let mut vec = Vec :: with_capacity ( 128 ) ;
229+ self . format_to_writer ( & mut vec, value) ?;
230+ Ok ( vec)
231+ }
232+
233+ /// Write a [`serde::Serialize`] value to a [`std::io::Write`] instance as
234+ /// JSON using the configured formatting options.
235+ ///
236+ /// # Errors
237+ ///
238+ /// Has the same error conditions as [`serde_json::to_writer()`].
170239 pub fn format_to_writer < T : ?Sized + Serialize , W : Write > (
171240 & self ,
172241 writer : W ,
@@ -176,17 +245,41 @@ impl JsonOptions {
176245 value. serialize ( & mut ser)
177246 }
178247
179- pub fn format_to_vec < T : ?Sized + Serialize > (
180- & self ,
181- value : & T ,
182- ) -> Result < Vec < u8 > , serde_json:: Error > {
183- let mut vec = Vec :: with_capacity ( 128 ) ;
184- self . format_to_writer ( & mut vec, value) ?;
185- Ok ( vec)
248+ /// Consume the `JsonOptions` instance and return a
249+ /// [`serde_json::ser::Formatter`] instance.
250+ ///
251+ /// This is a low-level operation. For most use cases, using one of the
252+ /// [`format_to_string()`][JsonOptions::format_to_string],
253+ /// [`format_to_vec()`][JsonOptions::format_to_vec], and
254+ /// [`format_to_writer()`][JsonOptions::format_to_writer] convenience
255+ /// methods is recommended.
256+ pub fn build ( self ) -> JsonFormatterOwned {
257+ JsonFormatterOwned :: new ( self )
258+ }
259+
260+ /// Return a [`serde_json::ser::Formatter`] instance that borrows data from
261+ /// the `JsonOptions` instance.
262+ ///
263+ /// This is a low-level operation. For most use cases, using one of the
264+ /// [`format_to_string()`][JsonOptions::format_to_string],
265+ /// [`format_to_vec()`][JsonOptions::format_to_vec], and
266+ /// [`format_to_writer()`][JsonOptions::format_to_writer] convenience
267+ /// methods is recommended.
268+ ///
269+ /// Unlike [`build()`][JsonOptions::build], this method makes it possible
270+ /// to create multiple `Formatter`s from a single `JsonOptions` instance.
271+ pub fn as_formatter ( & self ) -> JsonFormatter < ' _ > {
272+ JsonFormatter :: new ( internal:: JsonOptionsRef {
273+ indent : self . indent . as_ref ( ) . map ( |s| s. as_bytes ( ) ) ,
274+ comma : self . comma . as_bytes ( ) ,
275+ colon : self . colon . as_bytes ( ) ,
276+ ascii : self . ascii ,
277+ } )
186278 }
187279}
188280
189281impl Default for JsonOptions {
282+ /// Equivalent to [`JsonOptions::new()`]
190283 fn default ( ) -> Self {
191284 JsonOptions :: new ( )
192285 }
@@ -359,16 +452,34 @@ mod internal {
359452 }
360453}
361454
455+ /// A [`serde_json::ser::Formatter`] type that owns its data.
456+ ///
457+ /// Instances of this type are acquired by calling [`JsonOptions::build()`].
362458pub type JsonFormatterOwned = internal:: JsonFormatterBase < JsonOptions > ;
459+
460+ /// A [`serde_json::ser::Formatter`] type that borrows its data from a
461+ /// [`JsonOptions`].
462+ ///
463+ /// Instances of this type are acquired by calling
464+ /// [`JsonOptions::as_formatter()`].
363465pub type JsonFormatter < ' a > = internal:: JsonFormatterBase < internal:: JsonOptionsRef < ' a > > ;
364466
467+ /// Error returned when an invalid string is passed to certain [`JsonOptions`]
468+ /// methods.
365469#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
366470pub enum Error {
367- // a string parameter contained an unexpected character
471+ /// Returned when the given string contains an invalid/unexpected
472+ /// character. Contains the character in question.
368473 InvalidCharacter ( char ) ,
369- // a `comma` or `colon` parameter is missing the comma/colon
474+
475+ /// Retured when a string passed to [`JsonOptions::comma()`] or
476+ /// [`JsonOptions::colon()`] does not contain a comma or colon,
477+ /// respectively. Contains a comma or colon as appropriate.
370478 MissingSeparator ( char ) ,
371- // a `comma` or `colon` parameter has multiple commas/colons
479+
480+ /// Retured when a string passed to [`JsonOptions::comma()`] or
481+ /// [`JsonOptions::colon()`] contains more than one comma or colon,
482+ /// respectively. Contains a comma or colon as appropriate.
372483 MultipleSeparators ( char ) ,
373484}
374485
0 commit comments