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