1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use PhantomData;
/**
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:
```rust,ignore
#[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:
```rust,ignore
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)
}
}
```
*/
;