#pattern-matching #group #macro #enums

enum-group-macros

Define grouped enums with ergonomic pattern matching

1 unstable release

0.1.0 Jan 11, 2026

#1604 in Rust patterns

MIT license

11KB

enum-group-macros

Define grouped enums with ergonomic pattern matching in Rust.

Usage

Add this to your Cargo.toml:

[dependencies]
enum-group-macros = { git = "https://github.com/xuchaoqian/enum-group-macros.git" }

License

This project is licensed under the MIT License - see the LICENSE file for details.


lib.rs:

enum-group-macros

Define grouped enums with ergonomic pattern matching.

This crate allows you to define a "wire" enum with variants organized into logical groups, and provides macros for matching on those groups without boilerplate.

Example

use enum_group_macros::{define_enum_group, match_enum_group, EnumGroup};
use serde::{Deserialize, Serialize};

// Define message types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MsgA { pub value: i32 }

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MsgB { pub text: String }

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MsgC { pub flag: bool }

// Define grouped enum
define_enum_group! {
    #[derive(Debug, Clone, Serialize, Deserialize)]
    #[serde(tag = "type", content = "payload")]
    pub enum WireMsg {
        Protocol {
            A(MsgA),
            B(MsgB),
        },
        Business {
            C(MsgC),
        }
    }
}

// This generates:
// - enum Protocol { A(MsgA), B(MsgB) }
// - enum Business { C(MsgC) }
// - enum WireMsg { A(MsgA), B(MsgB), C(MsgC) }
// - enum WireMsgGroup { Protocol(Protocol), Business(Business) }
// - impl EnumGroup for WireMsg

fn handle_message(msg: WireMsg) {
    match_enum_group!(msg, WireMsg, {
        Protocol(p) => {
            println!("Protocol message: {:?}", p);
        },
        Business(b) => {
            println!("Business message: {:?}", b);
        },
    })
}

Features

  • Zero runtime overhead: All grouping is compile-time
  • Async-friendly: Works seamlessly with async/await
  • Serde compatible: Attributes like #[serde(...)] are propagated
  • IDE support: Full autocomplete and type checking

How It Works

The define_enum_group! macro generates:

  1. Group enums: One enum per group (e.g., Protocol, Business)
  2. Wire enum: A flat enum with all variants for serialization
  3. Group dispatch enum: An enum wrapping group enums (e.g., WireMsgGroup)
  4. EnumGroup impl: Conversion from wire enum to grouped representation

The match_enum_group! macro expands to a match on the grouped representation, using the EnumGroup trait to access the Group type without explicit imports.

Dependencies

~130–520KB
~12K SLoC