Skip to content

Commit 89c9c79

Browse files
committed
Docstrings
1 parent a2e42a5 commit 89c9c79

File tree

2 files changed

+151
-40
lines changed

2 files changed

+151
-40
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "serde-json-fmt"
33
version = "0.1.0"
44
edition = "2021"
55
rust-version = "1.60"
6-
description = "Configurable formatting for serde-json serialization"
6+
description = "Configurable formatting for serde_json serialization"
77
authors = ["John Thorvald Wodder II <serde-json-fmt@varonathe.org>"]
88
repository = "https://github.com/jwodder/serde-json-fmt"
99
license = "MIT"

src/lib.rs

Lines changed: 150 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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;
7979
use std::fmt;
8080
use 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)]
8397
pub struct JsonOptions {
8498
indent: Option<CompactString>,
@@ -88,8 +102,14 @@ pub struct JsonOptions {
88102
}
89103

90104
impl 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

189281
impl 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()`].
362458
pub 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()`].
363465
pub 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)]
366470
pub 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

Comments
 (0)