num_enum
Type-safe Rust derive macros for converting between primitive integers and enums.
Repository Health
Technical Analysis
num_enum is a Rust crate that provides procedural derive macros to make inter-operation between primitive integers and enums straightforward and type-safe. Instead of relying on error-prone as casts that silently truncate, you derive traits like IntoPrimitive, TryFromPrimitive, FromPrimitive, and UnsafeFromPrimitive to get correct, well-defined conversions in both directions.
Built as a no_std-compatible pair of crates (a runtime crate re-exporting derives from a companion proc-macro crate), num_enum is a staple for FFI boundaries, wire-format parsing, and any code that maps numeric discriminants onto named enum variants. It supports default and catch-all variants, value alternatives, custom error types, and optional complex discriminant expressions.
What You Get
IntoPrimitivederive that implementsFrom<Enum>for the exactreprtype, avoiding the silent truncation ofascastsTryFromPrimitiveandFromPrimitivederives for fallible and exhaustive conversions back from a primitive into an enum- Variant customization via
#[num_enum(default)],#[num_enum(catch_all)], and#[num_enum(alternatives = [..])]attributes no_stdsupport plus optionalcomplex-expressionsand customerror_typeconfiguration
Common Use Cases
- Parsing numeric opcodes, status codes, or protocol discriminants from wire formats into typed enums
- Crossing FFI boundaries where C-style integer constants must map onto Rust enums safely
- Converting typed enums back into their integer representation for serialization or transport
Under The Hood
Architecture - num_enum is split into two crates in a Cargo workspace: a lightweight runtime crate (num_enum/src/lib.rs) that defines the FromPrimitive, TryFromPrimitive, and UnsafeFromPrimitive traits and re-exports the derives, and a companion num_enum_derive proc-macro crate that generates the trait implementations. The derive crate parses the annotated enum into an EnumInfo model (num_enum_derive/src/parsing.rs), resolving repr, variant discriminants, alternatives, catch-all and default markers, then each #[proc_macro_derive] entry point in lib.rs emits the corresponding From/TryFrom implementation via quote!.
Tech Stack - Written in Rust (edition 2021, MSRV 1.70) with the standard proc-macro toolchain: syn 2 for parsing, quote for code generation, and proc-macro2 for spans, plus proc-macro-crate (behind the std feature) to resolve the crate path. The runtime crate depends on rustversion and is no_std compatible when the default std feature is disabled; an optional complex-expressions feature pulls in syn/full for richer discriminant expressions.
Code Quality - The codebase is small and well-factored, splitting attribute parsing, enum/variant attribute handling, and utilities into separate modules. It is thoroughly tested: dedicated integration test files cover each derive (try_from_primitive.rs alone has ~19 tests), and trybuild compile-fail/pass fixtures assert that invalid usages produce the intended compiler errors — a strong signal for a macro crate where diagnostics matter.
API Design - The public surface is deliberately minimal and ergonomic: users add a single #[derive(...)] and a #[repr(..)], and get idiomatic From/TryFrom conversions with no boilerplate. Attribute-driven customization (default, catch_all, alternatives, error_type) is discoverable and consistently namespaced under num_enum(..), and the README documents every derive with runnable examples, making the learning curve gentle.
Used by 2 apps in this directory
Graphite
Code Editors · Design Tools
A free, open source procedural 2D design tool that unifies vector, raster, motion graphics, and generative art in a single node-based nondestructive workflow.
Svix
Developer Tools · Automation
Open source, self-hostable webhook infrastructure that handles delivery, retries, HMAC signing, and multi-tenant event management so you never have to build a webhooks system from scratch.