Attribute Macro trait_gen

Source
#[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)
    }
}