utility_types/lib.rs
1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4use proc_macro::TokenStream;
5
6/// [Exclude] macro implementation.
7mod exclude;
8/// [Extract] macro implementation.
9mod extract;
10/// [Omit] macro implementation.
11mod omit;
12/// [Partial] macro implementation.
13mod partial;
14/// [Pick] macro implementation.
15mod pick;
16/// [Required] macro implementation.
17mod required;
18
19/// Utility functions and types.
20mod utils;
21
22/// Constructs a struct with all fields of the original struct set to **optional**.
23///
24/// ## Example
25///
26/// ```
27/// # use utility_types::Partial;
28/// #[derive(Partial)]
29/// #[partial(ident = PartialArticle, derive(Debug))]
30/// pub struct Article {
31/// author: String,
32/// content: String,
33/// liked: usize,
34/// comments: String,
35/// }
36/// ```
37///
38/// The above code will generate the following struct:
39///
40/// ```no_run
41/// #[derive(Debug)]
42/// pub struct PartialArticle {
43/// author: Option<String>,
44/// content: Option<String>,
45/// liked: Option<usize>,
46/// comments: Option<String>,
47/// }
48/// ```
49///
50/// Several trait implementations are also generated:
51/// - `From<Article>` for `PartialArticle`
52/// - `From<PartialArticle>` for `Article`
53///
54/// ## Attributes
55///
56/// ```ignore
57/// #[derive(Partial)]
58/// #[partial(
59/// ident = <IDENT>, // The identifier of the generated struct
60/// [derive(<DERIVE>, ...)], // Derive attributes for the generated struct
61/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated struct
62/// )]
63/// pub struct BasedStruct {
64/// #[partial(
65/// [default = <DEFAULT>], // The default value of the field in the generated From impl
66/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated field
67/// // If given, will override the container level `forward_attrs`
68/// )]
69/// field: FieldType,
70/// }
71/// ```
72#[proc_macro_derive(Partial, attributes(partial))]
73pub fn partial(input: TokenStream) -> TokenStream {
74 partial::partial(input)
75}
76
77/// Constructs a struct with all fields of the original struct set to **required**.
78///
79/// ## Example
80///
81/// ```
82/// # use utility_types::Required;
83/// #[derive(Required)]
84/// #[required(ident = RequiredArticle, derive(Debug))]
85/// pub struct Article {
86/// author: String,
87/// content: Option<String>,
88/// }
89/// ```
90///
91/// The above code will generate the following struct:
92///
93/// ```
94/// #[derive(Debug)]
95/// pub struct RequiredArticle {
96/// author: String,
97/// content: String,
98/// }
99/// ```
100///
101/// ## Attributes
102///
103/// ```ignore
104/// #[derive(Required)]
105/// #[required(
106/// ident = <IDENT>, // The identifier of the generated struct
107/// [derive(<DERIVE>, ...)], // Derive attributes for the generated struct
108/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated struct
109/// )]
110/// pub struct BasedStruct {
111/// #[required(
112/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated field
113/// // If given, will override the container level `forward_attrs`
114/// )]
115/// field: FieldType,
116/// }
117/// ```
118#[proc_macro_derive(Required, attributes(required))]
119pub fn required(input: TokenStream) -> TokenStream {
120 required::required(input)
121}
122
123/// Constructs structs by **picking** the set of fields from the original struct.
124///
125/// ## Example
126///
127/// ```ignore
128/// # use utility_types::Pick;
129/// #[derive(Pick)]
130/// #[pick(
131/// arg(ident = AuthorContent, fields(author, content), derive(Debug)),
132/// arg(ident = LikedComments, fields(liked, comments))
133/// )]
134/// pub struct Article {
135/// author: String,
136/// content: String,
137/// liked: usize,
138/// comments: String,
139/// }
140/// ```
141///
142/// The above code will generate the following structs:
143///
144/// ```
145/// #[derive(Debug)]
146/// pub struct AuthorContent {
147/// author: String,
148/// content: String,
149/// }
150///
151/// pub struct LikedComments {
152/// liked: usize,
153/// comments: String,
154/// }
155/// ```
156///
157/// Several trait implementations are also generated:
158/// - `From<Article>` for `AuthorContent`
159/// - `From<Article>` for `LikedComments`
160///
161/// ## Attributes
162///
163/// ```ignore
164/// # use utility_types::Pick;
165/// #[derive(Pick)]
166/// #[pick(
167/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to all generated structs
168/// arg(
169/// ident = <IDENT>, // The identifier of the generated struct
170/// fields(<FIELD>, ...), // The fields to pick from the original struct
171/// [derive(<DERIVE>, ...)], // Derive attributes for the generated struct
172/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated struct
173/// // If given, will override the container level `forward_attrs`
174/// ), ...
175/// )]
176/// pub struct BasedStruct {
177/// #[pick(
178/// #[forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated field
179/// // If given, will override the container level and arg level `forward_attrs`
180/// )]
181/// field: FieldType,
182/// }
183#[proc_macro_derive(Pick, attributes(pick))]
184pub fn pick(input: TokenStream) -> TokenStream {
185 pick::pick(input)
186}
187
188/// Constructs structs by **omitting** the set of fields from the original struct.
189///
190/// ## Example
191///
192/// ```
193/// # use utility_types::Omit;
194/// #[derive(Omit)]
195/// #[omit(
196/// arg(ident = OmitAuthorContent, fields(author, content), derive(Debug)),
197/// arg(ident = OmitLikedComments, fields(liked, comments))
198/// )]
199/// pub struct Article {
200/// author: String,
201/// content: String,
202/// liked: usize,
203/// comments: String,
204/// }
205/// ```
206///
207/// The above code will generate the following structs:
208///
209/// ```
210/// #[derive(Debug)]
211/// pub struct OmitAuthorContent {
212/// liked: usize,
213/// comments: String,
214/// }
215///
216/// pub struct OmitLikedComments {
217/// author: String,
218/// content: String,
219/// }
220/// ```
221///
222/// Several trait implementations are also generated:
223///
224/// - `From<Article>` for `OmitAuthorContent`
225/// - `From<Article>` for `OmitLikedComments`
226///
227/// ## Attributes
228///
229/// ```ignore
230/// #[derive(Omit)]
231/// #[omit(
232/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to all generated structs
233/// arg(
234/// ident = <IDENT>, // The identifier of the generated struct
235/// fields(<FIELD>, ...), // The fields to omit from the original struct
236/// [derive(<DERIVE>, ...)], // Derive attributes for the generated struct
237/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated struct
238/// // If given, will override the container level `forward_attrs`
239/// ), ...
240/// )]
241/// pub struct BasedStruct {
242/// #[omit(
243/// #[forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated field
244/// // If given, will override the container level and arg level `forward_attrs`
245/// )]
246/// field: FieldType,
247/// }
248/// ```
249#[proc_macro_derive(Omit, attributes(omit))]
250pub fn omit(input: TokenStream) -> TokenStream {
251 omit::omit(input)
252}
253
254/// Constructs enums by **extracting** the set of variants from the original enum.
255///
256/// ## Example
257///
258/// ```
259/// # use utility_types::Extract;
260/// #[derive(Extract)]
261/// #[extract(arg(ident = ExtractMercury, variants(Mercury)))]
262/// pub enum Planet {
263/// Mercury,
264/// Venus,
265/// Earth,
266/// Mars,
267/// }
268/// ```
269///
270/// The above code will generate the following enum:
271///
272/// ```
273/// pub enum ExtractMercury {
274/// Mercury,
275/// }
276/// ```
277///
278/// ## Attributes
279///
280/// ```ignore
281/// #[derive(Extract)]
282/// #[extract(
283/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to all generated enums
284/// arg(
285/// ident = <IDENT>, // The identifier of the generated enum
286/// variants(<VARIANT>, ...), // The variants to extract from the original enum
287/// [derive(<DERIVE>, ...)], // Derive attributes for the generated enum
288/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated enum
289/// // If given, will override the container level `forward_attrs`
290/// ), ...
291/// )]
292/// pub enum BasedEnum {
293/// #[extract(
294/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated variant
295/// // If given, will override the container level and arg level `forward_attrs`
296/// )]
297/// variant: VariantType,
298/// }
299/// ```
300#[proc_macro_derive(Extract, attributes(extract))]
301pub fn extract(input: TokenStream) -> TokenStream {
302 extract::extract(input)
303}
304
305/// Constructs enums by **excluding** the set of variants from the original enum.
306///
307/// ## Example
308///
309/// ```
310/// # use utility_types::Exclude;
311/// #[derive(Exclude)]
312/// #[exclude(arg(ident = ExcludeMercury, variants(Mercury)))]
313/// pub enum Planet {
314/// Mercury,
315/// Venus,
316/// Earth,
317/// Mars,
318/// }
319/// ```
320///
321/// The above code will generate the following enum:
322///
323/// ```
324/// pub enum ExcludeMercury {
325/// Venus,
326/// Earth,
327/// Mars,
328/// }
329/// ```
330///
331/// ## Attributes
332///
333/// ```ignore
334/// #[derive(Exclude)]
335/// #[exclude(
336/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to all generated enums
337/// arg(
338/// ident = <IDENT>, // The identifier of the generated enum
339/// variants(<VARIANT>, ...), // The variants to exclude from the original enum
340/// [derive(<DERIVE>, ...)], // Derive attributes for the generated enum
341/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated enum
342/// // If given, will override the container level `forward_attrs`
343/// ),
344/// )]
345/// pub enum BasedEnum {
346/// #[exclude(
347/// [forward_attrs(<ATTR, ...> | not(<ATTR, ...>))], // Forward specific attributes to the generated variant
348/// // If given, will override the container level and arg level `forward_attrs`
349/// )]
350/// variant: VariantType,
351/// }
352/// ```
353#[proc_macro_derive(Exclude, attributes(exclude))]
354pub fn exclude(input: TokenStream) -> TokenStream {
355 exclude::exclude(input)
356}