Skip to content

A procedural macro that expands an enum with special `#[other]` variants to handle all possible `u8` values while preserving known variants.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

NetGauze/expand-enum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

expand-enum Procedural Macro

A Rust procedural macro that expands an enum with a special #[other] variant containing a u8 field into a full unit enum with separate variants for all possible u8 values.

Overview

When working with binary protocols or file formats that use byte values as tags, you often need to handle both known values and potentially unknown values. This macro lets you define the known values as normal enum variants while automatically generating variants for all other possible values.

Usage

use expand_enum::expand_enum;

expand_enum! {
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    #[repr(u8)]
    enum Direction {
        North = 1,
        East = 2,
        South = 3,
        West = 4,
        #[other]
        Other(u8),
    }
}

The macro will expand this into a unit enum with:

  • Your explicitly defined variants (North, East, South, West)
  • Additional variants like Other0, Other5, Other6, ... for all other possible u8 values

Generated Methods

The macro also generates helper methods:

  • is_other(&self) -> bool - Returns true if the variant is one of the automatically generated "other" variants
  • as_other_value(&self) -> Option<u8> - Returns the underlying value if this is an "other" variant
  • from_u8(value: u8) -> Self - Creates an enum variant from a raw u8 value

Plus implementations of From<u8> and From<YourEnum> for u8.

Requirements

The enum must:

  • Be marked with #[repr(u8)]
  • Derive both Clone and Copy
  • Have exactly one variant marked with #[other] that contains a single u8 field
  • Specify explicit discriminants for all unit variants

Example

let d = Direction::from_u8(5); // This becomes Direction::Other5
assert!(d.is_other());
assert_eq!(d.as_other_value(), Some(5));

let north = Direction::North;
assert!(!north.is_other());
assert_eq!(north.as_other_value(), None);

// Converts to u8 when needed
let value: u8 = Direction::East.into();
assert_eq!(value, 2);

This macro is particularly useful for protocols or formats where you need to handle a predefined set of known values while preserving the ability to round-trip any arbitrary value.

About

A procedural macro that expands an enum with special `#[other]` variants to handle all possible `u8` values while preserving known variants.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages