Skip to main content

Module options

Module options 

Source
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§

AllowComments
JSONC: // and /* */ comments accepted wherever whitespace is.
Pretty
Indented JSON, two spaces per level.
PrettyInlineArrays
Indented JSON, with each array kept on one line.
RequireKeys
Every declared field required to be present, and every unknown key still refused.
SkipNull
Compact, with null members left out.
SkipUnknown
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.