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