metamatch 0.2.3

A proc-macro for generating repetitive match arms.
Documentation

metamatch!

githubgithub-buildcrates-iomsrvdocs-rs

A rust proc-macro for generating repetitive match arms.

Match arms for enum variants of different types cannot be combined, even if the match arm bodies are syntactically identical.

This macro implements a simple templating attribute (#[expand]) to automatically stamp out the neccessary copies.

Due to limitations on attributes in stable rust, a functional macro (metamatch!) is currently required around the full match expression. Rustfmt and rust-analyzer are fully able to reason about the macro. Even auto refactorings affecting the #[expand], like changing the name of an enum variant, work correctly.

Example

use metamatch::metamatch;

enum Number {
    I32(i32),
    I64(i64),
    U32(u32),
    U64(u64),
    F32(f32),
    F64(f64),
}

impl Number {
    fn as_i32(&self) -> Option<i32> {
        metamatch!(match self {
            Self::I32(v) => Some(*v),

            #[expand(T in [I64, U32, U64])]
            Self::T(v) => (*v).try_into().ok(),

            // multiple expands in the same match possible
            #[expand(T in [F32, F64])]
            Self::T(v) => Some(*v as i32)
        })
    }
    fn promote_to_64(&mut self) {
        metamatch!(match self {
            // multiple replacement expressions supported
            #[expand((SRC, TGT, TYPE) in [
                (I32, I64, i64),
                (U32, U64, u64),
                (F32, F64, f64),
            ])]
            Self::SRC(v) => {
                *self = Self::TGT(*v as TYPE)
            }

            // no #[expand] needed, types are unused
            Self::I64(_) | Self::U64(_) | Self::F64(_) => (),
        })
    }
}

License

MIT