#[trait_gen]Expand description
Generates the attached trait implementation for all the types given in argument.
The attribute is placed before the pseudo-generic implementation code. The generic argument
is given first, followed by a right arrow (->) and a list of type arguments.
#[trait_gen(T -> Type1, Type2, Type3)]
impl Trait for T {
// ...
}The attribute macro successively substitutes the generic argument T in the code with
the following types (Type1, Type2, Type3) to generate all the implementations.
All the type paths beginning with T
in the code have this part replaced. For example, T::default() generates Type1::default(),
Type2::default(), and so on, but super::T is unchanged because it belongs to another scope.
The code must be compatible with all the types, or the compiler will trigger the relevant
errors. For example, #[trait_gen(T -> u64, f64)] cannot be applied to let x: T = 0;, because 0
is not a valid floating-point literal.
Finally, the actual type replaces any ${T} occurrence in doc comments, macros and string literals.
Notes:
- Using the letter “T” is not mandatory; any type path will do. For example,
gen::Typeis fine too. But to make it easy to read and similar to a generic implementation, short upper-case identifiers are preferred. - Two or more attributes can be written in front of the implementation code to generate the cross-product of their arguments.
trait_gencan be used on type implementations too.
Examples
#[trait_gen(T -> u8, u16, u32, u64, u128)]
impl MyLog for T {
/// Logarithm base 2 for `${T}`
fn my_log2(self) -> u32 {
T::BITS - 1 - self.leading_zeros()
}
}
#[trait_gen(T -> u8, u16, u32, u64, u128)]
#[trait_gen(U -> &T, &mut T, Box<T>)]
impl MyLog for U {
/// Logarithm base 2 for `${U}`
fn my_log2(self) -> u32 {
MyLog::my_log2(*self)
}
}