Macro portrait::delegate

source ·
delegate!() { /* proc-macro */ }
Expand description

Impl filler: Generates an implementation that delegates to another implementation of the same trait.

Syntax

#[portrait::fill(portrait::delegate($delegate_type:ty, $self_to_delegate_value:expr))]

Alternatively, if the trait does not contain any associated functions with a receiver:

#[portrait::fill(portrait::delegate($delegate_type:ty))]
  • $delegate_type is the type that the implementation should delegate to.
  • $self_to_delegate_value is an expression that returns the value to delegate methods with a receiver to. References are automatically generated by the macro if required.

Example

#[portrait::make]
trait Foo {
    const BAR: i32;
    fn qux(&mut self, i: i64) -> u32;
    fn corge() -> u64;
    type Grault<U>;
}

// This is our delegation target type.
struct Real<T>(T);
impl<T> Foo for Real<T> {
    const BAR: i32 = 1;
    fn qux(&mut self, i: i64) -> u32 { i as u32 }
    fn corge() -> u64 { 3 }
    type Grault<U> = Option<U>;
}

struct Wrapper<T> {
    real: Real<T>,
}

#[portrait::fill(portrait::delegate(Real<T>; self.real))]
impl<T> Foo for Wrapper<T> {}
// Note: We cannot use `U` as the generic type
// because it is used in `type Grault<U>` in the trait definition.

assert_eq!(Wrapper::<u8>::BAR, 1);
assert_eq!(Wrapper::<u8> { real: Real(0) }.qux(2), 2);
assert_eq!(Wrapper::<u8>::corge(), 3);
let _: <Wrapper<u8> as Foo>::Grault<u8> = Some(1u8);

Debugging tips

If you see error E0275 or warn(unconditional_recursion), it is because you try to delegate to the same type. Note that it does not make sense to delegate to a value of the same type since all constants and types would be recursively defined (type X = X;), and all functions would be recursively implemented (fn x() { x() }).