lombok_macros/
lib.rs

1//! lombok-macros
2//!
3//! A Rust procedural macro collection providing Lombok-like functionality.
4//! Automatically generates getters/setters with field-level visibility control,
5//! custom Debug implementations with field skipping, and Display trait implementations.
6//! Supports structs, enums, generics and lifetimes.
7
8pub(crate) mod cfg;
9pub(crate) mod func;
10pub(crate) mod generate;
11pub(crate) mod parse;
12pub(crate) mod visibility;
13
14pub(crate) use cfg::*;
15pub(crate) use func::*;
16pub(crate) use generate::*;
17pub(crate) use parse::*;
18pub(crate) use visibility::*;
19
20pub(crate) use proc_macro::TokenStream;
21pub(crate) use proc_macro2::{TokenStream as TokenStream2, TokenTree as TokenTree2};
22pub(crate) use quote::{ToTokens, format_ident, quote};
23pub(crate) use std::{collections::HashMap, str::FromStr};
24pub(crate) use syn::{
25    Data, DeriveInput, Field,
26    GenericParam::{self},
27    Ident, Lifetime,
28    Type::{self},
29    TypeParam, WhereClause, parse_macro_input,
30};
31
32/// This is an example of how to use the `Lombok` procedural macro with `get` attributes.
33///
34/// The `Lombok` procedural macro is used to automatically generate getter methods for struct fields.
35/// The `get` attribute controls the visibility of the generated getter method.
36///
37/// Example:
38///
39/// ```rust
40/// use lombok_macros::*;
41///
42/// #[derive(Getter, Clone)]
43/// struct LombokTest2<'a, 'b, T: Clone> {
44///     #[get(pub(crate))]
45///     list: Vec<String>,
46///     #[get(pub(crate))]
47///     opt_str_lifetime_a: Option<&'a T>,
48///     opt_str_lifetime_b: Option<&'b str>,
49/// }
50/// let list: Vec<String> = vec!["hello".to_string(), "world".to_string()];
51/// let data2: LombokTest2<usize> = LombokTest2 {
52///     list: list.clone(),
53///     opt_str_lifetime_a: None,
54///     opt_str_lifetime_b: None,
55/// };
56/// let get_list: Vec<String> = data2.get_list().clone();
57/// assert_eq!(get_list, list);
58/// ```
59#[proc_macro_derive(Getter, attributes(get))]
60pub fn getter(input: TokenStream) -> TokenStream {
61    inner_lombok_data(input, true, false, false)
62}
63
64/// This is an example of how to use the `Lombok` procedural macro with `get_mut` attributes.
65///
66/// The `Lombok` procedural macro is used to automatically generate mutable getters for struct fields.
67/// The `get_mut` attribute controls the visibility of the mutable getter function.
68///
69/// Example:
70///
71/// ```rust
72/// use lombok_macros::*;
73///
74/// #[derive(GetterMut, Clone)]
75/// struct LombokTest2<'a, 'b, T: Clone> {
76///     #[get_mut(pub(crate))]
77///     list: Vec<String>,
78///     #[get_mut(pub(crate))]
79///     opt_str_lifetime_a: Option<&'a T>,
80///     opt_str_lifetime_b: Option<&'b str>,
81/// }
82/// let list: Vec<String> = vec!["hello".to_string(), "world".to_string()];
83/// let mut data2: LombokTest2<usize> = LombokTest2 {
84///     list: list.clone(),
85///     opt_str_lifetime_a: None,
86///     opt_str_lifetime_b: None,
87/// };
88/// let get_list: Vec<String> = data2.get_mut_list().clone();
89/// assert_eq!(get_list, list);
90/// ```
91#[proc_macro_derive(GetterMut, attributes(get_mut))]
92pub fn getter_mut(input: TokenStream) -> TokenStream {
93    inner_lombok_data(input, false, true, false)
94}
95
96/// This is an example of how to use the `Lombok` procedural macro with `set` attributes.
97///
98/// The `Lombok` procedural macro is used to automatically generate setters for struct fields.
99/// The `set` attribute controls the visibility of the setter function.
100///
101/// Example:
102///
103/// ```rust
104/// use lombok_macros::*;
105///
106/// #[derive(Setter, Debug, Clone)]
107/// struct LombokTest<'a, 'b, T: Clone> {
108///     #[set(pub(crate))]
109///     list: Vec<String>,
110///     opt_str_lifetime_a: Option<&'a T>,
111///     #[set(private)]
112///     opt_str_lifetime_b: Option<&'b str>,
113/// }
114/// let mut data: LombokTest<usize> = LombokTest {
115///     list: Vec::new(),
116///     opt_str_lifetime_a: None,
117///     opt_str_lifetime_b: None,
118/// };
119/// let list: Vec<String> = vec!["hello".to_string(), "world".to_string()];
120/// data.set_list(list.clone());
121/// match data.list {
122///     left_val => {
123///         assert_eq!(*left_val, list);
124///     }
125/// }
126/// ```
127#[proc_macro_derive(Setter, attributes(set))]
128pub fn setter(input: TokenStream) -> TokenStream {
129    inner_lombok_data(input, false, false, true)
130}
131
132/// This is an example of how to use the `Lombok` procedural macro with `get`, `get_mut`, and `set` attributes.
133///
134/// The `Lombok` procedural macro is used to automatically generate getters, mutable getters, and setters for struct fields.
135/// The `get` and `get_mut` attributes control the visibility of the getter functions, while the `set` attribute controls
136/// the visibility of the setter function.
137///
138/// Example:
139///
140/// ```rust
141/// use lombok_macros::*;
142///
143/// #[derive(Data, Debug, Clone)]
144/// struct LombokTest<'a, 'b, T: Clone> {
145///     #[get(pub(crate))]
146///     #[set(pub(crate))]
147///     list: Vec<String>,
148///     #[get(pub(crate))]
149///     opt_str_lifetime_a: Option<&'a T>,
150///     #[set(private)]
151///     opt_str_lifetime_b: Option<&'b str>,
152/// }
153/// let mut data: LombokTest<usize> = LombokTest {
154///     list: Vec::new(),
155///     opt_str_lifetime_a: None,
156///     opt_str_lifetime_b: None,
157/// };
158/// let list: Vec<String> = vec!["hello".to_string(), "world".to_string()];
159/// data.set_list(list.clone());
160/// match data.get_list() {
161///     left_val => {
162///         assert_eq!(*left_val, list);
163///     }
164/// }
165/// ```
166#[proc_macro_derive(Data, attributes(set, get, get_mut))]
167pub fn data(input: TokenStream) -> TokenStream {
168    inner_lombok_data(input, true, true, true)
169}
170
171/// A procedural macro that implements the `std::fmt::Display` trait for a type,
172/// using the standard debug format (`{:?}`) for formatting.
173///
174/// This macro derives the `Display` implementation for a type, allowing it to be formatted
175/// using `{:?}` in formatting macros. It uses the `inner_display_debug` function to generate
176/// the implementation with the standard debug format.
177///
178/// # Parameters
179/// - `input`: The input token stream representing the Rust item (struct, enum, etc.)
180///   for which the `Display` implementation will be generated.
181///
182/// # Returns
183/// - `TokenStream`: The generated `std::fmt::Display` implementation for the type
184///   using the standard debug format.
185#[proc_macro_derive(DisplayDebug)]
186pub fn display_debug(input: TokenStream) -> TokenStream {
187    inner_display_debug(input)
188}
189
190/// A procedural macro that implements the `std::fmt::Display` trait for a type,
191/// using the detailed debug format (`{:#?}`) for formatting.
192///
193/// This macro derives the `Display` implementation for a type, allowing it to be formatted
194/// using `{:#?}` in formatting macros. It uses the `inner_display_debug_format` function
195/// to generate the implementation with the detailed debug format.
196///
197/// # Parameters
198/// - `input`: The input token stream representing the Rust item (struct, enum, etc.)
199///   for which the `Display` implementation will be generated.
200///
201/// # Returns
202/// - `TokenStream`: The generated `std::fmt::Display` implementation for the type
203///   using the detailed debug format.
204#[proc_macro_derive(DisplayDebugFormat)]
205pub fn display_debug_format(input: TokenStream) -> TokenStream {
206    inner_display_debug_format(input)
207}
208
209/// A procedural macro that implements the `std::fmt::Debug` trait for a type,
210/// with support for the `#[debug(skip)]` attribute to skip specific fields.
211///
212/// This macro derives a custom Debug implementation that behaves like the standard
213/// library's Debug derive, but allows individual fields to be excluded from the
214/// debug output by annotating them with `#[debug(skip)]`.
215///
216/// # Supported Attributes
217/// - `#[debug(skip)]`: Excludes the field from the debug output
218///
219/// # Examples
220///
221/// ## Struct Example
222/// ```rust
223/// use lombok_macros::*;
224///
225/// #[derive(CustomDebug)]
226/// struct User {
227///     name: String,
228///     #[debug(skip)]
229///     password: String,
230///     email: String,
231/// }
232///
233/// let user = User {
234///     name: "Alice".to_string(),
235///     password: "secret123".to_string(),
236///     email: "alice@example.com".to_string(),
237/// };
238/// println!("{:?}", user);
239/// // Output: User { name: "Alice", email: "alice@example.com" }
240/// ```
241///
242/// ## Enum Example
243/// ```rust
244/// use lombok_macros::*;
245///
246/// #[derive(CustomDebug)]
247/// enum Response {
248///     Success { data: String },
249///     Error {
250///         message: String,
251///         #[debug(skip)]
252///         internal_code: u32,
253///     },
254/// }
255/// ```
256///
257/// # Parameters
258/// - `input`: The input token stream representing the Rust item (struct, enum, etc.)
259///   for which the Debug implementation will be generated.
260///
261/// # Returns
262/// - `TokenStream`: The generated `std::fmt::Debug` implementation for the type
263///   that respects the `#[debug(skip)]` attribute.
264#[proc_macro_derive(CustomDebug, attributes(debug))]
265pub fn custom_debug(input: TokenStream) -> TokenStream {
266    inner_custom_debug(input)
267}