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(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}