nestum
nestum is a proc-macro that makes nested enum paths feel natural, so you can write:
VariantA
instead of:
Variant1
It does this by generating a shadow module hierarchy and wrapper constructors around your enums.
Why
Rust enums are great for modeling state and variants, but nested enum patterns quickly get noisy when you need multiple levels:
Variant1
nestum removes the visual clutter by letting you access nested variants via paths:
VariantA
You still get the same enum types and matching semantics—you just get cleaner call sites.
Quick Start
use nestum;
Concepts
Shadow module
When #[nestum] is applied to an enum, the macro replaces it with a module of the same name.
Inside that module, it re-emits the original enum and creates submodules for nested variants.
Those submodules expose wrapper constructors that build the outer enum.
This means the enum type itself is accessed as EnumName::EnumName.
Nested variant detection
A variant is treated as nested if and only if:
- it is a tuple variant with exactly one field, and
- the inner field’s type is a simple enum ident that is also marked with
#[nestum]in the same module.
This keeps nesting explicit without requiring per-variant annotations.
Cross-module nesting
To nest an enum declared in a different module file, use an external path on the variant:
use nestum;
This resolves crate::inner::Inner to src/inner.rs or src/inner/mod.rs and generates wrappers.
API Summary
#[nestum] on enums
Enables shadow-module generation and wrapper constructors.
#[nestum(external = "path::to::Enum")] on variants
Opt-in support for nesting an enum in another module file.
nestum_match! { match value { ... } } / nested! { match value { ... } }
Macro that rewrites nested patterns (like Enum1::Variant1::VariantA) into real enum patterns.
Examples
Basic nesting
let _ = A;
let _ = B;
Cross-module nesting
let _ = A;
Nested match patterns
use ;
let value = A;
nested!
Limitations
- External crates are not supported (proc macros can’t reliably inspect other crates’ ASTs).
- The macro only resolves enums from source files in the current crate.
#[path = "..."],include!(), and complexcfglayouts may not be resolved.
Error Messages
nestum emits detailed compile-time errors, including:
- invalid
#[nestum(...)]usage, - misuse on variants,
- external path mismatches,
- missing module files or enums.
FAQ
Why does the enum type become EnumName::EnumName?
Because nestum replaces the enum with a module of the same name. The original enum is re-emitted inside it.
How do I pattern match with nested paths?
Use nested! (or nestum_match!) so paths like Enum1::Variant1::VariantA are rewritten to the real enum pattern.
Why not support external crates?
The macro would need to discover and parse dependency source files, which is brittle and not reliably possible in stable proc-macro APIs.
License
MIT