cgp_macro/lib.rs
1#![no_std]
2
3/*!
4 This crate provides the proc macros used for defining CGP components.
5*/
6
7extern crate proc_macro;
8
9use proc_macro::TokenStream;
10
11/**
12 `#[cgp_component]` is the most basic macro used to define a CGP component.
13
14 The macro can be used on a Rust trait, which would be used as the base consumer
15 trait for the macro to generate the other constructs, including the provider
16 trait and the blanket implementations.
17
18 The macro accepts two forms of attribute arguments. If only an identifier is
19 provided, the identifier is used as the name of the provider trait. Otherwise,
20 the macro accepts a list of key/value pairs, with the following keys allowed:
21
22 - `name` - the name of the component. If not provided, the name would be in the
23 format `{provider_trait_name}Component`.
24
25 - `provider` - the name of the provider trait.
26
27 - `context` - the identifier used for the generic context type. If not provided,
28 the default identifier `Context` would be used.
29
30 - `derive_delegate` - a list of generic dispatcher wrappers to derive the
31 `UseDelegate` pattern on, with the matching generic parameters specified in
32 the generic argument of the wrapper. Refer to `UseDelegate` for more details.
33
34 ## Extension Macros
35
36 There are two other macros that extends `#[cgp_component]` that can be used for
37 deriving specialized CGP components: [`#[cgp_type]`](macro@cgp_type) can be used to
38 define abstract type components, and [`#[cgp_getter]`](macro@cgp_getter) can be used
39 to define getter components.
40
41 These macros share the same arguments and expansion as `#[cgp_component]`,
42 but also derive additional constructs for the specialized use cases.
43
44 ## Example
45
46 Given the following simplified component definition:
47
48 ```rust,ignore
49 #[cgp_component(Greeter)]
50 pub trait CanGreet {
51 fn greet(&self);
52 }
53 ```
54
55 is equivalent to the fully explicit definition:
56
57 ```rust,ignore
58 #[cgp_component {
59 name: GreeterComponent,
60 provider: Greeter,
61 context: Context,
62 }]
63 pub trait CanGreet {
64 fn greet(&self);
65 }
66 ```
67*/
68#[proc_macro_attribute]
69pub fn cgp_component(attr: TokenStream, item: TokenStream) -> TokenStream {
70 cgp_macro_lib::cgp_component(attr.into(), item.into())
71 .unwrap_or_else(syn::Error::into_compile_error)
72 .into()
73}
74
75/**
76 `#[cgp_provider]` is used for implementing a provider trait.
77
78 It is applied on a provider trait `impl` block, and generates the accompanying
79 `IsProviderFor` trait implementation that captures the same constraints as
80 specified in the provider trait implementation.
81
82 The macro is mainly used to propagate the provider implementation constraints
83 through the `IsProviderFor` trait, so that Rust would print out any unsatisfied
84 constraints in the error messages.
85
86 In an ideal world, Rust should be able to print out the unsatisfied constraints,
87 even if we don't have an `IsProviderFor` trait. However, since that is not the case,
88 the use of this macro is required on all provider trait implementations to ensure
89 that the unsatisfied constraints are always printed out.
90
91 The macro accepts an optional identifier as its argument, which is used as the
92 component name identifier. If not provided, the component name would default to
93 the format `{provider_trait_name}Component`.
94
95 Although the component name may be omitted when using `#[cgp_provider]`, a issue
96 that arises is that the default component name identifier cannot be imported
97 automatically by Rust Analyzer, due to it being an identifier generated by the
98 macro. This means that the user cannot use the quick fix feature to auto import
99 the component name, but instead has to add the import statement manually.
100
101 ## Example
102
103 Given the following provider trait implementation:
104
105 ```rust,ignore
106 #[cgp_provider]
107 impl<Context> Greeter<Context> for GreetName
108 where
109 Context: HasName,
110 {
111 fn greet(context: &Context) {
112 println!("Hello, {}!", context.name());
113 }
114 }
115 ```
116
117 Is equivalent to the following fully explicit implementation:
118
119 ```rust,ignore
120 #[cgp_provider(GreeterComponent)]
121 impl<Context> Greeter<Context> for GreetName
122 where
123 Context: HasName,
124 {
125 fn greet(context: &Context) {
126 println!("Hello, {}!", context.name());
127 }
128 }
129 ```
130
131 Which would generate the following `IsProviderFor` trait implementation:
132
133 ```rust,ignore
134 impl<Context> IsProviderFor<GreeterComponent, Context> for GreetName
135 where
136 Context: HasName,
137 {}
138 ```
139*/
140#[proc_macro_attribute]
141pub fn cgp_provider(attr: TokenStream, item: TokenStream) -> TokenStream {
142 cgp_macro_lib::cgp_provider(attr.into(), item.into())
143 .unwrap_or_else(syn::Error::into_compile_error)
144 .into()
145}
146
147/**
148 `#[cgp_impl]` provides a simplified ergonomic implementing a provider trait,
149 by making it look like we are writing blanket implementations on a generic context.
150
151 The macro accepts a provider type in its attribute argument, along with an optional `new`
152 keyword at the front. If `new` is specified, a provider struct is defined along with
153 the trait impl.
154
155 The macro can be applied with a trait `impl` body, where the provider trait is implemented
156 as if it has the same trait signature as the consumer trait. Behind the scene, it moves
157 the `Self` type in the trait impl to the first position of the generic parameter
158 in the trait path, and use the given provider type as the new `Self` type.
159
160 The macro also replaces all references to `Self` and `self` in the trait body to explicitly
161 refer to the original context type.
162
163 After the transformation of the trait `impl`, `#[cgp_impl]` works the same way as
164 [`#[cgp_provider]`](cgp_provider), and also generates the corresponding `IsProviderFor`
165 implementation for the provider.
166
167 ## Example
168
169 Given the following provider trait implementation:
170
171 ```rust,ignore
172 #[cgp_impl(GreetName)]
173 impl<Context> Greeter for Context
174 where
175 Context: HasName,
176 {
177 fn greet(context: &Context) {
178 println!("Hello, {}!", context.name());
179 }
180 }
181 ```
182
183 would be equivalent to the following provider implementation using `#[cgp_provider]`:
184
185 ```rust,ignore
186 #[cgp_provider]
187 impl<Context> Greeter<Context> for GreetName
188 where
189 Context: HasName,
190 {
191 fn greet(context: &Context) {
192 println!("Hello, {}!", context.name());
193 }
194 }
195 ```
196
197 Which would generate the following `IsProviderFor` trait implementation:
198
199 ```rust,ignore
200 impl<Context> IsProviderFor<GreeterComponent, Context> for GreetName
201 where
202 Context: HasName,
203 {}
204 ```
205*/
206#[proc_macro_attribute]
207pub fn cgp_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
208 cgp_macro_lib::cgp_impl(attr.into(), item.into())
209 .unwrap_or_else(syn::Error::into_compile_error)
210 .into()
211}
212
213/**
214 The `#[cgp_new_provider]` macro is an extension to [`#[cgp_provider]`](macro@cgp_provider)
215 that in addition to the derivation of `IsProviderFor`, also generates a new provider
216 struct based on the `Self` type.
217
218 This macro is a convenient shorthand for users to skip the manual definition of
219 the provider struct. It is commonly used when user only wants to implement one
220 provider trait for each provider struct.
221
222 When the user wants to implement multiple provider traits for the same provider struct,
223 the user should still explicitly define the provider struct, and use `#[cgp_provider]`
224 instead.
225
226 ## Example
227
228 Given the following provider trait implementation:
229
230 ```rust,ignore
231 #[cgp_provider]
232 impl<Context> Greeter<Context> for GreetName
233 where
234 Context: HasName,
235 {
236 fn greet(context: &Context) {
237 println!("Hello, {}!", context.name());
238 }
239 }
240 ```
241
242 The provider struct `GreetName` is also generated as follows:
243
244 ```rust
245 struct GreetName;
246 ```
247*/
248#[proc_macro_attribute]
249pub fn cgp_new_provider(attr: TokenStream, item: TokenStream) -> TokenStream {
250 cgp_macro_lib::cgp_new_provider(attr.into(), item.into())
251 .unwrap_or_else(syn::Error::into_compile_error)
252 .into()
253}
254
255/**
256 `#[cgp_getter]` is an extension to [`#[cgp_component]`](macro@cgp_component) that
257 derives additional getter constructs.
258
259 This macro can only be used on traits that contains only getter-like methods.
260
261 The macro accepts the same arguments as `#[cgp_component]`, and generates the same
262 CGP component constructs. Additionally, it also generates implementation for the
263 following getter providers:
264
265 - `UseField<Tag>` - implements the provider trait using `HasField<Tag>`.
266 - `UseFields` - implements the provider trait using `HasField`, with the tag
267 being the same name as the getter methods.
268 - `WithProvider<Provider>` - implements the provider trait if the given
269 `Provider` implements `FieldGetter<ComponentName>`.
270
271 ## Example
272
273 Given the following getter component definition:
274
275 ```rust,ignore
276 #[cgp_component(NameGetter)]
277 pub trait HasName {
278 fn name(&self) -> &str;
279 }
280 ```
281
282 The following getter providers are generated:
283
284 ```rust,ignore
285 #[cgp_provider]
286 impl<Context, Tag> NameGetter<Context> for UseField<Tag>
287 where
288 Context: HasField<Tag, Value = String>,
289 {
290 fn get(context: &Context) -> &str {
291 context.get_field(PhantomData).as_str()
292 }
293 }
294
295 #[cgp_provider]
296 impl<Context> NameGetter<Context> for UseFields
297 where
298 Context: HasField<Symbol!("name"), Value = String>,
299 {
300 fn get(context: &Context) -> &str {
301 context.get_field(PhantomData).as_str()
302 }
303 }
304
305 #[cgp_provider]
306 impl<Context, Provider> NameGetter<Context> for WithProvider<Provider>
307 where
308 Provider: FieldGetter<Context, NameGetterComponent, Value = String>,
309 {
310 fn get(context: &Context) -> &str {
311 Provider::get_field(context, PhantomData).as_str()
312 }
313 }
314 ```
315*/
316#[proc_macro_attribute]
317pub fn cgp_getter(attr: TokenStream, item: TokenStream) -> TokenStream {
318 cgp_macro_lib::cgp_getter(attr.into(), item.into())
319 .unwrap_or_else(syn::Error::into_compile_error)
320 .into()
321}
322
323/**
324 `#[cgp_auto_getter]` is used on a regular getter Rust trait without turnning it
325 into a CGP component. Instead, a blanket implementation is derived directly on
326 that trait.
327
328 This macro can only be used on traits that contains only getter-like methods.
329
330 This macro is a simplified version of [`#[cgp_getter]`](macro@cgp_getter) that does
331 not require explicit implementation or wiring. Instead, the trait would have a blanket
332 implementation that is implemented only if the context implements `HasField` with the
333 field having the exact same name as the getter methods.
334
335 This macro serves as a convenient alternative, so that whenever there is a need to
336 use the `HasField` trait directly, one can instead define a getter trait that is
337 applied with `#[cgp_auto_getter]`.
338
339 This can significantly improve developer experience, as the `HasField` trait can be
340 confusing to new users, who may not be familiar with how the field tag being used
341 as a type-level string instead of regular values.
342
343 ## Example
344
345 Given the following getter trait definition:
346
347 ```rust,ignore
348 #[cgp_auto_getter]
349 pub trait HasName {
350 fn name(&self) -> &str;
351 }
352 ```
353
354 The trait will always be implemented for any struct that derives `HasField` with
355 a `name` field of type `String`, without requiring further wiring. For example:
356
357 ```rust,ignore
358 #[derive(HasField)]
359 struct Person {
360 name: String,
361 }
362 ```
363
364 or:
365
366 ```rust,ignore
367 #[derive(HasField)]
368 struct Person {
369 name: String,
370 age: u8,
371 }
372 ```
373*/
374#[proc_macro_attribute]
375pub fn cgp_auto_getter(attr: TokenStream, item: TokenStream) -> TokenStream {
376 cgp_macro_lib::cgp_auto_getter(attr.into(), item.into())
377 .unwrap_or_else(syn::Error::into_compile_error)
378 .into()
379}
380
381/**
382 The `delegate_components!` macro is used to define wiring of CGP components
383 on a provider type.
384
385 ## Type-Level Maps
386
387 Conceptually, we can think of the use of `delegate_components!` as defining a
388 type-level map, with the keys and values being types. When the keys are the
389 CGP component name types and the values are the CGP providers, then
390 `delegate_components!` is effectively implementing the specified providers
391 on the target type by delegating them to the providers specified in the
392 type-level map.
393
394 The macro is implemented by having the target type implement the `DelegateComponent`
395 trait, with the key used in the `Name` parameter and the value being set as the
396 `Delegate` associated type.
397
398 Additionally, for each key/value entry, the macro also generates implementation for
399 the `IsProviderFor` trait, which would be used during provider trait implementation
400 to propagate any unsatisfied constraints error to be shown to the user.
401
402 ## Basic Syntax
403
404 In its most basic form, the macro can be used by specifying a list of key/value pairs
405 as follows:
406
407 ```rust,ignore
408 delegate_components! {
409 MyComponents {
410 KeyA: ValueA,
411 KeyB: ValueB,
412 ...
413 }
414 }
415 ```
416
417 This would turn the target type into a type-level map, which would contain the entries
418 `KeyA` -> `ValueA`, `KeyB` -> `ValueB`, etc. For each `Key` and `Value`, the macro
419 would generate the following implementation:
420
421 ```rust,ignore
422 impl DelegateComponent<Key> for MyComponents
423 {
424 type Delegate = Value;
425 }
426
427 impl<Context, Params> IsProviderFor<Key, Context, Params> for Value
428 where
429 Value: IsProviderFor<Key, Context, Params>,
430 {
431 }
432 ```
433
434 ## Grouping Keys
435
436 The macro also supports grouping multiple keys together using the list syntax,
437 when the grouped keys all map to the same value. This is useful when we want to
438 delegate multiple CGP components to the same target provider.
439
440 For example, given the following:
441
442 ```rust,ignore
443 delegate_components! {
444 MyComponents {
445 [
446 KeyA,
447 KeyB,
448 ...
449 ]:
450 Value,
451 }
452 }
453 ```
454
455 It would be equivalent to the following:
456
457 ```rust,ignore
458 delegate_components! {
459 MyComponents {
460 KeyA: Value,
461 KeyB: Value,
462 ...
463 }
464 }
465 ```
466
467 ## Generating Mapping Struct
468
469 By default, mapping types like `MyComponents` would be defined outside of `delegate_components!`
470 as a dummy struct, or generated through other macros such as `#[cgp_context]`. However,
471 `delegate_components!` also accepts an optional `new` keyword in front of the map type,
472 in which it would also generate the struct definition for the mapping type.
473
474 For example, given the following:
475
476 ```rust,ignore
477 delegate_components! {
478 new MyComponents {
479 KeyA: ValueA,
480 KeyB: ValueB,
481 ...
482 }
483 }
484 ```
485
486 The macro would also generate the `MyComponents` struct as follows:
487
488 ```rust,ignore
489 pub struct MyComponents;
490 ```
491
492 ## Inner Maps
493
494 When defining component wiring that involves inner maps, such as with the use of
495 `UseDelegate`, `delegate_components!` also supports defining the inner map type
496 as well as the definition of inner key/value pairs all within the same macro invocation.
497
498 For example, given the following:
499
500 ```rust,ignore
501 delegate_components! {
502 MyComponents {
503 OuterKey: UseDelegate<new InnerMap {
504 InnerKeyA: InnerValueA,
505 InnerKeyB: InnerValueB,
506 ...
507 }>,
508 }
509 }
510 ```
511
512 It would be the same as writing two separate calls to `delegate_components!` as follows:
513
514 ```rust,ignore
515 delegate_components! {
516 MyComponents {
517 OuterKey: UseDelegate<InnerMap>,
518 }
519 }
520
521 delegate_components! {
522 new InnerMap {
523 InnerKeyA: InnerValueA,
524 InnerKeyB: InnerValueB,
525 ...
526 }
527 }
528 ```
529*/
530#[proc_macro]
531pub fn delegate_components(body: TokenStream) -> TokenStream {
532 cgp_macro_lib::delegate_components(body.into())
533 .unwrap_or_else(syn::Error::into_compile_error)
534 .into()
535}
536
537/**
538 The `check_components!` macro allows users to write compile-time tests to check
539 for the correctness of component wiring for a CGP context.
540
541 ## Example
542
543 Given the following:
544
545 ```rust,ignore
546 check_components! {
547 CanUsePerson for Person {
548 GreeterComponent,
549 }
550 }
551 ```
552
553
554 The code above generates a *check trait* called `CanUsePerson`, which verifies
555 whether the `Person` context implements the consumer trait for
556 `GreeterComponent` (i.e., `CanGreet`):
557
558 ```rust,ignore
559 trait CanUsePerson<Component, Params>: CanUseComponent<Component, Params> {}
560
561 impl CanUsePerson<GreeterComponent, ()> for Person {}
562 ```
563*/
564#[proc_macro]
565pub fn check_components(body: TokenStream) -> TokenStream {
566 cgp_macro_lib::check_components(body.into())
567 .unwrap_or_else(syn::Error::into_compile_error)
568 .into()
569}
570
571/**
572 The `delegate_and_check_components!` macro combines both `delegate_components!`
573 and `check_components!`, allowing both delegation and checks within a single
574 macro call.
575
576 This is useful for the majority of simple cases, providing immediate feedback on
577 whether the wiring works as intended.
578
579 ## Example
580
581 Given the following code:
582
583 ```rust,ignore
584 delegate_and_check_components! {
585 CanUsePerson for Person;
586 PersonComponents {
587 GreeterComponent: GreetHello,
588 }
589 }
590 ```
591
592 is equivalent to writing the two separate macro calls:
593
594 ```rust,ignore
595 delegate_components! {
596 PersonComponents {
597 GreeterComponent: GreetHello,
598 }
599 }
600
601 check_components! {
602 CanUsePerson for Person {
603 GreeterComponent,
604 }
605 }
606 ```
607
608 In more advanced cases, it may still be necessary to call `delegate_components!`
609 and `check_components` separately. This applies to cases where the CGP traits
610 contain additional generic parameters, or when presets are used.
611*/
612#[proc_macro]
613pub fn delegate_and_check_components(body: TokenStream) -> TokenStream {
614 cgp_macro_lib::delegate_and_check_components(body.into())
615 .unwrap_or_else(syn::Error::into_compile_error)
616 .into()
617}
618
619/**
620 CGP presets are made of extensible collection of key/value mappings, that can be inherited
621 to form new mappings.
622
623 Instead of defining regular structs and build mappings with `delegate_components!`,
624 presets are constructed as _modules_ using the `cgp_preset!` macro together with the
625 `#[re_export_imports]`. For example, the same mappings earlier would be rewritten as:
626
627 ```rust,ignore
628 #[cgp::re_export_imports]
629 mod preset {
630 use crate_a::{KeyA, ...};
631 use crate_b::{ValueA, ...};
632
633 cgp_preset! {
634 PresetA {
635 KeyA: ValueA,
636 KeyB: ValueB,
637 KeyC: ValueC1,
638 }
639 }
640 }
641 ```
642
643 The `#[cgp::re_export_imports]` macro is used over a surrogate `mod preset`, which wraps
644 around the inner module to re-export the imports, so that they can be reused during the
645 merging. This is required, because the merging works through macros, which don't have access to the actual type information. Aside from that, the macro re-exports all exports from the inner module, so that we can write regular code as if the `mod preset` modifier never existed.
646
647 The macro `cgp_preset!` works similar to `delegate_components!`, but it defines a new
648 _inner module_ that contains the mapping struct, together with macros and re-exports to
649 support the merging operation.
650
651 Similarly, the second preset would be re-written as:
652
653 ```rust,ignore
654 #[cgp::re_export_imports]
655 mod preset {
656 use crate_c::{KeyC, ...};
657 use crate_d::{ValueD, ...};
658
659 cgp_preset! {
660 PresetB {
661 KeyC: ValueC2,
662 KeyD: ValueD,
663 KeyE: ValueE,
664 }
665 }
666 }
667 ```
668
669 To merge the two presets, we can define a new `PresetC` that _inherits_ from both `PresetA`
670 and `PresetB`, like follows:
671
672 ```rust,ignore
673 #[cgp::re_export_imports]
674 mod preset {
675 use preset_a::PresetA;
676 use preset_b::PresetB;
677 use crate_f::{KeyF, ...};
678
679 cgp_preset! {
680 PresetC: PresetA + PresetB {
681 override KeyC: ValueC2,
682 KeyF: ValueF,
683 }
684 }
685 }
686 ```
687
688 As we can see, CGP supports *multiple inheritance* for presets by using macros to "copy"
689 over the entries from the parent preset. To resolve conflicts or override entries from
690 the parent presets, the `override` keyword can be used to exclude a given mapping from
691 being copied over and instead use the local definition. And since the underlying
692 implementation still uses `DelegateComponent` to implement the lookup, any non-overridden
693 conflicts would simply result in a trait error due to overlapping instances, thus preventing
694 the diamond inheritance dillema.
695*/
696#[proc_macro]
697pub fn cgp_preset(body: TokenStream) -> TokenStream {
698 cgp_macro_lib::define_preset(body.into())
699 .unwrap_or_else(syn::Error::into_compile_error)
700 .into()
701}
702
703/**
704 `#[cgp_type]` is an extension to [`#[cgp_component]`](macro@cgp_component) that
705 derives additional constructs for abstract type components.
706
707 This macro can only be used on an abstract type trait that contains a single
708 associated type as its item, and nothing else.
709
710 The macro can be used with no attribute argument, in which case the provider
711 type would be named in the format `{associated_type_name}TypeProvider`.
712
713 In addition to the component constructs generated by `#[cgp_component]`, the macro
714 also generates a provider for `UseType<Type>`, that implements the provider trait
715 using `Type`.
716
717 The macro also generates a type alias for accessing the associated type, with the
718 type alias named in the format `{associated_type_name}Of`.
719
720 For advanced use cases, the macro also generates an implementation of
721 `WithProvider<Provider>`, which implements the provider trait if the given
722 `Provider` implements `TypeProvider<Context, ComponentName>`.
723
724 ## Example
725
726 Given the following abstract type trait definition:
727
728 ```rust,ignore
729 #[cgp_type]
730 pub trait HasNameType {
731 type Name: Display;
732 }
733 ```
734
735 would be equivalent to the following fully explicit definition:
736
737 ```rust,ignore
738 #[cgp_type {
739 name: NameTypeProviderComponent,
740 provider: NameTypeProvider,
741 context: Context,
742 }]
743 pub trait HasNameType {
744 type Name: Display;
745 }
746 ```
747
748 Which would generate the following constructs:
749
750 ```rust,ignore
751 impl<Context, Type> NameTypeProvider<Context> for UseType<Type>
752 where
753 Type: Display,
754 {
755 type Name = Type;
756 }
757
758 type NameOf<Context> = <Context as HasNameType>::Name;
759
760 impl<Context, Provider> HasNameType<Context> for WithProvider<Provider>
761 where
762 Provider: TypeProvider<Context, NameTypeProviderComponent>,
763 Provider::Type: Display,
764 {
765 type Name = Provider::Type;
766 }
767 ```
768*/
769#[proc_macro_attribute]
770pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> TokenStream {
771 cgp_macro_lib::cgp_type(attrs.into(), body.into())
772 .unwrap_or_else(syn::Error::into_compile_error)
773 .into()
774}
775
776/**
777 The `#[cgp_context]` macro is used when defining a CGP context.
778
779 The macro can be used with a struct definition. An optional identifier can be
780 provided to be used as the name of the provider for the context. If not provided,
781 the context provider would be named in the format `{struct_name}Components`.
782
783 The macro generates a struct definition for the context provider, and implements
784 `DelegateComponent` for the context struct to point to the context provider.
785
786 ## Example
787
788 Given the following context definition:
789
790 ```rust,ignore
791 #[cgp_context]
792 pub struct MyApp {
793 name: String,
794 }
795 ```
796
797 would be equivalent to the following fully explicit definition:
798
799 ```rust,ignore
800 #[cgp_context(MyAppComponents)]
801 pub struct MyApp {
802 name: String,
803 }
804 ```
805
806 which would generate the following constructs:
807
808 ```rust,ignore
809 struct MyAppComponents;
810
811 impl<Name> DelegateComponent<Name> for MyApp {
812 type Delegate = MyAppComponents;
813 }
814 ```
815
816 ## Preset Inheritance
817
818 The macro also allows the context provider to inherit its component mappings
819 from a specified preset. The preset can be specified following a `:`, after
820 the context provider name is specified.
821
822 The context provider would implement `DelegateComponent` for all keys in the
823 preset, with the `Delegate` target pointing to `Preset::Provider`. This is
824 done through the `IsPreset` trait generated from the [`cgp_preset!`] macro.
825
826 For example, given the following definition:
827
828 ```rust,ignore
829 #[cgp_context(MyAppComponents: MyPreset)]
830 pub struct MyApp {
831 name: String,
832 }
833 ```
834
835 The following blanket implementation would be generated:
836
837 ```rust,ignore
838 impl<Name> DelegateComponent<Name> for MyAppComponents
839 where
840 Self: MyPreset::IsPreset<Name>,
841 {
842 type Delegate = MyPreset::Provider;
843 }
844 ```
845*/
846#[proc_macro_attribute]
847pub fn cgp_context(attr: TokenStream, item: TokenStream) -> TokenStream {
848 cgp_macro_lib::cgp_context(attr.into(), item.into())
849 .unwrap_or_else(syn::Error::into_compile_error)
850 .into()
851}
852
853#[proc_macro_attribute]
854pub fn cgp_inherit(attr: TokenStream, item: TokenStream) -> TokenStream {
855 cgp_macro_lib::cgp_inherit(attr.into(), item.into())
856 .unwrap_or_else(syn::Error::into_compile_error)
857 .into()
858}
859
860/**
861 The `#[blanket_trait]` macro can be used to define trait aliases that contain
862 empty body and trivial blanket implementations.
863
864 Developers can use the `#[blanket_trait]` macro to define trait aliases,
865 as well as abstract type aliases for more advanced cases.
866
867 ## Example
868
869 Given the following:
870
871 ```rust,ignore
872 #[trait_alias]
873 pub trait HasErrorType: Async + HasErrorType<Error: Async> {}
874 ```
875
876 automatically generates the following blanket implementation:
877
878 ```rust,ignore
879 impl<Context> HasErrorType for Context
880 where
881 Context: Async + HasErrorType<Error: Async> {}
882 ```
883*/
884#[proc_macro_attribute]
885pub fn blanket_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
886 cgp_macro_lib::blanket_trait(attr.into(), item.into())
887 .unwrap_or_else(syn::Error::into_compile_error)
888 .into()
889}
890
891#[proc_macro_attribute]
892pub fn re_export_imports(attrs: TokenStream, body: TokenStream) -> TokenStream {
893 cgp_macro_lib::re_export_imports(attrs.into(), body.into())
894 .unwrap_or_else(syn::Error::into_compile_error)
895 .into()
896}
897
898#[proc_macro]
899pub fn replace_with(body: TokenStream) -> TokenStream {
900 cgp_macro_lib::replace_with(body.into())
901 .unwrap_or_else(syn::Error::into_compile_error)
902 .into()
903}
904
905/**
906 The `Symbol!` macro is used to create a type-level string through the string literal
907 given to the macro.
908
909 The macro constructs the type-level string through a chain of `Char` types and
910 terminated with the `Nil` type. In other words, it constructs a type-level list
911 of characters to represent them as a type-level string.
912
913 Read more about type-level strings in the documentation for `Char`.
914
915 ## Example
916
917 Given the following symbol definition:
918
919 ```rust,ignore
920 type Hello = Symbol!("hello");
921 ```
922
923 The following type would be generated:
924
925 ```rust,ignore
926 type Hello = Char<'h', Char<'e', Char<'l', Char<'l', Char<'o', Nil>>>>>;
927 ```
928
929 which would be shown with the shortened representation as:
930
931 ```rust,ignore
932 type Hello = ζ<'h', ζ<'e', ζ<'l', ζ<'l', ζ<'o', ε>>>>>;
933 ```
934*/
935#[proc_macro]
936#[allow(non_snake_case)]
937pub fn Symbol(body: TokenStream) -> TokenStream {
938 cgp_macro_lib::make_symbol(body.into()).into()
939}
940
941/**
942 The `Product!` macro is used to define a type-level list of types, a.k.a. a product type.
943
944 Given a list of types to the macro, it would generate a chain of `Cons` types
945 for each type in the list, and terminated with the `Nil` type.
946
947 Read more about product types in the documentation for `Cons`.
948
949 ## Example
950
951 Given the following product type definition:
952
953 ```rust,ignore
954 type MyTypes = Product![u32, String, bool];
955 ```
956
957 The following type would be generated:
958
959 ```rust,ignore
960 type MyTypes = Cons<u32, Cons<String, Cons<bool, Nil>>>;
961 ```
962
963 which would be shown with the shortened representation as:
964
965 ```rust,ignore
966 type MyTypes = π<u32, π<String, π<bool, ε>>>;
967 ```
968*/
969#[proc_macro]
970#[allow(non_snake_case)]
971pub fn Product(body: TokenStream) -> TokenStream {
972 cgp_macro_lib::make_product_type(body.into()).into()
973}
974
975/**
976 The `Sum!` macro is used to define a sum type, with the given list of types
977 as disjoint variants.
978
979 Given a list of types to the macro, it would generate a chain of `Either` types
980 for each type in the list, and terminated with the `Void` type.
981
982 Read more about sum types in the documentation for `Either`.
983
984 ## Example
985
986 Given the following sum type definition:
987
988 ```rust,ignore
989 type MyUnion = Sum![u32, String, bool];
990 ```
991
992 The following type would be generated:
993
994 ```rust,ignore
995 type MyUnion = Either<u32, Either<String, Either<bool, Void>>>;
996 ```
997
998 which would be shown with the shortened representation as:
999
1000 ```rust,ignore
1001 type MyUnion = σ<u32, σ<String, σ<bool, θ>>>;
1002 ```
1003*/
1004#[proc_macro]
1005#[allow(non_snake_case)]
1006pub fn Sum(body: TokenStream) -> TokenStream {
1007 cgp_macro_lib::make_sum_type(body.into()).into()
1008}
1009
1010#[proc_macro]
1011pub fn product(body: TokenStream) -> TokenStream {
1012 cgp_macro_lib::make_product_expr(body.into()).into()
1013}
1014
1015#[proc_macro_derive(HasField)]
1016pub fn derive_fields(item: TokenStream) -> TokenStream {
1017 cgp_macro_lib::derive_has_field(item.into()).into()
1018}
1019
1020#[proc_macro_derive(HasFields)]
1021pub fn derive_has_fields(item: TokenStream) -> TokenStream {
1022 cgp_macro_lib::derive_has_fields(item.into())
1023 .unwrap_or_else(syn::Error::into_compile_error)
1024 .into()
1025}
1026
1027#[proc_macro_derive(BuildField)]
1028pub fn derive_builder(item: TokenStream) -> TokenStream {
1029 cgp_macro_lib::derive_build_field(item.into())
1030 .unwrap_or_else(syn::Error::into_compile_error)
1031 .into()
1032}
1033
1034#[proc_macro_derive(ExtractField)]
1035pub fn derive_extractor(item: TokenStream) -> TokenStream {
1036 cgp_macro_lib::derive_extract_field(item.into())
1037 .unwrap_or_else(syn::Error::into_compile_error)
1038 .into()
1039}
1040
1041#[proc_macro_derive(FromVariant)]
1042pub fn derive_from_variant(item: TokenStream) -> TokenStream {
1043 cgp_macro_lib::derive_from_variant(item.into())
1044 .unwrap_or_else(syn::Error::into_compile_error)
1045 .into()
1046}
1047
1048#[proc_macro_derive(CgpVariant)]
1049pub fn derive_cgp_variant(item: TokenStream) -> TokenStream {
1050 cgp_macro_lib::derive_cgp_variant(item.into())
1051 .unwrap_or_else(syn::Error::into_compile_error)
1052 .into()
1053}
1054
1055#[proc_macro_derive(CgpRecord)]
1056pub fn derive_cgp_record(item: TokenStream) -> TokenStream {
1057 cgp_macro_lib::derive_cgp_record(item.into())
1058 .unwrap_or_else(syn::Error::into_compile_error)
1059 .into()
1060}
1061
1062#[proc_macro_derive(CgpData)]
1063pub fn derive_cgp_data(item: TokenStream) -> TokenStream {
1064 cgp_macro_lib::derive_cgp_data(item.into())
1065 .unwrap_or_else(syn::Error::into_compile_error)
1066 .into()
1067}