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}