diff options
| -rw-r--r-- | src/lib.rs | 29 | ||||
| -rw-r--r-- | tests/get.rs | 111 |
2 files changed, 99 insertions, 41 deletions
@@ -6,6 +6,12 @@ pub fn get(input: proc_macro::TokenStream) -> proc_macro::TokenStream { get::expand(&parsed_input, false).unwrap().into() } +#[proc_macro_derive(GetCopy, attributes(get))] +pub fn get_copy(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let parsed_input = syn::parse_macro_input!(input as syn::DeriveInput); + get::expand(&parsed_input, true).unwrap().into() +} + mod get { use if_chain::if_chain; @@ -117,14 +123,27 @@ mod get { Type::Reference(type_ref) => Some(&type_ref.lifetime), _ => None, }; - let reference = (!is_copy).then(|| quote! { & }); + let method_args = if is_copy { + quote! { ( self ) } + } else { + quote! { ( & #field_lifetime self ) } + }; + let method_type = if is_copy { + quote! { #field_type } + } else { + quote! { & #field_type } + }; + let method_body = if is_copy { + quote! { { self . #field_name } } + } else { + quote! { { & self . #field_name } } + }; quote! { pub fn #method_name - ( #reference #field_lifetime self ) - -> #reference #field_type { - #reference self.#field_name - } + #method_args + -> #method_type + #method_body } } diff --git a/tests/get.rs b/tests/get.rs index b446ff4..937ddf5 100644 --- a/tests/get.rs +++ b/tests/get.rs @@ -1,45 +1,9 @@ -use get::Get; - macro_rules! testcase { ($test:literal) => { concat!("tests/trybuild/", $test) }; } -#[derive(Get)] -pub struct Cat<'a, T> { - name: &'a str, - age: u64, - owner: T, -} - -#[derive(Get)] -pub struct CatTuple<'a, T>( - #[get(method = "name")] &'a str, - #[get(method = "age")] u64, - #[get(method = "owner")] T, -); - -#[test] -fn cat_struct() { - let cat = Cat { - name: "cat", - age: 1, - owner: (), - }; - assert_eq!(*cat.name(), "cat"); - assert_eq!(*cat.age(), 1); - assert!(matches!(cat.owner(), ())); -} - -#[test] -fn cat_tuple_struct() { - let cat = CatTuple("cat", 1, ()); - assert_eq!(*cat.name(), "cat"); - assert_eq!(*cat.age(), 1); - assert!(matches!(cat.owner(), ())); -} - #[test] fn trybuild() { let tests = trybuild::TestCases::new(); @@ -47,3 +11,78 @@ fn trybuild() { tests.compile_fail(testcase!("tuple-struct-without-attribute.rs")); tests.compile_fail(testcase!("invalid-attribute.rs")); } + +mod get { + use get::Get; + #[derive(Get)] + pub struct Cat<'a, T> { + name: &'a str, + age: u64, + owner: T, + } + + #[derive(Get)] + pub struct CatTuple<'a, T>( + #[get(method = "name")] &'a str, + #[get(method = "age")] u64, + #[get(method = "owner")] T, + ); + + #[test] + fn cat_struct() { + let cat = Cat { + name: "cat", + age: 1, + owner: (), + }; + assert_eq!(*cat.name(), "cat"); + assert_eq!(*cat.age(), 1); + assert!(matches!(cat.owner(), ())); + } + + #[test] + fn cat_tuple_struct() { + let cat = CatTuple("cat", 1, ()); + assert_eq!(*cat.name(), "cat"); + assert_eq!(*cat.age(), 1); + assert!(matches!(cat.owner(), ())); + } +} + +mod get_copy { + use get::GetCopy; + + #[derive(Clone, Copy, GetCopy)] + pub struct Cat<'a, T> { + name: &'a str, + age: u64, + owner: T, + } + + #[derive(Clone, Copy, GetCopy)] + pub struct CatTuple<'a, T>( + #[get(method = "name")] &'a str, + #[get(method = "age")] u64, + #[get(method = "owner")] T, + ); + + #[test] + fn cat_struct() { + let cat = Cat { + name: "cat", + age: 1, + owner: (), + }; + assert_eq!(cat.name(), "cat"); + assert_eq!(cat.age(), 1); + assert!(matches!(cat.owner(), ())); + } + + #[test] + fn cat_tuple_struct() { + let cat = CatTuple("cat", 1, ()); + assert_eq!(cat.name(), "cat"); + assert_eq!(cat.age(), 1); + assert!(matches!(cat.owner(), ())); + } +} |
