# Changelog
All notable changes to `rapira` and `rapira-derive` are documented here.
## rapira-derive 0.14.0 — `rapira` 0.13.6
### Changed (behavioral — peer reads only)
- **`#[rapira(peer)]` missing-field handling is now Option-aware and `Default`-free** (G5).
When the peer schema omits a field/position the local type has:
- an `Option<T>` field resolves to `None`;
- any other (required) field resolves to `Err(RapiraError::SchemaMismatch)`.
Previously a missing field was filled with `Default::default()`, which imposed a viral
`Default` bound across the whole wire-type graph. That bound is **removed** — non-`Default`
types (e.g. `NonZeroU32`) are now valid `#[rapira(peer)]` fields.
Applies uniformly to named structs, tuple structs, and unnamed-multi / named enum variant
payloads. `Option` detection is syntactic (`Option` / `core::option::Option` /
`std::option::Option`); type aliases and `OptFuid`/`OptId64` are treated as required.
`#[rapira(with = …)]` fields are always required.
This is a behavioral break **only** for code on the peer path that relied on a missing
*required* field defaulting; it is gated by the `schema` feature. Non-peer codecs are
unaffected. The new codegen needs no new runtime API, so `rapira` itself is a patch
(`0.13.6`) carrying the bumped `rapira-derive = "0.14.0"` dependency, new tests, and this
changelog.
### Added
- **`#[rapira(peer_default)]`** — opt-in, per-field missing-field fill. On a `#[rapira(peer)]`
type, an absent peer field marked `peer_default` resolves to `Default::default()` instead of
`SchemaMismatch` (proto3-style "missing → zero"). The `Default` bound is scoped to the marked
field; un-annotated fields are unchanged. Works on structs, tuples, and enum variant payloads.
Compile error on an `Option<T>` field, a `#[rapira(skip)]` field, or a single-field enum
variant. Resolves libfunc/armour#65.
### Notes
- `#[rapira(peer_optional)]` and `#[rapira(peer_exact)]` (also floated in #65) were **not**
added: `peer_default` subsumes `peer_optional` for `OptFuid`/`OptId64`-style types, and
`#[rapira(with = …)]` already provides the exact/foreign-leaf read of `peer_exact`.
- A separate pre-existing gap — enum variant payloads ignore `#[rapira(with = …)]` on the peer
read path — is tracked in libfunc/armour#68 (no current consumer).
- Another pre-existing G5 limitation: a tuple enum variant cannot grow from single-field to
multi-field on the peer path (`derive(GetType)` emits a single-field variant's payload as a bare
scalar, which the multi-field reader rejects before any finalizer). So `peer_default` (and
`Option<T>` → `None`) on a tuple variant applies only when it was already multi-field; use named
variants to keep a one-field variant growable. Tracked in libfunc/armour#70.