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#[proc_macro_derive(Default, attributes(default))]
150pub fn default_macro_derive(input: TokenStream) -> TokenStream {
151    default::expand(input)
152}
153mod default;
154
155/// Автореализация [`Deref`] и [`DerefMut`](https://doc.rust-lang.org/std/ops/trait.DerefMut.html) для структур.
156///
157/// Макрос поддерживает работу с именованными и неименнованными структурами.
158///
159/// # Реализация с одним неименованным полем
160/// Дефолтная реализация макроса без дополнительных указаний работает только с одним неименованым полем.
161/// При разименовании структуры будет возвращены данные этого поля.
162/// ```
163/// use std_reset_macros::Deref;
164///
165/// #[derive(Deref)]
166/// struct Wrapper(pub Vec<i32>);
167///
168/// let mut wrapper = Wrapper(vec![1, 2, 3]);
169/// assert_eq!(*wrapper, vec![1, 2, 3]);
170/// ```
171/// # Со множеством неименованных полей
172/// Когда появляется несколько полей, макросу необходимо указать конретное поле,
173/// которое будет возвращено после разыменования с помощью атрибута `#[deref]`.
174/// ```
175/// # use std_reset_macros::Deref;
176/// #
177/// #[derive(Deref)]
178/// struct Wrapper(pub Vec<i32>, #[deref] pub String);
179///
180/// let mut wrapper = Wrapper(vec![1, 2, 3], String::from("crab"));
181/// assert_eq!(*wrapper, "crab");
182/// ```
183/// # Со множеством именованных полей
184/// Тоже самое работает и с именованными полями:
185/// ```
186/// # use std_reset_macros::Deref;
187/// #
188/// #[derive(Deref)]
189/// struct Wrapper {
190///     pub first: Vec<i32>,
191///     #[deref]
192///     pub second: String,
193/// }
194///
195/// let mut wrapper = Wrapper {
196///     first: vec![1, 2, 3],
197///     second: String::from("crab"),
198/// };
199/// assert_eq!(*wrapper, "crab");
200/// ```
201
202#[proc_macro_derive(Deref, attributes(deref))]
203pub fn deref_macro_derive(input: TokenStream) -> TokenStream {
204    deref::expand(input)
205}
206mod deref;
207
208/// Автоопределение `set` методов для полей именованых структур.
209///
210/// По умолчанию все поля включены в определение `set_` методов.
211/// Также с помощью атрибутов можно опционально исключать полe из определния `set_` метода,
212/// а также включать.
213/// - Аттрибут `exclude_setter` исключает поле из полей по умолчанию;
214/// - Аттрибут `include_setter` заставляет макрос определять метод `set_` только для полей с этим атрибутом.
215///
216/// # Конфликты атрибутов
217/// - Поле не может иметь одновременно исключающее и включающее поле, они препятсвуют работе друг друга;
218/// - Поле не может быть исключающим, если какое-либо поле до него было определено как включающее, и наоборот.
219///
220/// # Реализация по умолчанию
221/// ```
222/// use std_reset_macros::Setter;
223///
224/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
225/// struct Tmp {
226///     first: i32,
227///     second: i32,
228/// }
229/// let tmp = Tmp::default().set_first(2).set_second(3);
230/// assert_eq!(
231///     tmp,
232///     Tmp {
233///         first: 2,
234///         second: 3
235///     }
236/// );
237/// ```
238///
239/// # Исключающие поля
240///
241/// C помощью атрибута `exclude_setter` можно исключить поле из определения `set_` метода,
242/// таким образом метод будет определен только для дефолтных полей.
243/// ## Пример
244/// ```
245/// # use std_reset_macros::Setter;
246/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
247/// struct Tmp {
248///     first: i32,
249///     #[exclude_setter]
250///     second: i32,
251/// }
252/// # let tmp = Tmp::default().set_first(2);
253/// # assert_eq!(
254/// #     tmp,
255/// #     Tmp {
256/// #         first: 2,
257/// #         second: 0
258/// #     }
259/// # );
260/// ```
261/// -- здесь метод `set_` определен только для поля `first`.
262///
263/// # Включающие поля
264///
265/// Если есть хотябы одно поле с атрибутом `include_setter`, это значит,
266/// что макрос перестает опрделеять методы `set_` для полей по умолчанию,
267/// а начал назначать их для полей с атрибутом `include_setter`.
268/// ## Пример
269/// ```
270/// # use std_reset_macros::Setter;
271/// #[derive(Setter, Clone, Copy, Default, PartialEq, Debug)]
272/// struct Tmp {
273///     #[include_setter]
274///     first: i32,
275///     second: i32,
276///     #[include_setter]    
277///     third: i32
278/// }
279/// # let tmp = Tmp::default().set_first(2).set_third(5);
280/// # assert_eq!(
281/// #     tmp,
282/// #     Tmp {
283/// #         first: 2,
284/// #         second: 0,
285/// #         third: 5
286/// #     }
287/// # );
288/// ```
289/// -- здесь метод `set_` определен только для полей `first` и `third`.
290///
291///
292///
293#[proc_macro_derive(Setter, attributes(exclude_setter, include_setter))]
294pub fn setter_macro_derive(input: TokenStream) -> TokenStream {
295    setter_getter::expand_setter(input)
296}
297mod setter_getter;
298
299/// Автоопределение `get` методов для полей именованых структур.
300/// Тоже самое что и в [`Setter`], но:
301/// - вместо аттрибута `exclude_setter` - `exclude_getter`
302/// - вместо аттрибута `include_setter` - `include_getter`
303/// - вместо `set_` метода - `get_`
304#[proc_macro_derive(Getter, attributes(exclude_getter, include_getter))]
305pub fn getter_macro_derive(input: TokenStream) -> TokenStream {
306    setter_getter::expand_getter(input)
307}
308
309/// Прямая реализация метода `new`.
310///
311/// Макрос поддерживает работу с именованными и неименованными полями.
312///
313/// ## Примеры
314/// ```
315/// use std_reset_macros::New;
316///
317/// #[derive(New)]
318/// struct Tmp(i32);
319///
320/// Tmp::new(2);
321/// ```
322/// ```
323/// # use std_reset_macros::New;
324/// #
325/// #[derive(New)]
326/// struct Tmp<T>(T, i32) where T: Default;
327///
328/// Tmp::new(2, 3);
329/// ```
330/// ```
331/// # use std_reset_macros::New;
332/// #
333/// #[derive(New)]
334/// struct Tmp<T> {
335///     first: i32,
336///     second: T,
337/// }
338///
339/// Tmp::new(2, 3);
340/// ```
341#[proc_macro_derive(New)]
342pub fn new_macro_derive(input: TokenStream) -> TokenStream {
343    new::expand(input)
344}
345mod new;
346
347/// Реализация по умолчанию [`Display`] в качестве [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html#tymethod.fmt).
348///
349/// Струкутура, которая реализует [`Debug`] реализует `Display` по умолчанию, выводя строку формата [`debug::fmt`](https://doc.rust-lang.org/std/fmt/trait.Debug.html#tymethod.fmt).
350///
351/// ## Пример
352/// ```
353/// use std_reset_macros::Display;
354/// use std::fmt::Debug;
355///
356/// #[derive(Display, Debug, Clone, Copy)]
357/// struct Exmpl(i32);
358/// #
359/// # let exmpl = Exmpl(0);
360/// # assert_eq!(format!("{}", exmpl), format!("{:?}", exmpl));
361/// ```
362#[proc_macro_derive(Display)]
363pub fn display(input: TokenStream) -> TokenStream {
364    display::expand(input)
365}
366mod display;
367
368#[proc_macro_attribute]
369pub fn any_type(attr: TokenStream, item: TokenStream) -> TokenStream {
370    any_type::expand(attr, item)
371}
372mod any_type;