You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/component-macros.md
+52-11Lines changed: 52 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -361,6 +361,55 @@ impl CanUseContext for Context {}
361
361
362
362
The `check_components!` macro allows the use of array syntax at either the key or value position, when there are multiple components that share the same set of generic parameters.
363
363
364
+
## `delegate_and_check_components!` Macro
365
+
366
+
The `delegate_and_check_components!` macro combines both calls to `delegate_components!` and `check_components!`, so that wiring checks are done as soon as a delegate entry is added. This can simplify the boilerplate required to duplicate the code of listing all components in both delegate and check entries.
367
+
368
+
Given the following:
369
+
370
+
```rust,ignore
371
+
delegate_and_check_components! {
372
+
CanUseContext for Context;
373
+
ContextComponents {
374
+
ComponentA: ProviderA,
375
+
ComponentB: ProviderB,
376
+
[
377
+
ComponentC1,
378
+
ComponentC2,
379
+
...
380
+
]: ProviderC,
381
+
}
382
+
}
383
+
```
384
+
385
+
The macro would expand into the equivalent of:
386
+
387
+
```rust,ignore
388
+
delegate_components! {
389
+
ContextComponents {
390
+
ComponentA: ProviderA,
391
+
ComponentB: ProviderB,
392
+
[
393
+
ComponentC1,
394
+
ComponentC2,
395
+
...
396
+
]: ProviderC,
397
+
}
398
+
}
399
+
400
+
check_components! {
401
+
CanUseContext for Context {
402
+
ComponentA,
403
+
ComponentB,
404
+
ComponentC1,
405
+
ComponentC2,
406
+
}
407
+
}
408
+
```
409
+
410
+
You may wonder why we need define a separate macro, instead of always checking the wiring directly inside `delegate_components!`. The main reason is that while `delegate_and_check_components!` can work for the simple cases, it is more limited and cannot handle well on advanced cases where the CGP traits contain additional generic parameters. For such cases, it is still better to call `delegate_components!` and `check_components!` separately.
411
+
412
+
364
413
## Example Use
365
414
366
415
To illustrate how `cgp_component` and `delegate_components` can be
@@ -428,31 +477,23 @@ impl HasCgpProvider for Person {
428
477
typeCgpProvider=PersonComponents;
429
478
}
430
479
431
-
delegate_components! {
480
+
delegate_and_check_components! {
481
+
CanUsePersonforPerson;
432
482
PersonComponents {
433
483
StringFormatterComponent:
434
484
FormatAsJsonString,
435
485
StringParserComponent:
436
486
ParseFromJsonString,
437
487
}
438
488
}
439
-
440
-
check_components! {
441
-
CanUsePersonforPerson {
442
-
StringFormatterComponent,
443
-
StringParserComponent,
444
-
}
445
-
}
446
489
```
447
490
448
491
As we can see, the new code is significantly simpler and more readable than before.
449
492
Using `#[cgp_component]`, we no longer need to explicitly define the provider traits `StringFormatter` and `StringParser`, and the blanket implementations can be omitted.
450
493
451
494
With `#[cgp_new_provider]`, the `IsProviderFor` implementations for `FormatAsJsonString` and `ParseFromJsonString` are automatically implemented, together with the struct definitions.
452
495
453
-
We also make use of `delegate_components!` on `PersonComponents` to delegate `StringFormatterComponent` to `FormatAsJsonString`, and `StringParserComponent` to `ParseFromJsonString`.
454
-
455
-
Finally, the `check_components!` macro helps us check that we can in fact use `StringFormatterComponent` and `StringParserComponent` with the `Person` context.
496
+
We also make use of `delegate_and_check_components!` on `PersonComponents` to delegate `StringFormatterComponent` to `FormatAsJsonString`, and `StringParserComponent` to `ParseFromJsonString`, and then check to ensure that the wirings are implemented correctly for the `Person` context.
0 commit comments