From 0113268c3f301b5e25da5b6833b0875e702b8410 Mon Sep 17 00:00:00 2001 From: jngls Date: Mon, 16 Jun 2025 21:16:51 +0100 Subject: [PATCH] Implement generics, lifetimes, bounds and where clause support --- enum-display-macro/src/lib.rs | 7 +++++-- src/lib.rs | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/enum-display-macro/src/lib.rs b/enum-display-macro/src/lib.rs index 5dc0c7b..e2803be 100644 --- a/enum-display-macro/src/lib.rs +++ b/enum-display-macro/src/lib.rs @@ -30,7 +30,7 @@ fn parse_case_name(case_name: &str) -> Case { pub fn derive(input: TokenStream) -> TokenStream { // Parse the input tokens into a syntax tree let DeriveInput { - ident, data, attrs, .. + ident, data, attrs, generics, .. } = parse_macro_input!(input); // Should we transform the case of the enum variants? @@ -82,13 +82,16 @@ pub fn derive(input: TokenStream) -> TokenStream { } }); + // Copy generics and bounds + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + // #[allow(unused_qualifications)] is needed // due to https://github.com/SeedyROM/enum-display/issues/1 // Possibly related to https://github.com/rust-lang/rust/issues/96698 let output = quote! { #[automatically_derived] #[allow(unused_qualifications)] - impl ::core::fmt::Display for #ident { + impl #impl_generics ::core::fmt::Display for #ident #ty_generics #where_clause { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::write_str( f, diff --git a/src/lib.rs b/src/lib.rs index 2014389..7ac4ebc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,19 @@ mod tests { DateOfBirth(u32, u32, u32), } + #[allow(dead_code)] + #[derive(EnumDisplay)] + enum TestEnumWithGenerics<'a, T: Clone> where T: std::fmt::Display { + Name, + Address { + street: &'a T, + city: &'a T, + state: &'a T, + zip: &'a T, + }, + DateOfBirth(u32, u32, u32), + } + #[test] fn test_unit_field_variant() { assert_eq!(TestEnum::Name.to_string(), "Name"); @@ -117,4 +130,28 @@ mod tests { "date-of-birth" ); } + + #[test] + fn test_unit_field_variant_with_generics() { + assert_eq!(TestEnumWithGenerics::<'_, String>::Name.to_string(), "Name"); + } + + #[test] + fn test_named_fields_variant_with_generics() { + assert_eq!( + TestEnumWithGenerics::Address { + street: &"123 Main St".to_string(), + city: &"Any Town".to_string(), + state: &"CA".to_string(), + zip: &"12345".to_string() + } + .to_string(), + "Address" + ); + } + + #[test] + fn test_unnamed_fields_variant_with_generics() { + assert_eq!(TestEnumWithGenerics::<'_, String>::DateOfBirth(1, 1, 2000).to_string(), "DateOfBirth"); + } }