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