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}