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}