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}