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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
//! # TRL - type reflection library
//!
//! This library provides auto generation of some common methods based on Rust macros
//!
//! All future examples will use this test struct:
//! ```rust,ignore
//! struct User {
//! id: u32,
//! name: String,
//! email: String,
//!
//! // public fields are ignored by default
//! pub phone_number: u64,
//!}
//! ```
//!
//! This library contains 2 types of macros:
//! - Struct level - macros applied to a struct
//! - Field level - macros applied to a single field
//!
//! Both of them have addictional arguments
//!
//! ### Struct level macros
//! Struct level macros are: `getters` and `setters`. They generates getters/setters for all the fields of the struct
//! They have common arguments:
//! - include=[...]
//! - exclude=[...]
//! - pub
//! - prefix=...
//! ###
//! - include=\[...\] - generate getter/setters only for the listed fields.
//! For example:
//! ```rust,ignore
//! #[derive(trl)]
//! #[getters(include=[name, email])]
//! #[setters(include=[name, email])]
//! struct Test {/* ... */}
//! ```
//!
//! Would generate getters/setters for `b` and `c` fields.
//!
//! - exclude=\[...\] - generate getters/setters for all fields except the listed.
//! For example
//!
//! ```rust,ignore
//! #[derive(trl)]
//! #[getters(exclude=[a, b])]
//! #[setters(exclude=[a, b])]
//! struct Test { /* ... */ }
//! ```
//!
//! Would generate getters/setters only for the `c` field.
//!
//! - pub - include public fields.
//! By default public fields are ignored, but you can specify the `pub` argument to generate getters/setters for them too
//!
//! - prefix=... - generates getters/setters with specified prefix.
//! For example
//! ```rust,ignore
//! #[derive(trl)]
//! #[getters(prefix=get_)]
//! #[setters(prefix=set_)]
//! struct Test { /* ... */ }
//! ```
//! Would generate getters:
//! - `get_id()`, `get_name()`
//! and setters:
//! - `set_id()`, `set_name()`
//!
//! Default value for getters is empty string, and for setters is `set_`
//!
//! - option - valid return type of getters for fields of type `&Option` and `&mut Option`
//! The problem:
//! Basically this library generates getters with this pattern:
//! ```rust,ignore
//! pub fn FIELD_NAME(SELF) -> MODIIER FIELD_TYPE {&SELF.FIELD_NAME}
//! ```
//!
//! If the field type is `Option` and the getter return reference or mutable reference,
//! then the return type will be `&Option` of `&mut Option` respectively. But this doesn't make
//! sense and is even unsafe for `&mut Option` - it gives someone the opportunity to change
//! Some() to None which you usually don't want.
//!
//! Solution:
//! `getters` and `get` parameter `option` scans for each field for which the getter will be generated
//! and changes the return type and the body of the corresponding getter so now it return `Option<&T>`
//! or `Option<&mut T>`
//!
//! ### Field level macros
//! Field level macros are `get` and `set`. They generates a getter/setter for a single field.
//! They have common arguments:
//! - name = ... - generate a getter/setter with the specified name
//! - prefix = ... - generate a getter/setter with the specified prefix
//!
//! ### Constructor
//! Constructor is a struct-level macro which generates the default constructor:
//!
//! ```rust,ignore
//! #[derive(trl)]
//! #[constructor]
//! struct Test {/* ... */}
//! ```
//!
//! Would genetate:
//! ```rust,ignore
//! pub fn new(id: u32, name: String, email: String, phone_number: u64) -> Self {
//! Self {
//! id,
//! name,
//! email,
//! phone_number,
//! }
//! }
//! ```
//!
//! - name - generate constructor with specified name
//! - visibility - generate constructor with specified visibility modifier
//!
//! Possible visibilities (must be specified as string literals)
//! - `"pub"` - public visibility
//! - `"pub(path)"` - restricted public visibility (e.g. "pub(crate)", "pub(super)", "pub(in some::module)")
//! - `"private"` - private visibility (not actually a Rust keyword, but used here for convenience)
//!
//! For example this:
//!
//! ```rust,ignore
//! #[derive(trl)]
//! #[constructor(name = new_test, visibility = "pub(crate)")]
//! struct Test { /* ... */ }
//! ```
//!
//! Would generate:
//!
//! ```rust,ignore
//! pub(crate) fn new_test(id: u32, name: String, email: String, phone_number: u64) -> Self {
//! Self {
//! id,
//! name,
//! email,
//! phone_number,
//! }
//! }
//! ```
//!
pub use *;