Skip to main content

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#[proc_macro_attribute]
214pub fn cgp_fn(attr: TokenStream, item: TokenStream) -> TokenStream {
215    cgp_macro_lib::cgp_fn(attr.into(), item.into())
216        .unwrap_or_else(syn::Error::into_compile_error)
217        .into()
218}
219
220/**
221    The `#[cgp_new_provider]` macro is an extension to [`#[cgp_provider]`](macro@cgp_provider)
222    that in addition to the derivation of `IsProviderFor`, also generates a new provider
223    struct based on the `Self` type.
224
225    This macro is a convenient shorthand for users to skip the manual definition of
226    the provider struct. It is commonly used when user only wants to implement one
227    provider trait for each provider struct.
228
229    When the user wants to implement multiple provider traits for the same provider struct,
230    the user should still explicitly define the provider struct, and use `#[cgp_provider]`
231    instead.
232
233    ## Example
234
235    Given the following provider trait implementation:
236
237    ```rust,ignore
238    #[cgp_provider]
239    impl<Context> Greeter<Context> for GreetName
240    where
241        Context: HasName,
242    {
243        fn greet(context: &Context) {
244            println!("Hello, {}!", context.name());
245        }
246    }
247    ```
248
249    The provider struct `GreetName` is also generated as follows:
250
251    ```rust
252    struct GreetName;
253    ```
254*/
255#[proc_macro_attribute]
256pub fn cgp_new_provider(attr: TokenStream, item: TokenStream) -> TokenStream {
257    cgp_macro_lib::cgp_new_provider(attr.into(), item.into())
258        .unwrap_or_else(syn::Error::into_compile_error)
259        .into()
260}
261
262/**
263    `#[cgp_getter]` is an extension to [`#[cgp_component]`](macro@cgp_component) that
264    derives additional getter constructs.
265
266    This macro can only be used on traits that contains only getter-like methods.
267
268    The macro accepts the same arguments as `#[cgp_component]`, and generates the same
269    CGP component constructs. Additionally, it also generates implementation for the
270    following getter providers:
271
272    - `UseField<Tag>` - implements the provider trait using `HasField<Tag>`.
273    - `UseFields` - implements the provider trait using `HasField`, with the tag
274      being the same name as the getter methods.
275    - `WithProvider<Provider>` - implements the provider trait if the given
276      `Provider` implements `FieldGetter<ComponentName>`.
277
278    ## Example
279
280    Given the following getter component definition:
281
282    ```rust,ignore
283    #[cgp_component(NameGetter)]
284    pub trait HasName {
285        fn name(&self) -> &str;
286    }
287    ```
288
289    The following getter providers are generated:
290
291    ```rust,ignore
292    #[cgp_provider]
293    impl<Context, Tag> NameGetter<Context> for UseField<Tag>
294    where
295        Context: HasField<Tag, Value = String>,
296    {
297        fn get(context: &Context) -> &str {
298            context.get_field(PhantomData).as_str()
299        }
300    }
301
302    #[cgp_provider]
303    impl<Context> NameGetter<Context> for UseFields
304    where
305        Context: HasField<Symbol!("name"), Value = String>,
306    {
307        fn get(context: &Context) -> &str {
308            context.get_field(PhantomData).as_str()
309        }
310    }
311
312    #[cgp_provider]
313    impl<Context, Provider> NameGetter<Context> for WithProvider<Provider>
314    where
315        Provider: FieldGetter<Context, NameGetterComponent, Value = String>,
316    {
317        fn get(context: &Context) -> &str {
318            Provider::get_field(context, PhantomData).as_str()
319        }
320    }
321    ```
322*/
323#[proc_macro_attribute]
324pub fn cgp_getter(attr: TokenStream, item: TokenStream) -> TokenStream {
325    cgp_macro_lib::cgp_getter(attr.into(), item.into())
326        .unwrap_or_else(syn::Error::into_compile_error)
327        .into()
328}
329
330/**
331    `#[cgp_auto_getter]` is used on a regular getter Rust trait without turnning it
332    into a CGP component. Instead, a blanket implementation is derived directly on
333    that trait.
334
335    This macro can only be used on traits that contains only getter-like methods.
336
337    This macro is a simplified version of [`#[cgp_getter]`](macro@cgp_getter) that does
338    not require explicit implementation or wiring. Instead, the trait would have a blanket
339    implementation that is implemented only if the context implements `HasField` with the
340    field having the exact same name as the getter methods.
341
342    This macro serves as a convenient alternative, so that whenever there is a need to
343    use the `HasField` trait directly, one can instead define a getter trait that is
344    applied with `#[cgp_auto_getter]`.
345
346    This can significantly improve developer experience, as the `HasField` trait can be
347    confusing to new users, who may not be familiar with how the field tag being used
348    as a type-level string instead of regular values.
349
350    ## Example
351
352    Given the following getter trait definition:
353
354    ```rust,ignore
355    #[cgp_auto_getter]
356    pub trait HasName {
357        fn name(&self) -> &str;
358    }
359    ```
360
361    The trait will always be implemented for any struct that derives `HasField` with
362    a `name` field of type `String`, without requiring further wiring. For example:
363
364    ```rust,ignore
365    #[derive(HasField)]
366    struct Person {
367        name: String,
368    }
369    ```
370
371    or:
372
373    ```rust,ignore
374    #[derive(HasField)]
375    struct Person {
376        name: String,
377        age: u8,
378    }
379    ```
380*/
381#[proc_macro_attribute]
382pub fn cgp_auto_getter(attr: TokenStream, item: TokenStream) -> TokenStream {
383    cgp_macro_lib::cgp_auto_getter(attr.into(), item.into())
384        .unwrap_or_else(syn::Error::into_compile_error)
385        .into()
386}
387
388/**
389    The `delegate_components!` macro is used to define wiring of CGP components
390    on a provider type.
391
392    ## Type-Level Maps
393
394    Conceptually, we can think of the use of `delegate_components!` as defining a
395    type-level map, with the keys and values being types. When the keys are the
396    CGP component name types and the values are the CGP providers, then
397    `delegate_components!` is effectively implementing the specified providers
398    on the target type by delegating them to the providers specified in the
399    type-level map.
400
401    The macro is implemented by having the target type implement the `DelegateComponent`
402    trait, with the key used in the `Name` parameter and the value being set as the
403    `Delegate` associated type.
404
405    Additionally, for each key/value entry, the macro also generates implementation for
406    the `IsProviderFor` trait, which would be used during provider trait implementation
407    to propagate any unsatisfied constraints error to be shown to the user.
408
409    ## Basic Syntax
410
411    In its most basic form, the macro can be used by specifying a list of key/value pairs
412    as follows:
413
414    ```rust,ignore
415    delegate_components! {
416        MyComponents {
417            KeyA: ValueA,
418            KeyB: ValueB,
419            ...
420        }
421    }
422    ```
423
424    This would turn the target type into a type-level map, which would contain the entries
425    `KeyA` -> `ValueA`, `KeyB` -> `ValueB`, etc. For each `Key` and `Value`, the macro
426    would generate the following implementation:
427
428    ```rust,ignore
429    impl DelegateComponent<Key> for MyComponents
430    {
431        type Delegate = Value;
432    }
433
434    impl<Context, Params> IsProviderFor<Key, Context, Params> for Value
435    where
436        Value: IsProviderFor<Key, Context, Params>,
437    {
438    }
439    ```
440
441    ## Grouping Keys
442
443    The macro also supports grouping multiple keys together using the list syntax,
444    when the grouped keys all map to the same value. This is useful when we want to
445    delegate multiple CGP components to the same target provider.
446
447    For example, given the following:
448
449    ```rust,ignore
450    delegate_components! {
451        MyComponents {
452            [
453                KeyA,
454                KeyB,
455                ...
456            ]:
457                Value,
458        }
459    }
460    ```
461
462    It would be equivalent to the following:
463
464    ```rust,ignore
465    delegate_components! {
466        MyComponents {
467            KeyA: Value,
468            KeyB: Value,
469            ...
470        }
471    }
472    ```
473
474    ## Generating Mapping Struct
475
476    By default, mapping types like `MyComponents` would be defined outside of `delegate_components!`
477    as a dummy struct, or generated through other macros such as `#[cgp_context]`. However,
478    `delegate_components!` also accepts an optional `new` keyword in front of the map type,
479    in which it would also generate the struct definition for the mapping type.
480
481    For example, given the following:
482
483    ```rust,ignore
484    delegate_components! {
485        new MyComponents {
486            KeyA: ValueA,
487            KeyB: ValueB,
488            ...
489        }
490    }
491    ```
492
493    The macro would also generate the `MyComponents` struct as follows:
494
495    ```rust,ignore
496    pub struct MyComponents;
497    ```
498
499    ## Inner Maps
500
501    When defining component wiring that involves inner maps, such as with the use of
502    `UseDelegate`, `delegate_components!` also supports defining the inner map type
503    as well as the definition of inner key/value pairs all within the same macro invocation.
504
505    For example, given the following:
506
507    ```rust,ignore
508    delegate_components! {
509        MyComponents {
510            OuterKey: UseDelegate<new InnerMap {
511                InnerKeyA: InnerValueA,
512                InnerKeyB: InnerValueB,
513                ...
514            }>,
515        }
516    }
517    ```
518
519    It would be the same as writing two separate calls to `delegate_components!` as follows:
520
521    ```rust,ignore
522    delegate_components! {
523        MyComponents {
524            OuterKey: UseDelegate<InnerMap>,
525        }
526    }
527
528    delegate_components! {
529        new InnerMap {
530            InnerKeyA: InnerValueA,
531            InnerKeyB: InnerValueB,
532            ...
533        }
534    }
535    ```
536*/
537#[proc_macro]
538pub fn delegate_components(body: TokenStream) -> TokenStream {
539    cgp_macro_lib::delegate_components(body.into())
540        .unwrap_or_else(syn::Error::into_compile_error)
541        .into()
542}
543
544/**
545   The `check_components!` macro allows users to write compile-time tests to check
546   for the correctness of component wiring for a CGP context.
547
548   ## Example
549
550   Given the following:
551
552   ```rust,ignore
553   check_components! {
554       CanUsePerson for Person {
555           GreeterComponent,
556       }
557   }
558   ```
559
560
561   The code above generates a *check trait* called `CanUsePerson`, which verifies
562   whether the `Person` context implements the consumer trait for
563   `GreeterComponent` (i.e., `CanGreet`):
564
565   ```rust,ignore
566   trait CanUsePerson<Component, Params>: CanUseComponent<Component, Params> {}
567
568   impl CanUsePerson<GreeterComponent, ()> for Person {}
569   ```
570*/
571#[proc_macro]
572pub fn check_components(body: TokenStream) -> TokenStream {
573    cgp_macro_lib::check_components(body.into())
574        .unwrap_or_else(syn::Error::into_compile_error)
575        .into()
576}
577
578/**
579   The `delegate_and_check_components!` macro combines both `delegate_components!`
580   and `check_components!`, allowing both delegation and checks within a single
581   macro call.
582
583   This is useful for the majority of simple cases, providing immediate feedback on
584   whether the wiring works as intended.
585
586   ## Example
587
588   Given the following code:
589
590   ```rust,ignore
591   delegate_and_check_components! {
592       CanUsePerson for Person;
593       PersonComponents {
594           GreeterComponent: GreetHello,
595       }
596   }
597   ```
598
599   is equivalent to writing the two separate macro calls:
600
601   ```rust,ignore
602   delegate_components! {
603       PersonComponents {
604           GreeterComponent: GreetHello,
605       }
606   }
607
608   check_components! {
609       CanUsePerson for Person {
610           GreeterComponent,
611       }
612   }
613   ```
614
615   In more advanced cases, it may still be necessary to call `delegate_components!`
616   and `check_components` separately. This applies to cases where the CGP traits
617   contain additional generic parameters, or when presets are used.
618*/
619#[proc_macro]
620pub fn delegate_and_check_components(body: TokenStream) -> TokenStream {
621    cgp_macro_lib::delegate_and_check_components(body.into())
622        .unwrap_or_else(syn::Error::into_compile_error)
623        .into()
624}
625
626/**
627    CGP presets are made of extensible collection of key/value mappings, that can be inherited
628    to form new mappings.
629
630    Instead of defining regular structs and build mappings with `delegate_components!`,
631    presets are constructed as _modules_ using the `cgp_preset!` macro together with the
632    `#[re_export_imports]`. For example, the same mappings earlier would be rewritten as:
633
634    ```rust,ignore
635    #[cgp::re_export_imports]
636    mod preset {
637        use crate_a::{KeyA, ...};
638        use crate_b::{ValueA, ...};
639
640        cgp_preset! {
641            PresetA {
642                KeyA: ValueA,
643                KeyB: ValueB,
644                KeyC: ValueC1,
645            }
646        }
647    }
648    ```
649
650    The `#[cgp::re_export_imports]` macro is used over a surrogate `mod preset`, which wraps
651    around the inner module to re-export the imports, so that they can be reused during the
652    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.
653
654    The macro `cgp_preset!` works similar to `delegate_components!`, but it defines a new
655    _inner module_ that contains the mapping struct, together with macros and re-exports to
656    support the merging operation.
657
658    Similarly, the second preset would be re-written as:
659
660    ```rust,ignore
661    #[cgp::re_export_imports]
662    mod preset {
663        use crate_c::{KeyC, ...};
664        use crate_d::{ValueD, ...};
665
666        cgp_preset! {
667            PresetB {
668                KeyC: ValueC2,
669                KeyD: ValueD,
670                KeyE: ValueE,
671            }
672        }
673    }
674    ```
675
676    To merge the two presets, we can define a new `PresetC` that _inherits_ from both `PresetA`
677    and `PresetB`, like follows:
678
679    ```rust,ignore
680    #[cgp::re_export_imports]
681    mod preset {
682        use preset_a::PresetA;
683        use preset_b::PresetB;
684        use crate_f::{KeyF, ...};
685
686        cgp_preset! {
687            PresetC: PresetA + PresetB {
688                override KeyC: ValueC2,
689                KeyF: ValueF,
690            }
691        }
692    }
693    ```
694
695    As we can see, CGP supports *multiple inheritance* for presets by using macros to "copy"
696    over the entries from the parent preset. To resolve conflicts or override entries from
697    the parent presets, the `override` keyword can be used to exclude a given mapping from
698    being copied over and instead use the local definition. And since the underlying
699    implementation still uses `DelegateComponent` to implement the lookup, any non-overridden
700    conflicts would simply result in a trait error due to overlapping instances, thus preventing
701    the diamond inheritance dillema.
702*/
703#[proc_macro]
704pub fn cgp_preset(body: TokenStream) -> TokenStream {
705    cgp_macro_lib::define_preset(body.into())
706        .unwrap_or_else(syn::Error::into_compile_error)
707        .into()
708}
709
710/**
711    `#[cgp_type]` is an extension to [`#[cgp_component]`](macro@cgp_component) that
712    derives additional constructs for abstract type components.
713
714    This macro can only be used on an abstract type trait that contains a single
715    associated type as its item, and nothing else.
716
717    The macro can be used with no attribute argument, in which case the provider
718    type would be named in the format `{associated_type_name}TypeProvider`.
719
720    In addition to the component constructs generated by `#[cgp_component]`, the macro
721    also generates a provider for `UseType<Type>`, that implements the provider trait
722    using `Type`.
723
724    The macro also generates a type alias for accessing the associated type, with the
725    type alias named in the format `{associated_type_name}Of`.
726
727    For advanced use cases, the macro also generates an implementation of
728    `WithProvider<Provider>`, which implements the provider trait if the given
729    `Provider` implements  `TypeProvider<Context, ComponentName>`.
730
731    ## Example
732
733    Given the following abstract type trait definition:
734
735    ```rust,ignore
736    #[cgp_type]
737    pub trait HasNameType {
738        type Name: Display;
739    }
740    ```
741
742    would be equivalent to the following fully explicit definition:
743
744    ```rust,ignore
745    #[cgp_type {
746        name: NameTypeProviderComponent,
747        provider: NameTypeProvider,
748        context: Context,
749    }]
750    pub trait HasNameType {
751        type Name: Display;
752    }
753    ```
754
755    Which would generate the following constructs:
756
757    ```rust,ignore
758    impl<Context, Type> NameTypeProvider<Context> for UseType<Type>
759    where
760        Type: Display,
761    {
762        type Name = Type;
763    }
764
765    type NameOf<Context> = <Context as HasNameType>::Name;
766
767    impl<Context, Provider> HasNameType<Context> for WithProvider<Provider>
768    where
769        Provider: TypeProvider<Context, NameTypeProviderComponent>,
770        Provider::Type: Display,
771    {
772        type Name = Provider::Type;
773    }
774    ```
775*/
776#[proc_macro_attribute]
777pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> TokenStream {
778    cgp_macro_lib::cgp_type(attrs.into(), body.into())
779        .unwrap_or_else(syn::Error::into_compile_error)
780        .into()
781}
782
783/**
784    The macro also allows the context provider to inherit its component mappings
785    from a specified preset.
786
787    The context would implement `DelegateComponent` for all keys in the
788    preset, with the `Delegate` target pointing to `Preset::Provider`. This is
789    done through the `IsPreset` trait generated from the [`cgp_preset!`] macro.
790
791    For example, given the following definition:
792
793    ```rust,ignore
794    #[cgp_inherit(MyPreset)]
795    pub struct MyApp {
796        name: String,
797    }
798    ```
799
800    The following blanket implementation would be generated:
801
802    ```rust,ignore
803    impl<Name> DelegateComponent<Name> for MyApp
804    where
805        Self: MyPreset::IsPreset<Name>,
806    {
807        type Delegate = MyPreset::Provider;
808    }
809    ```
810*/
811#[proc_macro_attribute]
812pub fn cgp_inherit(attr: TokenStream, item: TokenStream) -> TokenStream {
813    cgp_macro_lib::cgp_inherit(attr.into(), item.into())
814        .unwrap_or_else(syn::Error::into_compile_error)
815        .into()
816}
817
818/**
819   The `#[blanket_trait]` macro can be used to define trait aliases that contain
820   empty body and trivial blanket implementations.
821
822   Developers can use the `#[blanket_trait]` macro to define trait aliases,
823   as well as abstract type aliases for more advanced cases.
824
825   ## Example
826
827   Given the following:
828
829   ```rust,ignore
830   #[trait_alias]
831   pub trait HasErrorType: Async + HasErrorType<Error: Async> {}
832   ```
833
834   automatically generates the following blanket implementation:
835
836   ```rust,ignore
837   impl<Context> HasErrorType for Context
838   where
839       Context: Async + HasErrorType<Error: Async> {}
840   ```
841*/
842#[proc_macro_attribute]
843pub fn blanket_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
844    cgp_macro_lib::blanket_trait(attr.into(), item.into())
845        .unwrap_or_else(syn::Error::into_compile_error)
846        .into()
847}
848
849#[proc_macro_attribute]
850pub fn re_export_imports(attrs: TokenStream, body: TokenStream) -> TokenStream {
851    cgp_macro_lib::re_export_imports(attrs.into(), body.into())
852        .unwrap_or_else(syn::Error::into_compile_error)
853        .into()
854}
855
856#[proc_macro]
857pub fn replace_with(body: TokenStream) -> TokenStream {
858    cgp_macro_lib::replace_with(body.into())
859        .unwrap_or_else(syn::Error::into_compile_error)
860        .into()
861}
862
863/**
864    The `Symbol!` macro is used to create a type-level string through the string literal
865    given to the macro.
866
867    The macro constructs the type-level string through a chain of `Char` types and
868    terminated with the `Nil` type. In other words, it constructs a type-level list
869    of characters to represent them as a type-level string.
870
871    Read more about type-level strings in the documentation for `Char`.
872
873    ## Example
874
875    Given the following symbol definition:
876
877    ```rust,ignore
878    type Hello = Symbol!("hello");
879    ```
880
881    The following type would be generated:
882
883    ```rust,ignore
884    type Hello = Char<'h', Char<'e', Char<'l', Char<'l', Char<'o', Nil>>>>>;
885    ```
886
887    which would be shown with the shortened representation as:
888
889    ```rust,ignore
890    type Hello = ζ<'h', ζ<'e', ζ<'l', ζ<'l', ζ<'o', ε>>>>>;
891    ```
892*/
893#[proc_macro]
894#[allow(non_snake_case)]
895pub fn Symbol(body: TokenStream) -> TokenStream {
896    cgp_macro_lib::make_symbol(body.into()).into()
897}
898
899/**
900    The `Product!` macro is used to define a type-level list of types, a.k.a. a product type.
901
902    Given a list of types to the macro, it would generate a chain of `Cons` types
903    for each type in the list, and terminated with the `Nil` type.
904
905    Read more about product types in the documentation for `Cons`.
906
907    ## Example
908
909    Given the following product type definition:
910
911    ```rust,ignore
912    type MyTypes = Product![u32, String, bool];
913    ```
914
915    The following type would be generated:
916
917    ```rust,ignore
918    type MyTypes = Cons<u32, Cons<String, Cons<bool, Nil>>>;
919    ```
920
921    which would be shown with the shortened representation as:
922
923    ```rust,ignore
924    type MyTypes = π<u32, π<String, π<bool, ε>>>;
925    ```
926*/
927#[proc_macro]
928#[allow(non_snake_case)]
929pub fn Product(body: TokenStream) -> TokenStream {
930    cgp_macro_lib::make_product_type(body.into()).into()
931}
932
933/**
934   The `Sum!` macro is used to define a sum type, with the given list of types
935   as disjoint variants.
936
937   Given a list of types to the macro, it would generate a chain of `Either` types
938   for each type in the list, and terminated with the `Void` type.
939
940   Read more about sum types in the documentation for `Either`.
941
942   ## Example
943
944   Given the following sum type definition:
945
946   ```rust,ignore
947   type MyUnion = Sum![u32, String, bool];
948   ```
949
950   The following type would be generated:
951
952   ```rust,ignore
953   type MyUnion = Either<u32, Either<String, Either<bool, Void>>>;
954   ```
955
956   which would be shown with the shortened representation as:
957
958   ```rust,ignore
959   type MyUnion = σ<u32, σ<String, σ<bool, θ>>>;
960   ```
961*/
962#[proc_macro]
963#[allow(non_snake_case)]
964pub fn Sum(body: TokenStream) -> TokenStream {
965    cgp_macro_lib::make_sum_type(body.into()).into()
966}
967
968#[proc_macro]
969pub fn product(body: TokenStream) -> TokenStream {
970    cgp_macro_lib::make_product_expr(body.into()).into()
971}
972
973#[proc_macro_derive(HasField)]
974pub fn derive_fields(item: TokenStream) -> TokenStream {
975    cgp_macro_lib::derive_has_field(item.into()).into()
976}
977
978#[proc_macro_derive(HasFields)]
979pub fn derive_has_fields(item: TokenStream) -> TokenStream {
980    cgp_macro_lib::derive_has_fields(item.into())
981        .unwrap_or_else(syn::Error::into_compile_error)
982        .into()
983}
984
985#[proc_macro_derive(BuildField)]
986pub fn derive_builder(item: TokenStream) -> TokenStream {
987    cgp_macro_lib::derive_build_field(item.into())
988        .unwrap_or_else(syn::Error::into_compile_error)
989        .into()
990}
991
992#[proc_macro_derive(ExtractField)]
993pub fn derive_extractor(item: TokenStream) -> TokenStream {
994    cgp_macro_lib::derive_extract_field(item.into())
995        .unwrap_or_else(syn::Error::into_compile_error)
996        .into()
997}
998
999#[proc_macro_derive(FromVariant)]
1000pub fn derive_from_variant(item: TokenStream) -> TokenStream {
1001    cgp_macro_lib::derive_from_variant(item.into())
1002        .unwrap_or_else(syn::Error::into_compile_error)
1003        .into()
1004}
1005
1006#[proc_macro_derive(CgpVariant)]
1007pub fn derive_cgp_variant(item: TokenStream) -> TokenStream {
1008    cgp_macro_lib::derive_cgp_variant(item.into())
1009        .unwrap_or_else(syn::Error::into_compile_error)
1010        .into()
1011}
1012
1013#[proc_macro_derive(CgpRecord)]
1014pub fn derive_cgp_record(item: TokenStream) -> TokenStream {
1015    cgp_macro_lib::derive_cgp_record(item.into())
1016        .unwrap_or_else(syn::Error::into_compile_error)
1017        .into()
1018}
1019
1020#[proc_macro_derive(CgpData)]
1021pub fn derive_cgp_data(item: TokenStream) -> TokenStream {
1022    cgp_macro_lib::derive_cgp_data(item.into())
1023        .unwrap_or_else(syn::Error::into_compile_error)
1024        .into()
1025}