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