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}