1 unstable release
0.1.0 | Apr 12, 2024 |
---|
#708 in Procedural macros
27KB
637 lines
denumic
denumic
macro is to create enum-based runtime dispatched traits.
When applied to a trait
, it exports the definition of the trait that would be passed to other denumic
attributes on enum
s.
When applied to an enum
, it generates a macro that can be used to dispatch to the appropriate implementation of the trait for each variant of the enum
.
From
and TryFrom
are also automatically implemented for the enum
, as long as it does not break coherence rules, so that it can be converted to and from the variants.
Example
use denumic::denumic;
// Generic parameters of the trait and the enum could be finly merged matching by names.
#[denumic]
pub trait Trait {
const MY_CONST: i32;
type MyType;
fn foo(self) -> i32;
}
// Note that the identifiers `used` before the trait definition also have to be `use`d before the enum definition.
#[denumic(Trait)]
// Associated types and consts can be specified using attributes:
#[MY_CONST = 1]
// As for types that are not a valid `expr`, quote them instead of raw types:
#[MyType = "&'static str"]
pub enum Impl<Other = ()>
where
Other: Trait,
{
// `From` and `TryFrom` are only generated if the enum has only a single field.
A(A),
// If multiple fields are found, the one with `#[denumic]` otherwise the first one is dispatched.
Other(Other, String),
}
pub struct A;
impl Trait for A {
const MY_CONST: i32 = 2;
type MyType = ();
fn foo(self) -> i32 {
10
}
}
impl Trait for () {
const MY_CONST: i32 = 0;
type MyType = String;
fn foo(self) -> i32 {
20
}
}
fn call_foo(v: A) -> i32 {
let v: Impl = v.into();
v.foo()
}
Dependencies
~240–690KB
~16K SLoC