ddd-toolkit-macro
Derive macros for ddd-toolkit-core's
value-object-shaped traits: ValueObject, EntityId, SecretVo, and
EnumVo. Works alongside ddd-toolkit-core directly, or through the
ddd-toolkit facade - the
generated code resolves the right crate path either way.
If you'd rather implement these traits by hand with zero macro machinery,
reach for ddd-toolkit-core directly instead. Reach for this crate when you
want to #[derive(...)] the boilerplate away.
Installation
Or add it to Cargo.toml directly:
[]
= "0.2"
Enable the zeroize feature if you use #[vo(zeroize)] on a SecretVo:
[]
= { = "0.2", = ["zeroize"] }
= "1"
Requires Rust 1.85 or newer (edition 2024). You'll also need
ddd-toolkit-core (or the ddd-toolkit facade) as a dependency of your own
crate - the derives generate code that references it, but don't pull it in
for you.
Derives
All four support tuple structs with exactly one field (struct Email(String););
the field must not be pub (a public field would let callers bypass
validation by constructing the type directly).
ValueObject- generatesWrapped/WrappedInner,TryFrom<Inner>,From<Self> for Inner, andDisplay.EntityId- everythingValueObjectgenerates, plusEq,Hash,Ord, andPartialOrd.SecretVo- generatesSecretVo,TryFrom<Inner>, and aDebugimpl that always printsTypeName(***), never the wrapped value.EnumVo- for fieldless enums; generatesEnumVo::variants(),Display, andFromStr, all derived from the same variant list so they can't drift out of sync.
Attributes
All via #[vo(...)]:
| Attribute | Applies to | Effect |
|---|---|---|
validate = "path::to::fn" |
ValueObject, EntityId, SecretVo |
Runs fn(&Inner) -> Result<(), ValidationError> before construction |
no_display |
ValueObject, EntityId, EnumVo |
Skips generating Display (write your own) |
rename_all = "snake_case" (etc.) |
EnumVo |
Renames variants for Display/FromStr |
zeroize |
SecretVo |
Generates a Drop impl that zeroizes the inner value; requires this crate's zeroize feature and your own crate depending on the zeroize crate directly |
Example
use ;
use ValueObject;
;
EntityId generates the same Wrapped/TryFrom/Display impls as
ValueObject, plus Eq/Hash/Ord/PartialOrd (derived from the inner
value) so the id can be used as a map key or sorted - don't derive those
four yourself, or you'll get conflicting impls:
use Entity;
use EntityId;
;
More usage, including SecretVo and EnumVo, is covered in the
API docs.
Changelog
See CHANGELOG.md for release history.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.