Expand description
Compile-time options, for reading and for writing.
Options are a type, not a value. Options carries one associated
constant per setting, a policy type implements it, and the parsers and
writers are generic over that type. Every setting is therefore a const
inside the code that consults it, so the branch folds away before the
optimizer ever sees it and the unselected behaviour costs no code at all.
This is the shape Glaze’s glz::opts has, arrived at differently. Rust has
no const generic parameter of struct type on stable, so write<opts{...}>
has no direct translation; a trait with defaulted associated constants
gets the same zero-cost dispatch, and gets a place to document each
setting besides.
use structio::{Pretty, to_string, to_string_with};
let p = P { x: 1 };
assert_eq!(to_string(&p), "{\"x\":1}");
assert_eq!(to_string_with::<Pretty, _>(&p), "{\n \"x\": 1\n}");§Writing your own
The built-in policies below are the common cases. Any combination is a unit struct and an impl that overrides the constants it cares about; everything left out keeps its default, so a policy written today keeps compiling when a later release adds a setting.
use structio::Options;
/// Indented four spaces, with absent members left out, and tolerant of a
/// document written against a newer version of the schema.
#[derive(Clone, Copy)]
pub struct Config;
impl Options for Config {
const PRETTY: bool = true;
const INDENT: usize = 4;
const SKIP_NULL: bool = true;
const ERROR_ON_UNKNOWN_KEYS: bool = false;
}§What it costs
Code size, in exchange for speed: the read and write paths are compiled once per policy a program actually uses. One policy costs exactly what no policy parameter cost before it.
§Reading and writing
One trait covers both directions, so a policy names everything a program
does with a document rather than making you carry two. A setting that
belongs to one direction is simply ignored by the other:
PRETTY means nothing to a parser, and
ERROR_ON_UNKNOWN_KEYS means nothing to
a writer. Every writing entry point has a _with twin and so does every
reading one; json::Documents and
json::Feed take theirs from with_options, one more
link in the builder chain they already have.
Structs§
- Allow
Comments - JSONC:
//and/* */comments accepted wherever whitespace is. - Pretty
- Indented JSON, two spaces per level.
- Pretty
Inline Arrays - Indented JSON, with each array kept on one line.
- Require
Keys - Every declared field required to be present, and every unknown key still refused.
- Skip
Null - Compact, with null members left out.
- Skip
Unknown - Unknown keys stepped over rather than refused.
- Standard
- Compact JSON, every declared member written, every unknown key refused.
Traits§
- Options
- How a value is read and written.