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}