summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs29
-rw-r--r--tests/get.rs111
2 files changed, 99 insertions, 41 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 27b847c..65c3857 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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(), ()));
+ }
+}