mkutils_macros/lib.rs
1mod basic;
2mod const_assoc;
3mod constructor;
4mod context;
5mod default;
6mod error;
7mod from_chain;
8mod set_variant;
9mod toggle;
10mod tokio_main;
11mod type_assoc;
12mod utils;
13
14use crate::{
15 basic::Basic, const_assoc::ConstAssoc, constructor::Constructor, default::Default, from_chain::FromChain,
16 set_variant::SetVariant, toggle::Toggle, type_assoc::TypeAssoc,
17};
18use proc_macro::TokenStream;
19
20// TODO: add documentation
21#[proc_macro_attribute]
22pub fn context(attr_args_token_stream: TokenStream, input_token_stream: TokenStream) -> TokenStream {
23 crate::context::context(attr_args_token_stream, input_token_stream)
24}
25
26/// Implement `::std::convert::From` through a chain of intermediate types.
27///
28///
29/// # Example
30///
31/// ```rust
32/// #[derive(FromChain)]
33/// #[from_chain(Foo, Bar, Baz)]
34/// struct MyStruct;
35/// ```
36///
37/// adds
38///
39/// ```rust
40/// impl From<Foo> for MyStruct {
41/// fn from(foo: Foo) -> Self {
42/// Self::from(Baz::from(Bar::from(foo)))
43/// }
44/// }
45/// ```
46#[proc_macro_derive(FromChain, attributes(from_chain))]
47pub fn from_chain(input_token_stream: TokenStream) -> TokenStream {
48 FromChain::derive(input_token_stream)
49}
50
51/// Implements traits that only have associated types.
52///
53///
54/// # Example
55///
56/// ```rust
57/// #[derive(TypeAssoc)]
58/// #[type_assoc(trait = Foo, Item = Vec<u8>)]
59/// struct MyStruct;
60/// ```
61///
62/// adds
63///
64/// ```rust
65/// impl Foo for MyStruct {
66/// type Item = Vec<u8>;
67/// }
68/// ```
69#[proc_macro_derive(TypeAssoc, attributes(type_assoc))]
70pub fn type_assoc(input_token_stream: TokenStream) -> TokenStream {
71 TypeAssoc::derive(input_token_stream)
72}
73
74/// Adds associated constants to a type via an inherent impl block.
75///
76///
77/// # Example
78///
79/// ```rust
80/// #[derive(ConstAssoc)]
81/// #[const_assoc(pub MAX_SIZE: usize = 1024)]
82/// #[const_assoc(DEFAULT_NAME: &str = "unnamed")]
83/// struct MyStruct;
84/// ```
85///
86/// adds
87///
88/// ```rust
89/// impl MyStruct {
90/// pub const MAX_SIZE: usize = 1024;
91/// const DEFAULT_NAME: &str = "unnamed";
92/// }
93/// ```
94#[proc_macro_derive(ConstAssoc, attributes(const_assoc))]
95pub fn const_assoc(input_token_stream: TokenStream) -> TokenStream {
96 ConstAssoc::derive(input_token_stream)
97}
98
99/// Implements `Default` for a struct, using `Default::default()` for each field
100/// unless a `#[default(...)]` attribute provides a custom expression.
101///
102///
103/// # Example
104///
105/// ```rust
106/// #[derive(Default)]
107/// struct MyStruct {
108/// name: String,
109/// #[default(42)]
110/// count: i32,
111/// #[default(vec![1, 2, 3])]
112/// items: Vec<i32>,
113/// }
114/// ```
115///
116/// adds
117///
118/// ```rust
119/// impl Default for MyStruct {
120/// fn default() -> Self {
121/// Self {
122/// name: ::core::default::Default::default(),
123/// count: 42,
124/// items: vec![1, 2, 3],
125/// }
126/// }
127/// }
128/// ```
129#[proc_macro_derive(Default, attributes(default))]
130pub fn default(input_token_stream: TokenStream) -> TokenStream {
131 Default::derive(input_token_stream)
132}
133
134/// Adds `set_*()` methods for each unit variant on the given enum.
135///
136/// # Example
137///
138/// ```rust
139/// #[derive(SetVariant)]
140/// enum MyEnum {
141/// Foo,
142/// Bar,
143/// Baz(String),
144/// }
145/// ```
146///
147/// adds
148///
149/// ```rust
150/// impl MyEnum {
151/// pub fn set_foo(&mut self) -> &mut Self {
152/// *self = Self::Foo;
153///
154/// self
155/// }
156///
157/// pub fn set_bar(&mut self) -> &mut Self {
158/// *self = Self::Bar;
159///
160/// self
161/// }
162/// }
163/// ```
164#[proc_macro_derive(SetVariant)]
165pub fn set_variant(input_token_stream: TokenStream) -> TokenStream {
166 SetVariant::derive(input_token_stream)
167}
168
169/// Adds a `toggled()` method that maps each enum variant to the next unit variant.
170///
171/// # Example
172///
173/// ```rust
174/// #[derive(Toggle)]
175/// enum MyEnum {
176/// Foo,
177/// Bar,
178/// Baz(String),
179/// }
180/// ```
181///
182/// adds
183///
184/// ```rust
185/// impl MyEnum {
186/// pub fn toggle(&self) -> Self {
187/// match self {
188/// Self::Foo => Self::Bar,
189/// Self::Bar => Self::Foo,
190/// Self::Baz(_string) => Self::Foo,
191/// }
192/// }
193///
194/// pub fn toggle(&mut self) -> &mut Self {
195/// *self = self.toggled();
196///
197/// self
198/// }
199/// }
200/// ```
201#[proc_macro_derive(Toggle)]
202pub fn toggle(input_token_stream: TokenStream) -> TokenStream {
203 Toggle::derive(input_token_stream)
204}
205
206/// Implements `num::traits::SaturatingAdd` for a struct by delegating to each field.
207///
208/// # Example
209///
210/// ```rust
211/// #[derive(SaturatingAdd)]
212/// struct MyStruct(usize);
213/// ```
214///
215/// adds
216///
217/// ```rust
218/// impl num::traits::SaturatingAdd for MyStruct {
219/// fn saturating_add(&self, v: &Self) -> Self {
220/// Self(self.0.saturating_add(&v.0))
221/// }
222/// }
223/// ```
224#[proc_macro_derive(SaturatingAdd)]
225pub fn saturating_add(input_token_stream: TokenStream) -> TokenStream {
226 Basic::derive(input_token_stream, "::num::traits::SaturatingAdd", "saturating_add")
227}
228
229/// Implements `num::traits::SaturatingSub` for a struct by delegating to each field.
230///
231/// # Example
232///
233/// ```rust
234/// #[derive(SaturatingSub)]
235/// struct MyStruct(usize);
236/// ```
237///
238/// adds
239///
240/// ```rust
241/// impl num::traits::SaturatingSub for MyStruct {
242/// fn saturating_sub(&self, v: &Self) -> Self {
243/// Self(self.0.saturating_sub(&v.0))
244/// }
245/// }
246/// ```
247#[proc_macro_derive(SaturatingSub)]
248pub fn saturating_sub(input_token_stream: TokenStream) -> TokenStream {
249 Basic::derive(input_token_stream, "::num::traits::SaturatingSub", "saturating_sub")
250}
251
252/// Adds a `new()` constructor that accepts each field as a parameter.
253/// The method is private by default. Use `#[new("pub")]` or `#[new("pub(crate)")]`
254/// to set a custom visibility.
255///
256/// # Example
257///
258/// ```rust
259/// #[derive(Constructor)]
260/// struct MyStruct {
261/// name: String,
262/// count: i32,
263/// }
264/// ```
265///
266/// adds
267///
268/// ```rust
269/// impl MyStruct {
270/// fn new(name: String, count: i32) -> Self {
271/// Self { name, count }
272/// }
273/// }
274/// ```
275///
276/// With a visibility attribute:
277///
278/// ```rust
279/// #[derive(Constructor)]
280/// #[new(pub(crate))]
281/// struct MyStruct(usize);
282/// ```
283///
284/// adds
285///
286/// ```rust
287/// impl MyStruct {
288/// pub(crate) fn new(_0: usize) -> Self {
289/// Self(_0)
290/// }
291/// }
292/// ```
293#[proc_macro_derive(Constructor, attributes(new))]
294pub fn constructor(input_token_stream: TokenStream) -> TokenStream {
295 Constructor::derive(input_token_stream)
296}
297
298/// # Example
299///
300/// ```rust
301/// const THREAD_STACK_SIZE = lits::bytes!("8 MiB");
302///
303/// #[mkutils_macros::tokio_main(thread_stack_size = THREAD_STACK_SIZE)]
304/// fn main() {
305/// ...
306/// }
307/// ```
308#[proc_macro_attribute]
309pub fn tokio_main(attr_args_token_stream: TokenStream, item_token_stream: TokenStream) -> TokenStream {
310 crate::tokio_main::tokio_main(attr_args_token_stream, item_token_stream)
311}