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;