trait_gen

Attribute Macro trait_gen 

Source
#[trait_gen]
Expand description

Generates the attached implementation code for all the types given in argument.

The attribute is placed before the pseudo-generic code to implement. The generic arguments are given first, followed by a right arrow (->) and a list of types that will replace the argument in the generated implementations:

#[trait_gen(T -> Type1, Type2, Type3)]
impl Trait for T {
    // ...
}

The attribute macro successively substitutes the generic argument T in the code with the given types (Type1, Type2, Type3) to generate each implementation.

All the type paths beginning with T in the code have that part replaced. For example, T::default() generates Type1::default(), Type2::default() and so on, but super::T is unchanged. Similarly, all the types including T in the code have that part replaced; for example, &T or Box<T>.

The compiler will trigger an error if the resulting code is wrong. 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 of T replaces any occurrence of ${T} in doc comments, macros, and string literals.

Notes:

  • Using the letter “T” is not mandatory; any type path will do. For example, g::Type is fine too. But to make it easy to read and similar to a generic implementation, short upper-case identifiers are preferred.
  • If a <..> is required in the generic argument, the turbofish syntax must be used. For example, use T::<U> and not T<U>.
  • type_gen is a synonym attribute that can be used instead of trait_gen. This can be disabled with the no_type_gen feature, in case it conflicts with another 3rd-party attribute.

See the crate documentation for more details.

§Example

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