icydb-model-macros 0.220.0

Procedural macros for IcyDB application models
Documentation

IcyDB Model Macros

Procedural-macro compiler for icydb-model declarations and application helper derives.

Applications normally consume these macros through icydb-model. The compiler lowers declarations into that package's host graph and the public icydb-schema proposal vocabulary; it has no dependency on icydb or icydb-core.

Durable Rule Grammar

A ty(...) declaration may contain multiple uniquely named durable rules. Each rule(...) requires exactly one of these typed operations:

rule(name = "length", length_range_inclusive(min = 1, max = 40))
rule(name = "minimum", numeric_minimum_inclusive(value = 0))
rule(name = "maximum", numeric_maximum_inclusive(value = 100))
rule(name = "range", numeric_range_inclusive(min = 0, max = 100))
rule(name = "step", multiple_of(divisor = 5))

length_range_inclusive takes nonnegative u64 bounds and requires min <= max. Numeric operands are exact literals admitted later against the declared target kind. multiple_of accepts only a nonzero exact integer or fixed-scale decimal divisor; it has no floating-point form. Target-kind incompatibility rejects during model-to-proposal lowering.

The grammar rejects missing or multiple operations, unknown operation or operand names, missing or repeated operands, duplicate rule names, reversed ranges, zero divisors, and invalid rule names. The retired string kind and positional rule args(...) fields are not accepted. Positional args(...) remain available only where explicitly documented for application normalizer and validator constructors; those callbacks are not durable rules.

Changing an operation or operand while retaining the local rule name keeps the catalog identity and uses normal accepted-constraint evolution. Changing the rule name is an explicit removal plus addition.

Application Behavior

Generated types implement the required traversal traits automatically. Application code invokes icydb_model::normalize, icydb_model::validate, or the consuming NormalizeAndValidate::normalize_and_validate method explicitly. Generated persistence adapters and database writes do not call normalizers or validators.

Generated Rust Ergonomics

traits(add(...), remove(...)) selects supported Rust trait implementations; it is not a free-form list. Required traits are compiler-owned, while removal remains available for supported generated implementations that applications need to replace manually. The compiler resolves the complete node and shape baseline before applying either directive and rejects any selected trait that has no derive or generated implementation strategy.

From is generated only for newtype and collection wrappers. NormalizeCustom and ValidateCustom are generated for every application value and may be removed for a manual implementation. Inner is newtype-only. NumericValue is generated or explicitly opt-in only for newtypes.

Collection wrappers generate Default, Deref, DerefMut, FromIterator, and IntoIterator; other application values opt into Default, while only newtypes may opt into dereference and display. Copy, Hash, Ord, and PartialOrd are available as standard derives when the node shape does not already generate them. Arithmetic, assignment, Sum, Product, and signed Neg helpers are newtype-only and follow the wrapped primitive capability baseline. Finite floats do not generate Neg, because negating canonical positive zero would recreate negative zero.

Enum declaration-order checking is an enum option rather than a trait:

#[enum_(
    sorted,
    variant(name = "First"),
    variant(name = "Second")
)]
pub struct Ordered {}

Generated list, set, and map wrappers implement Deref and DerefMut to their standard containers. Methods such as iter, len, and is_empty are therefore available directly without an IcyDB-specific collection trait. They also support standard owned and shared-reference iteration and exact FromIterator collection. Lists and maps support mutable-reference iteration; sets preserve the standard BTreeSet rule that elements cannot be mutated in place. Either iterator protocol may be removed when an application supplies a manual implementation.

References:

  • Workspace overview: ../../README.md
  • Release notes: ../../CHANGELOG.md