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 config;
9pub(crate) mod func;
10pub(crate) mod generate;
11pub(crate) mod parse;
12pub(crate) mod visibility;
13
14pub(crate) use config::*;
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::{
22 Delimiter, TokenStream as TokenStream2, TokenTree as TokenTree2, token_stream::IntoIter,
23};
24pub(crate) use quote::{ToTokens, format_ident, quote};
25pub(crate) use std::{
26 collections::{HashMap, HashSet},
27 fmt::{Display, Formatter},
28 iter::Peekable,
29 str::FromStr,
30};
31pub(crate) use syn::{
32 Data, DeriveInput, Field, Fields, GenericArgument,
33 GenericParam::{self},
34 Generics, Ident, Index, Lifetime, PathArguments,
35 Type::{self},
36 TypeParam, Variant, WhereClause, parse_macro_input,
37};
38
39/// A procedural macro that automatically generates getter methods for struct and enum fields.
40///
41/// This macro derives getter methods with configurable visibility and return type behavior.
42/// The generated getters can return either references to field values or cloned copies,
43/// with support for Option and Result types.
44///
45/// # Supported Attributes
46/// - `#[get(pub)]` - Generates a public getter with reference return type
47/// - `#[get(pub, reference)]` - Generates a public getter that returns a reference (`&T`)
48/// - `#[get(pub, clone)]` - Generates a public getter that returns a cloned value (`T`)
49/// - `#[get(pub, copy)]` - Generates a public getter that returns a copy of the field value (`self.field`) for Copy types
50/// - `#[get(pub, deref)]` - Generates a public getter that returns a dereferenced value (`*field`) with enhanced match control for Option/Result types
51/// - `#[get(pub(crate))]` - Generates a crate-visible getter
52/// - `#[get(private)]` - Generates a private getter
53///
54/// # Return Type Behavior
55/// - `reference` - Returns `&T` - a reference to the field value
56/// - `clone` - Returns `T` - a cloned copy of the field value
57/// - `copy` - Returns `T` - a copy of the field value (`self.field`) for types implementing Copy trait
58/// - `deref` - Returns dereferenced values with enhanced match control:
59/// - `Option<T>` → `T` with detailed None panic messages
60/// - `Result<T, E>` → `T` with detailed Err panic messages
61/// - `Box<T>` → `T` by dereferencing the box
62/// - `Rc<T>` → `T` by cloning the inner value
63/// - `Arc<T>` → `T` by cloning the inner value
64/// - Other types → `T` by dereferencing
65/// - Default behavior: Returns `&T` for non-Option/Result types, `T` for Option/Result types
66///
67/// # Default Behavior Details
68/// - **Non-Option/Result types**: Returns `&T` (reference to field)
69/// - **Option/Result types**: Returns `T` (cloned value) to avoid exposing internal references
70/// - This ensures safe access patterns while maintaining performance for common use cases
71///
72/// # Examples
73///
74/// ## Basic Usage
75///
76/// ```rust
77/// use lombok_macros::*;
78///
79/// #[derive(Getter, Clone)]
80/// struct BasicStruct {
81/// #[get(pub)]
82/// name: String,
83/// #[get(pub, type(reference))]
84/// description: String,
85/// #[get(pub, type(clone))]
86/// data: Vec<i32>,
87/// #[get(pub, type(copy))]
88/// count: i32,
89/// }
90///
91/// let basic = BasicStruct {
92/// name: "test".to_string(),
93/// description: "description".to_string(),
94/// data: vec![1, 2, 3],
95/// count: 42,
96/// };
97/// let name_ref: &String = basic.get_name();
98/// let description_ref: &String = basic.get_description();
99/// let data_clone: Vec<i32> = basic.get_data();
100/// let count_copy: i32 = basic.get_count();
101/// assert_eq!(*name_ref, "test");
102/// assert_eq!(*description_ref, "description");
103/// assert_eq!(data_clone, vec![1, 2, 3]);
104/// assert_eq!(count_copy, 42);
105/// ```
106///
107/// ## Option and Result Types
108///
109/// ```rust
110/// use lombok_macros::*;
111///
112/// #[derive(Getter, Clone)]
113/// struct OptionalStruct {
114/// #[get(pub)]
115/// optional: Option<String>,
116/// #[get(pub, type(reference))]
117/// optional_ref: Option<String>,
118/// #[get(pub)]
119/// result: Result<String, String>,
120/// }
121///
122/// let opt_struct = OptionalStruct {
123/// optional: Some("value".to_string()),
124/// optional_ref: Some("ref_value".to_string()),
125/// result: Ok("success".to_string()),
126/// };
127/// let optional_value: String = opt_struct.get_optional();
128/// let optional_reference: &Option<String> = opt_struct.get_optional_ref();
129/// let result_value: String = opt_struct.get_result();
130/// assert_eq!(optional_value, "value");
131/// assert_eq!(*optional_reference, Some("ref_value".to_string()));
132/// assert_eq!(result_value, "success");
133/// ```
134///
135/// ## Tuple Structs
136///
137/// ```rust
138/// use lombok_macros::*;
139///
140/// #[derive(Getter, Clone)]
141/// struct TupleStruct(
142/// #[get(pub)] String,
143/// #[get(pub, type(clone))] Vec<i32>,
144/// );
145///
146/// let tuple = TupleStruct("hello".to_string(), vec![1, 2, 3]);
147/// let field0: &String = tuple.get_0();
148/// let field1: Vec<i32> = tuple.get_1();
149/// assert_eq!(*field0, "hello");
150/// assert_eq!(field1, vec![1, 2, 3]);
151/// ```
152///
153/// ## Copy Return Type
154///
155/// ```rust
156/// use lombok_macros::*;
157///
158/// #[derive(Getter, Clone)]
159/// struct CopyStruct {
160/// #[get(pub, type(copy))]
161/// value: i32,
162/// #[get(pub, type(copy))]
163/// flag: bool,
164/// #[get(pub, type(copy))]
165/// count: u64,
166/// }
167///
168/// let copy_struct = CopyStruct {
169/// value: 42,
170/// flag: true,
171/// count: 1000,
172/// };
173/// let copied_value: i32 = copy_struct.get_value();
174/// let copied_flag: bool = copy_struct.get_flag();
175/// let copied_count: u64 = copy_struct.get_count();
176/// assert_eq!(copied_value, 42);
177/// assert_eq!(copied_flag, true);
178/// assert_eq!(copied_count, 1000);
179/// ```
180///
181/// ## Deref Return Type with Enhanced Match Control
182///
183/// ```rust
184/// use lombok_macros::*;
185///
186/// #[derive(Getter, Clone)]
187/// struct DerefStruct {
188/// #[get(pub, type(deref))]
189/// optional: Option<bool>,
190/// #[get(pub, type(deref))]
191/// result: Result<String, &'static str>,
192/// #[get(pub, type(deref))]
193/// boxed_value: Box<i32>,
194/// #[get(pub, type(deref))]
195/// rc_value: std::rc::Rc<String>,
196/// #[get(pub, type(deref))]
197/// arc_value: std::sync::Arc<Vec<u8>>,
198/// }
199///
200/// let deref_struct = DerefStruct {
201/// optional: Some(true),
202/// result: Ok("success".to_string()),
203/// boxed_value: Box::new(100),
204/// rc_value: std::rc::Rc::new("test".to_string()),
205/// arc_value: std::sync::Arc::new(vec![1, 2, 3]),
206/// };
207/// let optional_value: bool = deref_struct.get_optional();
208/// let result_value: String = deref_struct.get_result();
209/// let boxed_value: i32 = deref_struct.get_boxed_value();
210/// let rc_value: String = deref_struct.get_rc_value();
211/// let arc_value: Vec<u8> = deref_struct.get_arc_value();
212/// assert_eq!(optional_value, true);
213/// assert_eq!(result_value, "success");
214/// assert_eq!(boxed_value, 100);
215/// assert_eq!(rc_value, "test");
216/// assert_eq!(arc_value, vec![1, 2, 3]);
217/// ```
218///
219/// ## Generics and Lifetimes
220///
221/// ```rust
222/// use lombok_macros::*;
223///
224/// #[derive(Getter, Clone)]
225/// struct GenericStruct<'a, T: Clone> {
226/// #[get(pub)]
227/// value: &'a T,
228/// #[get(pub, type(clone))]
229/// owned: T,
230/// }
231///
232/// let data = 42;
233/// let generic = GenericStruct {
234/// value: &data,
235/// owned: 42,
236/// };
237/// let value_ref: &i32 = generic.get_value();
238/// let owned_clone: i32 = generic.get_owned();
239/// assert_eq!(*value_ref, 42);
240/// assert_eq!(owned_clone, 42);
241/// ```
242#[proc_macro_derive(Getter, attributes(get))]
243pub fn getter(input: TokenStream) -> TokenStream {
244 inner_lombok_data(input, true, false, false)
245}
246
247/// A procedural macro that automatically generates mutable getter methods for struct and enum fields.
248///
249/// This macro derives mutable getter methods that provide mutable references to field values,
250/// allowing modification of the struct's fields while maintaining proper borrowing semantics.
251///
252/// # Supported Attributes
253/// - `#[get_mut(pub)]` - Generates a public mutable getter
254/// - `#[get_mut(pub(crate))]` - Generates a crate-visible mutable getter
255/// - `#[get_mut(pub(super))]` - Generates a mutable getter visible to parent module
256/// - `#[get_mut(private)]` - Generates a private mutable getter
257///
258/// # Example
259///
260/// ```rust
261/// use lombok_macros::*;
262///
263/// #[derive(GetterMut, Clone)]
264/// struct StructWithLifetimes<'a, 'b, T: Clone> {
265/// #[get_mut(pub(crate))]
266/// list: Vec<String>,
267/// #[get_mut(pub(crate))]
268/// optional_lifetime_a: Option<&'a T>,
269/// optional_lifetime_b: Option<&'b str>,
270/// }
271///
272/// let list: Vec<String> = vec!["hello".to_string(), "world".to_string()];
273/// let mut struct_with_lifetimes: StructWithLifetimes<usize> = StructWithLifetimes {
274/// list: list.clone(),
275/// optional_lifetime_a: None,
276/// optional_lifetime_b: None,
277/// };
278/// let mut list_reference: &mut Vec<String> = struct_with_lifetimes.get_mut_list();
279/// list_reference.push("new_item".to_string());
280/// assert_eq!(*list_reference, vec!["hello".to_string(), "world".to_string(), "new_item".to_string()]);
281/// ```
282#[proc_macro_derive(GetterMut, attributes(get_mut))]
283pub fn getter_mut(input: TokenStream) -> TokenStream {
284 inner_lombok_data(input, false, true, false)
285}
286
287/// A procedural macro that automatically generates setter methods for struct and enum fields.
288///
289/// This macro derives setter methods that allow modification of struct fields with
290/// configurable visibility and parameter type conversion options.
291///
292/// # Supported Attributes
293/// - `#[set(pub)]` - Generates a public setter
294/// - `#[set(pub(crate))]` - Generates a crate-visible setter
295/// - `#[set(pub(super))]` - Generates a setter visible to parent module
296/// - `#[set(private)]` - Generates a private setter
297/// - `#[set(pub, type(AsRef<str>))]` - Generates a setter with custom parameter type conversion
298/// - `#[set(pub, Into)]` - Generates a setter using `impl Into<T>` trait bound
299/// - `#[set(pub, type(AsRef<[u8]>))]` - Generates a setter with `impl AsRef<[u8]>` parameter type
300///
301/// # Parameter Type Conversion
302/// Setters support flexible parameter type conversion through trait bounds:
303/// - `type(AsRef<T>)` - Accepts any type implementing `AsRef<T>` and converts using `.as_ref().to_owned()`
304/// - `type(Into<T>)` - Accepts any type implementing `Into<T>` and converts using `.into()`
305/// - `type(CustomTrait<T>)` - Accepts any type implementing the specified custom trait bound
306///
307/// # Examples
308///
309/// ## Basic Usage
310///
311/// ```rust
312/// use lombok_macros::*;
313///
314/// #[derive(Setter, Debug, Clone)]
315/// struct BasicStruct {
316/// #[set(pub)]
317/// name: String,
318/// #[set(pub(crate))]
319/// value: i32,
320/// #[set(private)]
321/// secret: String,
322/// }
323///
324/// let mut basic = BasicStruct {
325/// name: "initial".to_string(),
326/// value: 0,
327/// secret: "hidden".to_string(),
328/// };
329/// basic.set_name("updated".to_string());
330/// basic.set_value(42);
331/// assert_eq!(basic.name, "updated");
332/// assert_eq!(basic.value, 42);
333/// ```
334///
335/// ## Parameter Type Conversion
336///
337/// ```rust
338/// use lombok_macros::*;
339///
340/// #[derive(Setter, Debug, Clone)]
341/// struct ConversionStruct {
342/// #[set(pub, type(AsRef<str>))]
343/// name: String,
344/// #[set(pub, type(Into<i32>))]
345/// value: i32,
346/// #[set(pub, type(AsRef<[u8]>))]
347/// data: Vec<u8>,
348/// }
349///
350/// let mut conversion = ConversionStruct {
351/// name: "initial".to_string(),
352/// value: 0,
353/// data: vec![1, 2, 3],
354/// };
355///
356/// conversion.set_name("updated");
357/// assert_eq!(conversion.name, "updated");
358///
359/// conversion.set_value(1u8);
360/// assert_eq!(conversion.value, 1);
361///
362/// conversion.set_data(&[4, 5, 6]);
363/// assert_eq!(conversion.data, vec![4, 5, 6]);
364/// ```
365///
366/// ## Tuple Structs
367///
368/// ```rust
369/// use lombok_macros::*;
370///
371/// #[derive(Setter, Debug, Clone)]
372/// struct TupleStruct(
373/// #[set(pub)] String,
374/// #[set(pub)] i32,
375/// );
376///
377/// let mut tuple = TupleStruct("hello".to_string(), 1);
378/// tuple.set_0("world".to_string());
379/// tuple.set_1(100);
380/// assert_eq!(tuple.0, "world");
381/// assert_eq!(tuple.1, 100);
382/// ```
383#[proc_macro_derive(Setter, attributes(set))]
384pub fn setter(input: TokenStream) -> TokenStream {
385 inner_lombok_data(input, false, false, true)
386}
387
388/// A procedural macro that combines getter, mutable getter, and setter functionality in a single derive.
389///
390/// This macro derives all three types of accessor methods (getters, mutable getters, and setters)
391/// for struct and enum fields, providing comprehensive data manipulation capabilities with
392/// configurable visibility and behavior options.
393///
394/// # Supported Attributes
395/// - `#[get(...)]` - Controls getter generation (supports `reference`, `clone`, `copy`, `deref` options)
396/// - `#[get_mut(...)]` - Controls mutable getter generation
397/// - `#[set(...)]` - Controls setter generation (supports parameter type conversion with `type(AsRef<T>)`, `Into`, etc.)
398///
399/// # Visibility Control
400/// Each attribute supports the same visibility options:
401/// - `pub` - Public access
402/// - `pub(crate)` - Crate-level access
403/// - `pub(super)` - Parent module access
404/// - `private` - Private access
405///
406/// # Examples
407///
408/// ## Basic Combination
409///
410/// ```rust
411/// use lombok_macros::*;
412///
413/// #[derive(Data, Debug, Clone)]
414/// struct User {
415/// #[get(pub)]
416/// #[set(pub)]
417/// name: String,
418/// #[get(pub, type(clone))]
419/// #[set(pub)]
420/// email: String,
421/// #[get(pub, type(copy))]
422/// age: u32,
423/// #[get_mut(pub)]
424/// mutable_age: u32,
425/// }
426///
427/// let mut user = User {
428/// name: "Alice".to_string(),
429/// email: "alice@ltpp.vip".to_string(),
430/// age: 30,
431/// mutable_age: 25,
432/// };
433/// let name_reference: &String = user.get_name();
434/// let email_clone: String = user.get_email();
435/// let age_copy: u32 = user.get_age();
436/// assert_eq!(*name_reference, "Alice");
437/// assert_eq!(email_clone, "alice@ltpp.vip");
438/// assert_eq!(age_copy, 30);
439///
440/// user.set_name("Bob".to_string());
441/// user.set_email("bob@ltpp.vip".to_string());
442/// let updated_email: String = user.get_email();
443/// assert_eq!(updated_email, "bob@ltpp.vip");
444///
445/// (*user.get_mut_mutable_age() = 31);
446///
447/// assert_eq!(*user.get_mutable_age(), 31);
448/// ```
449///
450/// ## Multiple Field Types
451///
452/// ```rust
453/// use lombok_macros::*;
454///
455/// #[derive(Data, Debug, Clone)]
456/// struct ComplexStruct {
457/// #[get(pub)]
458/// id: i32,
459/// #[get(pub)]
460/// #[set(pub)]
461/// optional: Option<String>,
462/// #[get(pub, type(reference))]
463/// result: Result<i32, String>,
464/// #[get(pub(crate))]
465/// #[set(private)]
466/// internal_data: Vec<u8>,
467/// }
468///
469/// let mut complex = ComplexStruct {
470/// id: 1,
471/// optional: Some("value".to_string()),
472/// result: Ok(42),
473/// internal_data: vec![1, 2, 3],
474/// };
475///
476/// let id_reference: &i32 = complex.get_id();
477/// let optional_clone: String = complex.get_optional();
478/// let result_reference: &Result<i32, String> = complex.get_result();
479/// assert_eq!(*id_reference, 1);
480/// assert_eq!(optional_clone, "value");
481/// assert_eq!(*result_reference, Ok(42));
482/// ```
483///
484/// ## Tuple Struct with Combined Accessors
485///
486/// ```rust
487/// use lombok_macros::*;
488///
489/// #[derive(Data, Debug, Clone)]
490/// struct Point(
491/// #[get(pub)] f64,
492/// #[get(pub, type(clone))]
493/// #[set(pub)] f64,
494/// );
495///
496/// let mut point = Point(1.0, 2.0);
497/// let x_coordinate: &f64 = point.get_0();
498/// let y_coordinate: f64 = point.get_1();
499/// assert_eq!(*x_coordinate, 1.0);
500/// assert_eq!(y_coordinate, 2.0);
501///
502/// point.set_1(3.0);
503/// let updated_y_coordinate: f64 = point.get_1();
504/// assert_eq!(updated_y_coordinate, 3.0);
505/// ```
506#[proc_macro_derive(Data, attributes(get, get_mut, set))]
507pub fn data(input: TokenStream) -> TokenStream {
508 let mut result: TokenStream2 = TokenStream2::new();
509 let lombok_data: TokenStream = inner_lombok_data(input.clone(), true, true, true);
510 result.extend(
511 lombok_data
512 .to_string()
513 .parse::<TokenStream2>()
514 .unwrap_or_default(),
515 );
516 result.into()
517}
518
519/// A procedural macro that implements the `std::fmt::Display` trait for a type,
520/// using the standard debug format (`{:?}`) for formatting.
521///
522/// This macro derives the `Display` implementation for a type, allowing it to be formatted
523/// using `{:?}` in formatting macros. It uses the `inner_display_debug` function to generate
524/// the implementation with the standard debug format.
525///
526/// # Arguments
527/// - `input` - The input token stream representing the Rust item (struct, enum, etc.)
528/// for which the `Display` implementation will be generated.
529///
530/// # Returns
531/// - `TokenStream` - The generated `std::fmt::Display` implementation for the type
532/// using the standard debug format.
533#[proc_macro_derive(DisplayDebug)]
534pub fn display_debug(input: TokenStream) -> TokenStream {
535 inner_display_debug(input)
536}
537
538/// A procedural macro that implements the `std::fmt::Display` trait for a type,
539/// using the detailed debug format (`{:#?}`) for formatting.
540///
541/// This macro derives the `Display` implementation for a type, allowing it to be formatted
542/// using `{:#?}` in formatting macros. It uses the `inner_display_debug_format` function
543/// to generate the implementation with the detailed debug format.
544///
545/// # Arguments
546/// - `input` - The input token stream representing the Rust item (struct, enum, etc.)
547/// for which the `Display` implementation will be generated.
548///
549/// # Returns
550/// - `TokenStream` - The generated `std::fmt::Display` implementation for the type
551/// using the detailed debug format.
552#[proc_macro_derive(DisplayDebugFormat)]
553pub fn display_debug_format(input: TokenStream) -> TokenStream {
554 inner_display_debug_format(input)
555}
556
557/// A procedural macro that implements the `std::fmt::Debug` trait for a type,
558/// with support for the `#[debug(skip)]` attribute to skip specific fields.
559///
560/// This macro derives a custom Debug implementation that behaves like the standard
561/// library's Debug derive, but allows individual fields to be excluded from the
562/// debug output by annotating them with `#[debug(skip)]`.
563///
564/// # Supported Attributes
565/// - `#[debug(skip)]` - Excludes the field from the debug output
566///
567/// # Examples
568///
569/// ## Struct Example
570/// ```rust
571/// use lombok_macros::*;
572///
573/// #[derive(CustomDebug)]
574/// struct User {
575/// name: String,
576/// #[debug(skip)]
577/// password: String,
578/// email: String,
579/// }
580///
581/// let user = User {
582/// name: "Alice".to_string(),
583/// password: "secret123".to_string(),
584/// email: "alice@ltpp.vip".to_string(),
585/// };
586/// let expected_debug = "User { name: \"Alice\", email: \"alice@ltpp.vip\" }";
587/// assert_eq!(format!("{:?}", user), expected_debug);
588/// ```
589///
590/// ## Enum Example
591/// ```rust
592/// use lombok_macros::*;
593///
594/// #[derive(CustomDebug)]
595/// enum Response {
596/// Success { data: String },
597/// Error {
598/// message: String,
599/// #[debug(skip)]
600/// internal_code: u32,
601/// },
602/// }
603///
604/// let success = Response::Success { data: "Hello".to_string() };
605/// let error = Response::Error { message: "Failed".to_string(), internal_code: 500 };
606/// let expected_success = "Success { data: \"Hello\" }";
607/// let expected_error = "Error { message: \"Failed\" }";
608/// assert_eq!(format!("{:?}", success), expected_success);
609/// assert_eq!(format!("{:?}", error), expected_error);
610/// ```
611///
612/// # Arguments
613/// - `input` - The input token stream representing the Rust item (struct, enum, etc.)
614/// for which the Debug implementation will be generated.
615///
616/// # Returns
617/// - `TokenStream` - The generated `std::fmt::Debug` implementation for the type
618/// that respects the `#[debug(skip)]` attribute.
619#[proc_macro_derive(CustomDebug, attributes(debug))]
620pub fn custom_debug(input: TokenStream) -> TokenStream {
621 inner_custom_debug(input)
622}
623
624/// A procedural macro that generates a constructor function for structs.
625///
626/// This macro automatically generates a `new` function that takes all non-skipped fields
627/// as parameters and returns a new instance of the struct. Fields marked with `#[new(skip)]`
628/// will be initialized with their default values.
629///
630/// # Supported Attributes
631/// - `#[new(skip)]` - Excludes the field from constructor parameters and uses default initialization
632/// - `#[new(pub)]` - Generates a public constructor
633/// - `#[new(pub(crate))]` - Generates a crate-visible constructor
634/// - `#[new(pub(super))]` - Generates a constructor visible to parent module
635/// - `#[new(private)]` - Generates a private constructor
636///
637/// # Default Behavior
638/// - The generated constructor is `pub` by default
639/// - All fields are included in the constructor unless marked with `#[new(skip)]`
640/// - Skipped fields are initialized using `Default::default()`
641///
642/// # Examples
643///
644/// ## Basic Usage
645/// ```rust
646/// use lombok_macros::*;
647///
648/// #[derive(New)]
649/// struct Person {
650/// name: String,
651/// age: u32,
652/// }
653///
654/// let person = Person::new("Alice".to_string(), 30);
655/// assert_eq!(person.name, "Alice");
656/// assert_eq!(person.age, 30);
657/// ```
658///
659/// ## With Skip Attribute
660/// ```rust
661/// use lombok_macros::*;
662///
663/// #[derive(New)]
664/// struct User {
665/// username: String,
666/// email: String,
667/// #[new(skip)]
668/// created_at: String,
669/// }
670///
671/// let user = User::new("alice".to_string(), "alice@ltpp.vip".to_string());
672/// assert_eq!(user.username, "alice");
673/// assert_eq!(user.email, "alice@ltpp.vip");
674/// assert_eq!(user.created_at, "");
675/// ```
676///
677/// ## With Custom Visibility
678/// ```rust
679/// use lombok_macros::*;
680///
681/// #[derive(New)]
682/// #[new(pub(crate))]
683/// struct InternalStruct {
684/// value: i32,
685/// }
686///
687/// let internal = InternalStruct::new(42);
688/// assert_eq!(internal.value, 42);
689/// ```
690///
691/// ## Tuple Structs
692/// ```rust
693/// use lombok_macros::*;
694///
695/// #[derive(New)]
696/// struct Point(
697/// f64,
698/// f64,
699/// );
700///
701/// let origin = Point::new(0.0, 0.0);
702/// assert_eq!(origin.0, 0.0);
703/// assert_eq!(origin.1, 0.0);
704/// ```
705///
706/// ## Generic Types
707/// ```rust
708/// use lombok_macros::*;
709///
710/// #[derive(New)]
711/// struct Container<T: Default + Clone> {
712/// data: T,
713/// #[new(skip)]
714/// count: usize,
715/// }
716///
717/// let container = Container::new("data".to_string());
718/// assert_eq!(container.data, "data");
719/// assert_eq!(container.count, 0);
720/// ```
721///
722/// # Arguments
723/// - `input` - The input token stream representing the struct for which to generate the constructor.
724///
725/// # Returns
726/// - `TokenStream` - The generated constructor implementation.
727#[proc_macro_derive(New, attributes(new))]
728pub fn new(input: TokenStream) -> TokenStream {
729 let derive_input: DeriveInput = parse_macro_input!(input as DeriveInput);
730 let visibility: Visibility = parse_new_visibility(&derive_input);
731 inner_new_constructor(&derive_input, visibility)
732}