cgp_impl

Attribute Macro cgp_impl 

Source
#[cgp_impl]
Expand description

#[cgp_impl] provides a simplified ergonomic implementing a provider trait, by making it look like we are writing blanket implementations on a generic context.

The macro accepts a provider type in its attribute argument, along with an optional new keyword at the front. If new is specified, a provider struct is defined along with the trait impl.

The macro can be applied with a trait impl body, where the provider trait is implemented as if it has the same trait signature as the consumer trait. Behind the scene, it moves the Self type in the trait impl to the first position of the generic parameter in the trait path, and use the given provider type as the new Self type.

The macro also replaces all references to Self and self in the trait body to explicitly refer to the original context type.

After the transformation of the trait impl, #[cgp_impl] works the same way as #[cgp_provider], and also generates the corresponding IsProviderFor implementation for the provider.

ยงExample

Given the following provider trait implementation:

โ“˜
#[cgp_impl(GreetName)]
impl<Context> Greeter for Context
where
    Context: HasName,
{
    fn greet(context: &Context) {
        println!("Hello, {}!", context.name());
    }
}

would be equivalent to the following provider implementation using #[cgp_provider]:

โ“˜
#[cgp_provider]
impl<Context> Greeter<Context> for GreetName
where
    Context: HasName,
{
    fn greet(context: &Context) {
        println!("Hello, {}!", context.name());
    }
}

Which would generate the following IsProviderFor trait implementation:

โ“˜
impl<Context> IsProviderFor<GreeterComponent, Context> for GreetName
where
    Context: HasName,
{}