#[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::Type
is 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 chained to generate all the combinations.
trait_gen
can 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)
}
}