IsProviderFor

Trait IsProviderFor 

Source
pub trait IsProviderFor<Component, Context, Params = ()>
where Params: ?Sized,
{ }
Expand description

The IsProviderFor trait is used to propagate the constraints required to implement the provider trait that corresponds to the Component type.

§Parameters

The IsProviderFor trait parameters are used as follows:

  • Component: The component name type that corresponds to the provider trait.
  • Context: The Context type used in the provider trait.
  • Params: Any additional generic parameters in the provider trait, with multiple generic parameters grouped inside a tuple.

§IsProviderFor as a constraint carrier

The trait definition for IsProviderFor has an empty body that can be trivially implemented. However, when used with #[cgp_provider] or #[cgp_new_provider], on a provider trait implementation, it would be implemented by the Provider type with the same set of constraints as the provider trait implementation.

The IsProviderFor trait is included as a supertrait of all CGP provider traits generated from #[cgp_component]. This means that when there is any unsatisfied constraint in the provider trait implementation, it would also result in the same error shown in the IsProviderFor implementation.

§Why is this trait necessary?

The trait is necessary to force the Rust compiler to show any relevant error message when there are unsatisfied constraints in the provider trait implementation. By default, Rust would hide the error messages from the provider trait implementation, because there is also an alternative candidate implementation available, which is the blanket implementation of the provider trait.

On the other hand, the IsProviderFor trait is explicitly propagated inside delegate_components!, together with DelegateComponent. Because of this different implementation path, we are able to “unhide” the error messages that were hidden away by Rust.

§Example Definition

Given a CGP trait definition such as:

#[cgp_component(FooGetterAt)]
pub trait CanGetFooAt<I, J> {
    fn foo_at(&self, _phantom: PhantomData<(I, J)>) -> u64;
}

The following provider trait would be generated with the IsProviderFor supertrait:

pub trait FooGetterAt<Context, I, J>:
    IsProviderFor<FooGetterAtComponent, Context, (I, J)>
{
    fn foo_at(context: &Context, _phantom: PhantomData<(I, J)>) -> u64;
}

§Example Implementation

Given a provider trait implementation such as:

#[cgp_provider(FooGetterAt)]
impl<I, J> FooGetterAt<Context, I, J> for GetFooValue
where
    Context: HasField<Symbol!("foo"), Value = u64>,
{
    fn foo_at(context: &Context, _phantom: PhantomData<(I, J)>) -> u64 {
        context.get_field(PhantomData)
    }
}

The following implementation for IsProviderFor would be generated:

impl<Context, I, J>
    IsProviderFor<FooGetterAtComponent, Context, (I, J)>
    for GetFooValue
where
    Context: HasField<Symbol!("foo"), Value = u64>,
{
}

§Example Delegation

Given a component delegation such as:

delegate_component! {
    MyAppComponents {
        FooGetterAtComponent: GetFooValue,
    }
}

The following IsProviderFor implementation would be generated:

impl<Context, Params>
    IsProviderFor<FooGetterAtComponent, Context, Params>
    for MyAppComponents
where
    GetFooValue: IsProviderFor<FooGetterAtComponent, Context, Params>,
{
}

This means that MyAppComponents has an explicit implementation of IsProviderFor for all possible Context and Params, with the where constraint propagating the constraints coming from GetFooValue with the same Context and Params.

Because of this is an explicit implementation and not a blanket implementation, Rust would follow the implementation path and surface all unsatisfied constraints from GetFooValue.

Implementors§

Source§

impl<Context, Tag, Components, Type> IsProviderFor<TypeComponent, Context, Tag> for UseDelegatedType<Components>
where Components: DelegateComponent<Tag, Delegate = Type>,

Source§

impl<Context, Tag, Type> IsProviderFor<TypeComponent, Context, Tag> for UseType<Type>

Source§

impl<Context, TypeTag, FieldTag, Field> IsProviderFor<TypeComponent, Context, TypeTag> for UseField<FieldTag>
where Context: HasField<FieldTag, Value = Field>,

Source§

impl<Error, __Context__> IsProviderFor<ErrorTypeProviderComponent, __Context__> for UseType<Error>
where Error: Debug,

Source§

impl<__Context__> IsProviderFor<ErrorTypeProviderComponent, __Context__> for UseContext
where __Context__: HasErrorType,

Source§

impl<__Context__, Detail> IsProviderFor<ErrorWrapperComponent, __Context__, Detail> for UseContext
where __Context__: HasErrorType + CanWrapError<Detail>,

Source§

impl<__Context__, Detail, __Components__, __Delegate__> IsProviderFor<ErrorWrapperComponent, __Context__, Detail> for UseDelegate<__Components__>
where __Context__: HasErrorType, __Components__: DelegateComponent<Detail, Delegate = __Delegate__>, __Delegate__: IsProviderFor<ErrorWrapperComponent, __Context__, Detail> + ErrorWrapper<__Context__, Detail>,

Source§

impl<__Context__, SourceError> IsProviderFor<ErrorRaiserComponent, __Context__, SourceError> for UseContext
where __Context__: HasErrorType + CanRaiseError<SourceError>,

Source§

impl<__Context__, SourceError, __Components__, __Delegate__> IsProviderFor<ErrorRaiserComponent, __Context__, SourceError> for UseDelegate<__Components__>
where __Context__: HasErrorType, __Components__: DelegateComponent<SourceError, Delegate = __Delegate__>, __Delegate__: IsProviderFor<ErrorRaiserComponent, __Context__, SourceError> + ErrorRaiser<__Context__, SourceError>,

Source§

impl<__Context__, Tag> IsProviderFor<TypeComponent, __Context__, Tag> for UseContext
where __Context__: HasType<Tag>,

Source§

impl<__Context__, Tag, __Components__, __Delegate__> IsProviderFor<TypeComponent, __Context__, Tag> for UseDelegate<__Components__>
where __Components__: DelegateComponent<Tag, Delegate = __Delegate__>, __Delegate__: IsProviderFor<TypeComponent, __Context__, Tag> + ProvideType<__Context__, Tag>,

Source§

impl<__Provider__, __Context__> IsProviderFor<ErrorTypeProviderComponent, __Context__> for WithProvider<__Provider__>
where __Provider__: ProvideType<__Context__, ErrorTypeProviderComponent>, <__Provider__ as ProvideType<__Context__, ErrorTypeProviderComponent>>::Type: Debug,