Skip to main content

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(impl_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/// Supports setting bounds with `#[saturating_add(bound = "T: SomeTrait")]`
208///
209/// # Example
210///
211/// ```rust
212/// #[derive(SaturatingAdd)]
213/// struct MyStruct(usize);
214/// ```
215///
216/// adds
217///
218/// ```rust
219/// impl num::traits::SaturatingAdd for MyStruct {
220///     fn saturating_add(&self, v: &Self) -> Self {
221///         Self(self.0.saturating_add(&v.0))
222///     }
223/// }
224/// ```
225#[proc_macro_derive(SaturatingAdd, attributes(saturating_add))]
226pub fn saturating_add(input_token_stream: TokenStream) -> TokenStream {
227    Basic::derive(
228        input_token_stream,
229        "::num::traits::SaturatingAdd",
230        "saturating_add",
231        "Self",
232        "saturating_add",
233    )
234}
235
236/// Implements `num::traits::SaturatingSub` for a struct by delegating to each field.
237/// Supports setting bounds with `#[saturating_sub(bound = "T: SomeTrait")]`
238///
239/// # Example
240///
241/// ```rust
242/// #[derive(SaturatingSub)]
243/// struct MyStruct(usize);
244/// ```
245///
246/// adds
247///
248/// ```rust
249/// impl num::traits::SaturatingSub for MyStruct {
250///     fn saturating_sub(&self, v: &Self) -> Self {
251///         Self(self.0.saturating_sub(&v.0))
252///     }
253/// }
254/// ```
255#[proc_macro_derive(SaturatingSub, attributes(saturating_sub))]
256pub fn saturating_sub(input_token_stream: TokenStream) -> TokenStream {
257    Basic::derive(
258        input_token_stream,
259        "::num::traits::SaturatingSub",
260        "saturating_sub",
261        "Self",
262        "saturating_sub",
263    )
264}
265
266/// Implements `mkutils::SaturatingAddSigned` for a struct by delegating to each field.
267/// Supports setting bounds with `#[saturating_add_signed(bound = "T: SomeTrait")]`
268///
269/// # Example
270///
271/// ```rust
272/// #[derive(SaturatingAddSigned)]
273/// #[saturating_add_signed(assoc(type Signed = usize))]
274/// struct MyStruct(usize);
275/// ```
276///
277/// adds
278///
279/// ```rust
280/// impl mkutils::SaturatingAddSigned for MyStruct {
281///     type Signed = usize;
282///
283///     fn saturating_add_signed(&self, v: &Self::Signed) -> Self {
284///         Self(self.0.saturating_add_signed(&v.0))
285///     }
286/// }
287/// ```
288#[proc_macro_derive(SaturatingAddSigned, attributes(saturating_add_signed))]
289pub fn saturating_add_signed(input_token_stream: TokenStream) -> TokenStream {
290    Basic::derive(
291        input_token_stream,
292        "::mkutils::SaturatingAddSigned", // NOTE-ee355f
293        "saturating_add_signed",
294        "Self::Signed",
295        "saturating_add_signed",
296    )
297}
298
299/// Adds a `new()` constructor that accepts each field as a parameter.
300/// The method is private by default. Use `#[new("pub")]` or `#[new("pub(crate)")]`
301/// to set a custom visibility.
302///
303/// # Example
304///
305/// ```rust
306/// #[derive(Constructor)]
307/// struct MyStruct {
308///     name: String,
309///     count: i32,
310/// }
311/// ```
312///
313/// adds
314///
315/// ```rust
316/// impl MyStruct {
317///     fn new(name: String, count: i32) -> Self {
318///         Self { name, count }
319///     }
320/// }
321/// ```
322///
323/// With a visibility attribute:
324///
325/// ```rust
326/// #[derive(Constructor)]
327/// #[new(pub(crate))]
328/// struct MyStruct(usize);
329/// ```
330///
331/// adds
332///
333/// ```rust
334/// impl MyStruct {
335///     pub(crate) fn new(_0: usize) -> Self {
336///         Self(_0)
337///     }
338/// }
339/// ```
340#[proc_macro_derive(Constructor, attributes(new))]
341pub fn constructor(input_token_stream: TokenStream) -> TokenStream {
342    Constructor::derive(input_token_stream)
343}
344
345/// # Example
346///
347/// ```rust
348/// const THREAD_STACK_SIZE = lits::bytes!("8 MiB");
349///
350/// #[mkutils_macros::tokio_main(thread_stack_size = THREAD_STACK_SIZE)]
351/// fn main() {
352///     ...
353/// }
354/// ```
355#[proc_macro_attribute]
356pub fn tokio_main(attr_args_token_stream: TokenStream, item_token_stream: TokenStream) -> TokenStream {
357    crate::tokio_main::tokio_main(attr_args_token_stream, item_token_stream)
358}