std_reset_macros/
lib.rs

1#![allow(unused)]
2
3use macro_functions::{get_segment_from_type, type_from_args};
4use paste::paste;
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{parse_macro_input, Field, Fields, FieldsNamed, FieldsUnnamed, ItemStruct, PathSegment};
8
9/// Реализация трейта [`Default`] с указанием значений по умолчанию для каждого поля структуры.
10///
11/// Макрос поддерживает работу со всеми видами стурктур и перечислений, кроме _zero-variant_ перечислений.
12///
13/// Чтобы указать дефолтное значение поля необходимо использовать атрибут `#[default]` с следующим синтаксисом:
14/// ```
15/// # use std_reset_macros::Default;
16/// # #[derive(Debug, Default, PartialEq)]
17/// # struct Wrap<T>(
18/// #[default(10_i32)]
19/// #   i32,
20/// #   T
21/// # );
22/// ```
23/// -- выражение, которое будет подставляться в поле как его дефолтное значение указывается внутри скобок и описан как строковый литерал.
24///
25/// **P.s.** Выражение описывается строке, потому что`rust` требует
26/// указывать в атрибутах только литералы. Макрос [`Default`] в свою очередь
27/// преобразует [cтроковый лиетрал](https://doc.rust-lang.org/reference/tokens.html?highlight=literal#string-literals) в выржаение.
28///
29/// Например, указать дефолтное значение для поля с типом `&str` можно следующим образом:
30/// ```
31/// # use std_reset_macros::Default;
32/// # #[derive(Debug, Default, PartialEq)]
33/// # struct Wrap(
34/// #[default("crab")]
35/// #   &'static str
36/// # );
37/// ```
38///
39/// # Примеры
40/// ### 1. Структуры
41/// - с _именнованными_ полями:
42///
43///     ```
44///     use std_reset_macros::Default;
45///
46///     #[derive(Debug, Default, PartialEq)]
47///     struct Named {
48///         #[default(String::from("Ferris"))]
49///         first: String,
50///         #[default("Ferris")]
51///         second: &'static str,
52///         #[default(8_9999_999_999)]
53///         third: u128,
54///         fourth: Option<String>,
55///         #[default(Some(32))]
56///         fifth: Option<u32>,
57///     }
58///     assert_eq!(
59///         Named::default(),
60///         Named {
61///             first: "Ferris".to_string(),
62///             second: "Ferris",
63///             third: 8_9999_999_999,
64///             fourth: None,
65///             fifth: Some(32),
66///         }
67///     );
68///     ```
69/// - с _неименнованными_ полями:
70///     ```
71///     # use std_reset_macros::Default;
72///     #
73///     #[derive(Debug, Default, PartialEq)]
74///     struct Unnamed(
75///         #[default(String::from("Ferris"))] String,
76///         #[default("Ferris")] &'static str,
77///         #[default(8_9999_999_999)] u128,
78///         Option<String>,
79///         #[default(Some(32))] Option<u32>,
80///     );
81///     assert_eq!(
82///         Unnamed::default(),
83///         Unnamed(
84///             "Ferris".to_string(),
85///             "Ferris",
86///             8_9999_999_999,
87///             None,
88///             Some(32),
89///         )
90///     );
91///     ```
92/// - _unit-like_ структура:
93///     ```
94///     # use std_reset_macros::Default;
95///     #
96///     #[derive(Debug, Default, PartialEq)]
97///     struct Unit;
98///     assert_eq!(Unit::default(), Unit);
99///     ```
100///
101/// ### 2. Перечисления
102/// - unit-like:
103///     ```
104///     # use std_reset_macros::Default;
105///     #
106///     #[derive(Default, PartialEq, Debug)]
107///     enum Units {
108///         #[default]
109///         One,
110///         Two,
111///     }
112///     assert_eq!(Units::default(), Units::One);
113///     ```
114/// - tuple-like:
115///     ```
116///     # use std_reset_macros::Default;
117///     #
118///     #[derive(Default, PartialEq, Debug)]
119///     enum Unnamed {
120///         #[default]
121///         One(#[default(10)] i32),
122///         Two,
123///     }
124///     assert_eq!(Unnamed::default(), Unnamed::One(10));
125///     ```
126/// - struct-like:
127///     ```
128///     # use std_reset_macros::Default;
129///     #
130///     #[derive(Default, PartialEq, Debug)]
131///     enum Named {
132///         One,
133///         #[default]
134///         Two {
135///             #[default(UnnamedStruct)]
136///             first: UnnamedStruct,
137///         },
138///     }
139///     assert_eq!(
140///         Named::default(),
141///         Named::Two {
142///             first: UnnamedStruct
143///         }
144///     );
145///
146///     #[derive(PartialEq, Debug)]
147///     struct UnnamedStruct;
148///     ```
149///
150/// with `#[ignore]` generic `Default`-trait bound:
151///
152/// - without `#[ignore]`:
153///     ```compile_fail
154///     # use std_reset_macros::Default;
155///     # use std::marker::PhantomData;
156///     #
157///     #[derive(PartialEq, Debug, Default)]
158///     struct Abstract<T>(PhantomData<T>);
159///
160///     struct Inner;
161///
162///     Abstract::<Inner>::default();
163///     ```
164///
165/// - with `#[ignore]`:
166///     ```
167///     # use std_reset_macros::Default;
168///     # use std::marker::PhantomData;
169///     #
170///     #[derive(PartialEq, Debug, Default)]
171///     struct Abstract<#[ignore] T>(PhantomData<T>);
172///
173///     struct Inner;
174///
175///     Abstract::<Inner>::default();
176///     ```
177#[proc_macro_derive(Default, attributes(default))]
178pub fn default_macro_derive(input: TokenStream) -> TokenStream {
179    default::expand(input)
180}
181mod default;
182
183/// Автореализация [`Deref`] и [`DerefMut`](https://doc.rust-lang.org/std/ops/trait.DerefMut.html) для структур.
184///
185/// Макрос поддерживает работу с именованными и неименнованными структурами.
186///
187/// # Реализация с одним неименованным полем
188/// Дефолтная реализация макроса без дополнительных указаний работает только с одним неименованым полем.
189/// При разименовании структуры будет возвращены данные этого поля.
190/// ```
191/// use std_reset_macros::Deref;
192///
193/// #[derive(Deref)]
194/// struct Wrapper(pub Vec<i32>);
195///
196/// let mut wrapper = Wrapper(vec![1, 2, 3]);
197/// assert_eq!(*wrapper, vec![1, 2, 3]);
198/// ```
199/// # Со множеством неименованных полей
200/// Когда появляется несколько полей, макросу необходимо указать конретное поле,
201/// которое будет возвращено после разыменования с помощью атрибута `#[deref]`.
202/// ```
203/// # use std_reset_macros::Deref;
204/// #
205/// #[derive(Deref)]
206/// struct Wrapper(pub Vec<i32>, #[deref] pub String);
207///
208/// let mut wrapper = Wrapper(vec![1, 2, 3], String::from("crab"));
209/// assert_eq!(*wrapper, "crab");
210/// ```
211/// # Со множеством именованных полей
212/// Тоже самое работает и с именованными полями:
213/// ```
214/// # use std_reset_macros::Deref;
215/// #
216/// #[derive(Deref)]
217/// struct Wrapper {
218///     pub first: Vec<i32>,
219///     #[deref]
220///     pub second: String,
221/// }
222///
223/// let mut wrapper = Wrapper {
224///     first: vec![1, 2, 3],
225///     second: String::from("crab"),
226/// };
227/// assert_eq!(*wrapper, "crab");
228/// ```
229
230#[proc_macro_derive(Deref, attributes(deref))]
231pub fn deref_macro_derive(input: TokenStream) -> TokenStream {
232    deref::expand(input)
233}
234mod deref;
235
236/// Автоопределение `set` методов для полей именованых структур.
237///
238/// По умолчанию все поля включены в определение `set_` методов.
239/// Также с помощью атрибутов можно опционально исключать полe из определния `set_` метода,
240/// а также включать.
241/// - Аттрибут `exclude_setter` исключает поле из полей по умолчанию;
242/// - Аттрибут `include_setter` заставляет макрос определять метод `set_` только для полей с этим атрибутом.
243///
244/// # Конфликты атрибутов
245/// - Поле не может иметь одновременно исключающее и включающее поле, они препятсвуют работе друг друга;
246/// - Поле не может быть исключающим, если какое-либо поле до него было определено как включающее, и наоборот.
247///
248/// # Реализация по умолчанию
249/// ```
250/// use std_reset_macros::Setter;
251///
252/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
253/// struct Tmp {
254///     first: i32,
255///     second: i32,
256/// }
257/// let tmp = Tmp::default().set_first(2).set_second(3);
258/// assert_eq!(
259///     tmp,
260///     Tmp {
261///         first: 2,
262///         second: 3
263///     }
264/// );
265/// ```
266///
267/// # Исключающие поля
268///
269/// C помощью атрибута `exclude_setter` можно исключить поле из определения `set_` метода,
270/// таким образом метод будет определен только для дефолтных полей.
271/// ## Пример
272/// ```
273/// # use std_reset_macros::Setter;
274/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
275/// struct Tmp {
276///     first: i32,
277///     #[exclude_setter]
278///     second: i32,
279/// }
280/// # let tmp = Tmp::default().set_first(2);
281/// # assert_eq!(
282/// #     tmp,
283/// #     Tmp {
284/// #         first: 2,
285/// #         second: 0
286/// #     }
287/// # );
288/// ```
289/// -- здесь метод `set_` определен только для поля `first`.
290///
291/// # Включающие поля
292///
293/// Если есть хотябы одно поле с атрибутом `include_setter`, это значит,
294/// что макрос перестает опрделеять методы `set_` для полей по умолчанию,
295/// а начал назначать их для полей с атрибутом `include_setter`.
296/// ## Пример
297/// ```
298/// # use std_reset_macros::Setter;
299/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
300/// struct Tmp {
301///     #[include_setter]
302///     first: i32,
303///     second: i32,
304///     #[include_setter]    
305///     third: i32
306/// }
307/// # let tmp = Tmp::default().set_first(2).set_third(5);
308/// # assert_eq!(
309/// #     tmp,
310/// #     Tmp {
311/// #         first: 2,
312/// #         second: 0,
313/// #         third: 5
314/// #     }
315/// # );
316/// ```
317/// -- здесь метод `set_` определен только для полей `first` и `third`.
318///
319///
320///
321#[proc_macro_derive(Setter, attributes(exclude_setter, include_setter))]
322pub fn setter_macro_derive(input: TokenStream) -> TokenStream {
323    setter_getter::expand_setter(input)
324}
325mod setter_getter;
326
327/// Автоопределение `get` методов для полей именованых структур.
328/// Тоже самое что и в [`Setter`], но:
329/// - вместо аттрибута `exclude_setter` - `exclude_getter`
330/// - вместо аттрибута `include_setter` - `include_getter`
331/// - вместо `set_` метода - `get_`
332#[proc_macro_derive(Getter, attributes(exclude_getter, include_getter))]
333pub fn getter_macro_derive(input: TokenStream) -> TokenStream {
334    setter_getter::expand_getter(input)
335}
336
337/// Прямая реализация метода `new`.
338///
339/// Макрос поддерживает работу с именованными и неименованными полями.
340///
341/// ## Примеры
342/// ```
343/// use std_reset_macros::New;
344///
345/// #[derive(New)]
346/// struct Tmp(i32);
347///
348/// Tmp::new(2);
349/// ```
350/// ```
351/// # use std_reset_macros::New;
352/// #
353/// #[derive(New)]
354/// struct Tmp<T>(T, i32) where T: Default;
355///
356/// Tmp::new(2, 3);
357/// ```
358/// ```
359/// # use std_reset_macros::New;
360/// #
361/// #[derive(New)]
362/// struct Tmp<T> {
363///     first: i32,
364///     second: T,
365/// }
366///
367/// Tmp::new(2, 3);
368/// ```
369#[proc_macro_derive(New)]
370pub fn new_macro_derive(input: TokenStream) -> TokenStream {
371    new::expand(input)
372}
373mod new;
374
375/// Реализация по умолчанию [`Display`] в качестве [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html#tymethod.fmt).
376///
377/// Струкутура, которая реализует [`Debug`] реализует `Display` по умолчанию, выводя строку формата [`debug::fmt`](https://doc.rust-lang.org/std/fmt/trait.Debug.html#tymethod.fmt).
378///
379/// ## Пример
380/// ```
381/// use std_reset_macros::Display;
382/// use std::fmt::Debug;
383///
384/// #[derive(Display, Debug, Clone, Copy)]
385/// struct Exmpl(i32);
386/// #
387/// # let exmpl = Exmpl(0);
388/// # assert_eq!(format!("{}", exmpl), format!("{:?}", exmpl));
389/// ```
390#[proc_macro_derive(Display)]
391pub fn display(input: TokenStream) -> TokenStream {
392    display::expand(input)
393}
394mod display;
395
396#[proc_macro_attribute]
397pub fn any_type(attr: TokenStream, item: TokenStream) -> TokenStream {
398    any_type::expand(attr, item)
399}
400mod any_type;