defaulted
Trait and derive macro for testing whether a value equals its default state, with per-field customization and optional serde integration.
Overview
Rust's standard [Default] trait constructs default values, but it says nothing
about whether an existing value is still at its default state.
This crate fills that gap with a single-method trait:
The crate also provides:
- Built-in impls for all primitive types,
String,Option,Vec,HashMap,HashSet, etc. - A derive macro
#[derive(Defaulted)](behindderivefeature) to generate the impl automatically for a user-defined struct or enum. - An attribute macro
#[skip_serializing_defaults](behindderiveandserdefeatures) making serde skip serialization for fields that are in their default state.
Usage
Add the crate to Cargo.toml:
[]
= { = "0.1", = ["derive"] }
Enable serde support with:
[]
= { = "0.1", = ["derive", "serde"] }
Basic derive
use Defaulted;
let c = default;
assert!;
let c2 = Config ;
assert!;
Per-field customization
Each field can opt into one of several checker strategies via
#[defaulted(...)]:
| Attribute | Meaning |
|---|---|
| (none) | Delegate to the field type's Defaulted impl |
#[defaulted(default = expr)] |
Field is "default" when it equals expr |
#[defaulted(with = func)] |
Call func(&field) -- true means "default" |
#[defaulted(with = |v| ...)] |
Inline closure |
#[defaulted(ignore)] |
Always treat this field as default (skip it) |
use Defaulted;
Enums
Mark exactly one variant with #[defaulted(default)]:
use Defaulted;
assert!;
assert!;
Enum variants with fields follow the same per-field rules as structs.
Generating Default from field defaults
#[defaulted(Default)] on a struct generates a Default impl whose
field values match the #[defaulted(default = expr)] annotations, so the two
stay in sync automatically:
use Defaulted;
let s = default;
assert_eq!;
assert_eq!;
assert!;
Serde integration
#[skip_serializing_defaults] rewrites a struct's fields to add
#[serde(skip_serializing_if = "...")] (and #[serde(default = "...")] for
EqualsValue fields) automatically, so default-valued fields are omitted from
serialized output and restored correctly on deserialization.
use Defaulted;
use ;
// must go before #[derive(Serialize)]
let c = default;
let json = to_string.unwrap;
assert_eq!; // all fields at default -- nothing serialized
Feature flags
| Flag | Default | Description |
|---|---|---|
std |
yes | Enables impls for HashMap, Mutex, Path, etc. Implies alloc. |
alloc |
yes (via std) |
Enables impls for String, Vec, Box, Arc, Cow, etc. |
derive |
no | Enables #[derive(Defaulted)] |
serde |
no | Enables #[skip_serializing_defaults] attribute macro |
serde-json |
no | Enables impls for serde_json::Value and serde_json::Map |
serde-yaml |
no | Enables impls for serde_yaml::Value and serde_yaml::Mapping |
bytes |
no | Enables impls for Bytes and BytesMut |
indexmap |
no | Enables impls for IndexMap and IndexSet |
smallvec |
no | Enables impls for SmallVec |
no_std support
Disable default features and optionally enable alloc:
[]
= { = "0.1", = false } # core only
= { = "0.1", = false, = ["alloc"] } # core + alloc
License
MIT