cgp_component/traits/
delegate_component.rs

1/**
2   This is the core trait used by the `delegate_component!` macro to define a mapping
3   from `Name` to `Delegate` on the target `Self` type.
4
5   ## `DelegateComponent` as a type-level key-value map
6
7   Essentially, `DelegateComponent` turns the `Self` type into a type-level key-value map,
8   with `Name` as the key and `Delegate` as the value. The implementation of
9   `DelegateComponent` serves as "setting" an entry of `Self` at `Name` to `Delegate`.
10   Then, the inclusion of `DelegateComponent` in a constraint serves as "getting" the
11   `Delegate` value with the provided `Name` as the key.
12
13   When `Name` type in `DelegateComponent` is a CGP component name type, then the `Self`
14   type would also automatically implement the corresponding provider trait through the
15   blanket implementation.
16
17   However, it is also common to use `DelegateComponent` with regular types as the `Name`
18   key, especially when it is used to define lookup tables for providers such as
19   `UseDelegate`. In such cases, the `Self` type that implements `DelegateComponent` would
20   not be used to implement any provider trait.
21
22   ## Examples
23
24   As an example, given the following `delegate_component!` macro invocation:
25
26   ```rust,ignore
27   delegate_component! {
28       MyComponent {
29           GreeterComponent: GreetHello,
30       }
31   }
32   ```
33
34   would generate the following impl:
35
36   ```rust,ignore
37   impl DelegateComponent<GreeterComponent> for MyComponent {
38       type Delegate = GreetHello;
39   }
40   ```
41*/
42#[diagnostic::on_unimplemented(
43    message = "{Self} does not contain any DelegateComponent entry for {Name}",
44    note = "You might want to implement the provider trait for {Name} on {Self}"
45)]
46pub trait DelegateComponent<Name: ?Sized> {
47    type Delegate;
48}