1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use quote;
use TokenStream;
use cratecomposite_type_impl;
use crateTypeInput;
use crateprocess_input;
/// # compose_type!
/// Compose types from other types in Rust similar to [Typescript](https://www.typescriptlang.org/docs/handbook/2/types-from-types.html)!
/// Here is a quick example!
/// ```rust
/// # use proc_macro_def::{compose_type};
/// struct FieldType {}
///
/// compose_type! {
///
/// struct Example {
/// field: Option<FieldType>
/// }
/// struct MyStruct = Required(Example);
/// struct MyStruct2 = Optional(MyStruct);
/// pub struct MyStruct3 = Required(MyStruct);
/// }
///
/// struct Example2 {
/// field: Option<MyStruct>
/// }
///
/// ```
/// Here are a few points from the above example:
/// 1. You can reference types defined outside of `compose_type` like `FieldType`.
/// 2. You can reference types defined inside of `compose_type` like `MyStruct` outside of the macro
/// invocation.
/// 3. You can expose types outside of the current module, defined inside of `compose_type` by using
/// the `pub` keyword.
///
/// You can find the full feature set below!
///
/// ## Type Alias
/// You can rename types within the scope of the macro invocation. This can be useful when you
/// want to rename the type based on context.
/// ```rust
/// # use proc_macro_def::{compose_type};
/// compose_type! {
///
/// struct Example {
/// field: Option<FieldType>
/// }
/// pub struct MyStruct = Example;
/// }
///
/// const EXAMPLE: MyStruct = MyStruct {
/// field: None
/// };
/// ```
///
/// ## Type Functions
/// ### Optional
/// You can wrap a type in `Option` by using the `Optional` type function.
/// ```rust
/// # use proc_macro_def::{compose_type};
/// struct FieldType {}
/// compose_type! {
/// struct Example {
/// field: FieldType
/// }
///
/// struct MyStruct = Optional(Example);
/// }
///
/// const EXAMPLE: MyStruct = MyStruct {
/// field: None
/// };
///
/// ```
/// ### Required
/// You can unwrap a type from `Option` by using the `Required` type function.
/// ```rust
/// # use proc_macro_def::{compose_type};
/// struct FieldType {}
/// compose_type! {
/// struct Example {
/// pub field: Option<FieldType>
/// }
/// struct MyStruct = Required(Example);
/// }
///
/// const EXAMPLE: MyStruct = MyStruct {
/// field: FieldType {}
/// };
/// ```