The predfined macros

For frequently used traits in std, this library provides macros such as impl_trait!() to implement these traits without the need of writing trait methods.

Syntax of impl_trait!{}

The full form is


#![allow(unused)]
fn main() {
impl_trait! {
    _impl!( Generics ) Path::Of::Trait _for!( Type ) _where!( Clause )
}
}

Generics and Clause are optional:


#![allow(unused)]
fn main() {
impl_trait!{ _impl!() Path::Of::Trait _for!( Type ) _where!() }
}

and the wrapped macros can be omitted:


#![allow(unused)]
fn main() {
impl_trait!{ Path::Of::Trait _for!( Type )}
}

Supported forms of types in _for!()

The _for!() macro supports two forms of types.

One is ad-hoc enums:


#![allow(unused)]
fn main() {
impl_trait!{ Path::Of::Trait _for!( Enum![1..=16] )}
}

The other is the enum type definition copied in _def!() macro:


#![allow(unused)]
fn main() {
impl_trait!{ Path::Of::Trait _for!( _def!(
    enum Value {
        Bin( Vec<u8> ),
        Text( String ),
    }
))}
}

Note: _def!() does not define any enum, so Value should have been defined elsewhere.

The _where!() macro

You can write any where clause in this macro.

Note: you do not need write _where!( _Variants!(): Path::Of::Trait ) which the impl_trait!{} macro will generate it silently.

Traits in std prelude

AsRef

AsMut

DoubleEndedIterator

ExactSizeIterator

Extend

Fn

Iterator

The example of implementing Iterator:


#![allow(unused)]
fn main() {
impl_trait!{ Iterator _for!( Type )}
}

The example of implementing Fn:


#![allow(unused)]
fn main() {
impl_trait!{ _impl!(Args) Fn<Args> _for!( Type )}
}

Traits with full path

std::error::Error

std::fmt::Debug

std::fmt::Display

std::iter::FusedIterator

std::iter::TrustedLen

std::io::BufRead

std::io::Read

std::io::Seek

std::io::Write

std::ops::Deref

std::ops::DerefMut

std::ops::Generator

std::ops::Index

std::ops::IndexMut

std::ops::RangeBounds

The example of implementing std::ops::Generator:


#![allow(unused)]
fn main() {
impl_trait!{ _impl!(R) std::ops::Generator<R> _for!( Type )}
}

Unstable traits

To implement these traits, the crate feature "unstable" should be opted in.

Fn

std::iter::TrustedLen

std::ops::Generator

impl_super_traits!{} and impl_all_traits!{}

The syntax of these two traits are similar with impl_trait!{}.

The impl_super_traits!{} macro helps to implement the super trait(s) of the mentioned trait, e.g. impl_super_traits!{ _impl!(Args) Fn<Args> _for!( Type )} will implement FnMut and FnOnce for Type, but NOT Fn.

The impl_all_traits!{} macro does what impl_trait!{} and impl_super_traits!{} does, e.g. impl_all_traits!{ _impl!(Args) Fn<Args> _for!( Type )} will implement Fn, FnMut and FnOnce for Type.

macro inheritance

If the library users want to support extra traits, they can write the extra implementations in their macro, and delegate other traits to enumx::impl_trait!().


#![allow(unused)]
fn main() {
use enumx::export::{def_impls, impl_all_traits};

macro_rules! impl_trait {
    ($(_impl!($($gen:tt),*))* ExtraTrait<$t:ident> _for!($($ty:tt)+) $(_where!($($pred:tt)*))*) => {
        // omitted
    };
    ($($tt:tt)+) => {
        enumx::impl_trait!{ $($tt)+ }
    };
}


macro_rules! impl_super_traits {
    ($(_impl!($($gen:tt),*))* ExtraTrait<$t:ident> _for!($($ty:tt)+) $(_where!($($pred:tt)*))*) => {
        // omitted
    };
    ($($tt:tt)+) => {
        enumx::impl_super_traits!{ $($tt)+ }
    };
}
}