#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#[macro_export]
macro_rules! trait_enum {
(
$(#[$outer:meta])*
pub enum $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident,
)+
}
) => {
$crate::__trait_enum! {
$(#[$outer])*
(pub) $EnumName: $Trait {
$(
$(#[$inner])*
$name,
)+
}
}
};
(
$(#[$outer:meta])*
enum $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident,
)+
}
) => {
$crate::__trait_enum! {
$(#[$outer])*
() $EnumName: $Trait {
$(
$(#[$inner])*
$name,
)+
}
}
};
(
$(#[$outer:meta])*
pub enum $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident
),+
}
) => {
$crate::__trait_enum! {
$(#[$outer])*
(pub) $EnumName: $Trait {
$(
$(#[$inner])*
$name,
)+
}
}
};
(
$(#[$outer:meta])*
enum $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident
),+
}
) => {
$crate::__trait_enum! {
$(#[$outer])*
() $EnumName: $Trait {
$(
$(#[$inner])*
$name,
)+
}
}
};
(
$(#[$outer:meta])*
pub ($($vis:tt)+) struct $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident
),+
}
) => {
$crate::__trait_enum! {
$(#[$outer])*
(pub ($($vis)+)) $EnumName: $Trait {
$(
$(#[$inner:meta])*
$name,
)+
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __trait_enum {
(
$(#[$outer:meta])*
($($vis:tt)*) $EnumName:ident: $Trait:tt {
$(
$(#[$inner:meta])*
$name:ident,
)+
}
) => {
$(#[$outer])*
$($vis)* enum $EnumName {
$(
$(#[$inner])*
$name($name),
)*
}
impl $crate::Deref for $EnumName {
type Target = dyn $Trait;
fn deref(&self) -> &(dyn $Trait + 'static) {
match self {
$(
$EnumName::$name(v) => v as &dyn $Trait,
)*
}
}
}
impl $crate::DerefMut for $EnumName {
fn deref_mut(&mut self) -> &mut (dyn $Trait + 'static) {
match self {
$(
$EnumName::$name(v) => v as &mut dyn $Trait,
)*
}
}
}
};
}
#[cfg(not(feature = "std"))]
pub use core::ops::{Deref, DerefMut};
#[cfg(feature = "std")]
pub use std::ops::{Deref, DerefMut};
#[cfg(test)]
pub mod test;