pud
pud is a procedural macro and trait system for generating typed, composable, no-std-friendly modifications (“puds”) for Rust structs.
Core Concepts
[Pud]
A pud is a single atomic modification that can be applied to a target value.
A pud consumes itself and mutates its Target in place.
[Pudded]
Any sized type can receive puds (blanket implementation).
[IntoPud] / [TryIntoPud]
IntoPud (and its fallible equivalent TryIntoPud) allows external code to produce a modification without depending on the concrete {StructName}Pud enum generated by #[pud].
This is useful for update producers such as commands, events, or protocol messages, which should be able to request changes to a struct without knowing the name, visibility, or exact shape of its Pud enum.
TryIntoPud is the fallible variant and is automatically implemented for all IntoPud types using Infallible as the error.
The #[pud] macro
The #[pud] attribute is applied to a struct and generates:
-
A Pud enum named
{StructName}Pud(by default) -
An implementation of
Pud<Target = StructName>for that enum -
Optional visibility, attributes, and renaming control
Note: The generated code is fully #![no_std] compatible and doesn't depend on alloc.
Basic Example
Generates:
Struct-Level Settings
Struct-level settings are provided inside the #[pud(...)] attribute.
| Setting | Description |
|---|---|
vis = <visibility> |
Visibility of the generated Pud enum |
rename = <Ident> |
Rename the generated Pud enum |
attrs(...) |
Attributes applied to the generated Pud enum |
Field-Level Settings
Field settings control how individual fields participate in the Pud enum and how updates are applied.
Settings may be comma-separated or split across multiple #[pud(...)] attributes.
rename = Ident
Renames the generated Pud variant.
foo: u8,
Generates
FOO // instead of FooPud::foo(u8)
map(Type >>= expr)
Allows you to use a mapper instead of the field type, mapper can be a function path or a closure expression (Fn(Type) -> field_type)
toto: u16,
Generates:
target.toto = u8_to_u16;
flatten = Type
Delegates modification to another Pud type (a glorified map(InnerPud >>= Pud::apply)).
titi: u8,
group = Ident
Groups multiple fields into a single multi-field Pud variant.
foo: u8,
bar: u8,
baz: u8,
Generates:
FooBarBaz // and appropriate application
Note: Groups do not remove the individual field variants; both coexist.
Full Example
Generates:
pub
Design Philosophy
pud is minimal and explicit: a pud describes what to update, not whether or how to update it.
Producing a modification is a deliberate act—if a value should not change, ideally, no pud should be emitted.
The crate avoids side effects, hidden control flow, or mutable access outside of apply; mapping is pure, and application is mechanical and predictable.
Conditional or state-dependent updates are outside the core design, but may be added later via optional, feature-gated extensions without affecting the current guarantees.
Supported Types and Constraints
Only structs are supported.
Named and tuple structs are allowed; tuple struct fields must be explicitly renamed.