diff --git a/Cargo.toml b/Cargo.toml index 4f245d9..4f6dc6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,4 @@ proc-macro = true [dependencies] quote = "1" proc-macro2 = "1.0" -syn = "2.0.15" +syn = { version = "2.0.15", features = ["extra-traits"] } diff --git a/src/lib.rs b/src/lib.rs index 94d1fc7..9594520 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ use proc_macro2::Ident; use quote::{format_ident, quote}; use syn::parse::discouraged::Speculative; use syn::parse::ParseStream; -use syn::{parse_macro_input, DataEnum, DeriveInput, Fields, Meta, Token}; +use syn::{parse_macro_input, DataEnum, DeriveInput, Fields, Meta, Token, Type}; #[derive(Clone, Eq, PartialEq, Debug)] enum GetterKind { @@ -52,7 +52,7 @@ impl GetterKind { struct CommonField { kinds: Vec, field_name: Ident, - field_type: Ident, + field_type: Type, resulting_name: Option, // Can have a value only if one function is generated } @@ -336,7 +336,7 @@ fn generate_accessor( enum_name: &Ident, variants: &Vec, field_name: &Ident, - field_type: &Ident, + field_type: &Type, ref_token: proc_macro2::TokenStream, resulting_name: Ident, ) -> proc_macro2::TokenStream { @@ -393,7 +393,7 @@ mod common_field_parsing_tests { let parsed: CommonField = syn::parse2(tokens).expect("Failed to parse"); assert_eq!(parsed.field_name, "field1"); - assert_eq!(parsed.field_type, "i32"); + assert_eq!(parsed.field_type, parse_quote!(i32)); assert_eq!(parsed.kinds, vec![GetterKind::ReadOnly]); assert!(parsed.resulting_name.is_none()); } @@ -405,17 +405,28 @@ mod common_field_parsing_tests { assert_eq!(parsed.field_name, "field1"); assert_eq!(parsed.resulting_name.unwrap(), "custom_name"); - assert_eq!(parsed.field_type, "i32"); + assert_eq!(parsed.field_type, parse_quote!(i32)); assert_eq!(parsed.kinds, vec![GetterKind::ReadOnly]); } + #[test] + fn test_field_with_complex_type() { + let tokens = parse_quote! { field1: Option<(i32, [u8; 4])> }; + let parsed: CommonField = syn::parse2(tokens).expect("Failed to parse"); + + assert_eq!(parsed.field_name, "field1"); + assert_eq!(parsed.field_type, parse_quote!(Option<(i32, [u8; 4])>)); + assert_eq!(parsed.kinds, vec![GetterKind::ReadOnly]); + assert!(parsed.resulting_name.is_none()); + } + #[test] fn test_mutable_field() { let tokens = parse_quote! { mut field1: i32 }; let parsed: CommonField = syn::parse2(tokens).expect("Failed to parse"); assert_eq!(parsed.field_name, "field1"); - assert_eq!(parsed.field_type, "i32"); + assert_eq!(parsed.field_type, parse_quote!(i32)); assert_eq!( parsed.kinds, vec![GetterKind::ReadOnly, GetterKind::Mutable] @@ -429,7 +440,7 @@ mod common_field_parsing_tests { let parsed: CommonField = syn::parse2(tokens).expect("Failed to parse"); assert_eq!(parsed.field_name, "field1"); - assert_eq!(parsed.field_type, "i32"); + assert_eq!(parsed.field_type, parse_quote!(i32)); assert_eq!(parsed.kinds, vec![GetterKind::Owning]); assert!(parsed.resulting_name.is_none()); } @@ -440,7 +451,7 @@ mod common_field_parsing_tests { let parsed: CommonField = syn::parse2(tokens).expect("Failed to parse"); assert_eq!(parsed.field_name, "field1"); - assert_eq!(parsed.field_type, "i32"); + assert_eq!(parsed.field_type, parse_quote!(i32)); assert_eq!( parsed.kinds, vec![ @@ -494,7 +505,7 @@ mod attributes_parse_tests { let result = parse_common_fields_attributes(&input); assert_eq!(result.len(), 1); assert_eq!(result[0].field_name, "field1"); - assert_eq!(result[0].field_type, "i32"); + assert_eq!(result[0].field_type, parse_quote!(i32)); assert_eq!(result[0].kinds, vec![GetterKind::ReadOnly]); } @@ -514,11 +525,11 @@ mod attributes_parse_tests { assert_eq!(result.len(), 2); assert_eq!(result[0].field_name, "field1"); - assert_eq!(result[0].field_type, "i32"); + assert_eq!(result[0].field_type, parse_quote!(i32)); assert_eq!(result[0].kinds, vec![GetterKind::ReadOnly]); assert_eq!(result[1].field_name, "field2"); - assert_eq!(result[1].field_type, "String"); + assert_eq!(result[1].field_type, parse_quote!(String)); assert_eq!( result[1].kinds, vec![GetterKind::ReadOnly, GetterKind::Mutable] @@ -540,7 +551,7 @@ mod attributes_parse_tests { assert_eq!(result.len(), 1); assert_eq!(result[0].field_name, "field1"); assert_eq!(result[0].clone().resulting_name.unwrap(), "custom_name"); - assert_eq!(result[0].field_type, "i32"); + assert_eq!(result[0].field_type, parse_quote!(i32)); assert_eq!(result[0].kinds, vec![GetterKind::ReadOnly]); }