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
102
103
104
105
106
107
108
use TokenStream;
use ;
/// Generate Builder struct, implementation for Builder struct, Builder trait implementation for Builder struct from provided struct
///
/// - Generated Builder name will be `XXXBuilder`.
/// - use `with_xxx` method to set value.
/// - use build method to get `Option<provided struct>` .
/// - `#[generate_builder(Traits)]` Traits will be derived to Builder struct by `#[derive(Traits)]`
/// - if there is data has not been set, build method returns `None`
/// - generated struct field will be `provided_field_name: Option<provided_field_type>`
///
/// # Examples
/// ```
/// # extern crate patternize;
/// use patternize::builder::generate_builder;
///
/// #[derive(Debug, PartialEq)] // for assert_eq!
/// #[generate_builder(Clone)]
/// struct Example {
/// data1: usize,
/// data2: isize
/// }
///
/// fn main() {
/// let example_builder: ExampleBuilder = ExampleBuilder::new()
/// .with_data1(0);
///
/// assert_eq!(example_builder.clone().build(), None);
///
/// let example: Option<Example> = example_builder.with_data2(-1).build();
///
/// assert_eq!(example, Some(Example { data1: 0, data2: -1 }));
/// }
/// ```
/// # Generation Image
/// ```ignore
/// #[generate_builder(Debug, Clone)]
/// struct Example {
/// data: T
/// ...
/// }
///
/// // after generate
/// #[derive(Debug, Clone)]
/// struct ExampleBuilder {
/// data: Option<T>
/// ...
/// }
///
/// impl ExampleBuilder {
/// fn new() -> Self;
/// fn build(self) -> Example;
/// fn with_data(self, T) -> Self;
/// ...
/// }
///
/// impl patternize::builder::Builder for ExampleBuilder;
/// ```
/// Generate singleton static variable
///
/// - generated variable name will be `SCREAMING_CAMEL_CASE` of `InputName`
/// - `InputName` must be written in `PascalCase`
/// - `#[generate_singleton]` will generate `std::sync::OnceLock<InputType>`
/// - `#[generate_singleton(expr)` will generate `std::sync::LazyLock<InputType>`
/// - `expr` type must be `InputType`
///
/// # Examples
/// ```
/// # extern crate patternize;
/// use patternize::singleton::generate_singleton;
///
/// #[derive(Debug, PartialEq)]
/// #[generate_singleton]
/// struct SampleSingleton {
/// data: std::string::String
/// }
///
/// #[derive(Debug, PartialEq)]
/// #[generate_singleton(SampleSingleton2 { data: "sample".to_string() })]
/// struct SampleSingleton2 {
/// data: std::string::String
/// }
///
/// fn main(){
/// // SAMPLE_SINGLETON: std::sync::OnceLock<SampleSingleton>
/// SAMPLE_SINGLETON.set(SampleSingleton {data: "sample".to_string()});
///
/// assert_eq!(SAMPLE_SINGLETON.get(), Some(&SampleSingleton { data: "sample".to_string() }));
///
/// // SAMPLE_SINGLETON2: std::sync::LazyLock<SampleSingleton2>
///
/// assert_eq!(&*SAMPLE_SINGLETON2, &SampleSingleton2 { data: "sample".to_string() });
/// }
/// ```