UseDelegate

Struct UseDelegate 

Source
pub struct UseDelegate<Components>(pub PhantomData<Components>);
Expand description

The UseDelegate pattern is used as the default dispatcher for CGP components that contain additional generic parameters in their traits.

When a provider trait contains additional generic parameters in addition to the Context type, CGP can generate a UseDelegate implementation that uses Components as a type-level lookup table to dispatch the implementation to different providers based on the generic types.

The implementation of UseDelegate follows the same pattern as the blanket implementation of a provider trait. However, instead of using the component name type as the key, it uses the specified generic parameters as the key to lookup the provider through DelegateComponent.

UseDelegate is very commonly used to perform ad hoc dispatch of concrete types to different context-generic providers. This allows the providers to remain generic, even when they may have implementations that overlaps on the generic parameters.

The implementation of UseDelegate can be automatically generated through the derive_delegate entry in #[cgp_component]. It is also possible to implement the dispatcher pattern on types other than UseDelegate, especially when there are multiple generic parameters that could be dispatched differently. We mainly use UseDelegate as the default dispatcher, so that users don’t need to remember the different provider types to be used with each component.

§Example

Given the following component definition:

#[cgp_component {
    provider: ErrorRaiser,
    derive_delegate: UseDelegate<SourceError>,
}]
pub trait CanRaiseError<SourceError>: HasErrorType {
    fn raise_error(error: SourceError) -> Self::Error;
}

The following UseDelegate implementation would be generated:

impl<Context, SourceError, Components, Delegate> ErrorRaiser<Context, SourceError>
    for UseDelegate<Components>
where
    Context: HasErrorType,
    Components: DelegateComponent<(SourceError), Delegate = Delegate>,
    Delegate: ErrorRaiser<Context, SourceError>,
{
    fn raise_error(error: SourceError) -> Context::Error {
        Delegate::raise_error(error)
    }
}

Tuple Fields§

§0: PhantomData<Components>

Trait Implementations§

Source§

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

The CanRaiseError trait is used to raise any concrete error type into an abstract error provided by HasErrorType.

Source§

fn raise_error(error: SourceError) -> <__Context__ as HasErrorType>::Error

Source§

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

Source§

fn wrap_error( error: <__Context__ as HasErrorType>::Error, detail: Detail, ) -> <__Context__ as HasErrorType>::Error

Source§

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

Source§

type Type = <__Delegate__ as ProvideType<__Context__, Tag>>::Type

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__, 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__, Tag, __Components__, __Delegate__> IsProviderFor<TypeComponent, __Context__, Tag> for UseDelegate<__Components__>
where __Components__: DelegateComponent<Tag, Delegate = __Delegate__>, __Delegate__: IsProviderFor<TypeComponent, __Context__, Tag> + ProvideType<__Context__, Tag>,

Auto Trait Implementations§

§

impl<Components> Freeze for UseDelegate<Components>

§

impl<Components> RefUnwindSafe for UseDelegate<Components>
where Components: RefUnwindSafe,

§

impl<Components> Send for UseDelegate<Components>
where Components: Send,

§

impl<Components> Sync for UseDelegate<Components>
where Components: Sync,

§

impl<Components> Unpin for UseDelegate<Components>
where Components: Unpin,

§

impl<Components> UnwindSafe for UseDelegate<Components>
where Components: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Builder, Source, Output> CanBuildFrom<Source> for Builder
where Source: HasFields + IntoBuilder, <Source as HasFields>::Fields: FieldsBuilder<<Source as IntoBuilder>::Builder, Builder, Output = Output>,

Source§

type Output = Output

Source§

fn build_from(self, source: Source) -> Output

Source§

impl<Source, Target, Remainder> CanDowncastFields<Target> for Source
where Target: HasFields, <Target as HasFields>::Fields: FieldsExtractor<Source, Target, Remainder = Remainder>,

Source§

type Remainder = Remainder

Source§

fn downcast_fields( self, _tag: PhantomData<Target>, ) -> Result<Target, <Source as CanDowncastFields<Target>>::Remainder>

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.