changeset 15:a794b6862ef4

Clean up code
author Lewin Bormann <lbo@spheniscida.de>
date Thu, 15 Oct 2020 19:24:47 +0200
parents 4603aaa0378c
children 2c254214df2e
files Cargo.toml src/lib.rs
diffstat 2 files changed, 37 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/Cargo.toml	Thu Oct 15 14:28:34 2020 +0200
+++ b/Cargo.toml	Thu Oct 15 19:24:47 2020 +0200
@@ -2,7 +2,7 @@
 name = "memoize"
 version = "0.1.2"
 description = "Attribute macro for auto-memoizing functions with somewhat-simple signatures"
-tags = ["memoization", "cache"]
+keywords = ["memoization", "cache", "proc-macro"]
 authors = ["Lewin Bormann <lewin@lewin-bormann.info>"]
 homepage = "https://github.com/dermesser/memoize"
 repository = "https://github.com/dermesser/memoize"
--- a/src/lib.rs	Thu Oct 15 14:28:34 2020 +0200
+++ b/src/lib.rs	Thu Oct 15 19:24:47 2020 +0200
@@ -50,53 +50,28 @@
     let renamed_name = format!("memoized_original_{}", fn_name);
     let map_name = format!("memoized_mapping_{}", fn_name);
 
-    let input_type;
-    let input_names;
-    let type_out;
+    // Extracted from the function signature.
+    let input_types: Vec<Box<syn::Type>>;
+    let input_names: Vec<Box<syn::Pat>>;
+    let return_type;
 
-    // Only one argument
-    if let syn::FnArg::Receiver(_) = sig.inputs[0] {
-        return TokenStream::from(
-            syn::Error::new(
-                sig.span(),
-                "Cannot memoize method (self-receiver) without arguments!",
-            )
-            .to_compile_error(),
-        );
-    }
-    let mut types = vec![];
-    let mut names = vec![];
-    for a in &sig.inputs {
-        if let syn::FnArg::Typed(ref arg) = a {
-            types.push(arg.ty.clone());
-
-            if let syn::Pat::Ident(_) = &*arg.pat {
-                names.push(arg.pat.clone());
-            } else {
-                return syn::Error::new(sig.span(), "Cannot memoize arbitrary patterns!")
-                    .to_compile_error()
-                    .into();
-            }
-        }
+    match check_signature(sig) {
+        Ok((t, n)) => { input_types = t; input_names = n; },
+        Err(e) => return e.to_compile_error().into()
     }
 
-    // We treat functions with one or with multiple arguments the same: The type is made into a
-    // tuple.
-    input_type = Some(quote::quote! { (#(#types),*) });
-    input_names = Some(names);
+    let input_tuple_type = quote::quote! { (#(#input_types),*) };
 
     match &sig.output {
-        syn::ReturnType::Default => type_out = quote::quote! { () },
-        syn::ReturnType::Type(_, ty) => type_out = ty.to_token_stream(),
+        syn::ReturnType::Default => return_type = quote::quote! { () },
+        syn::ReturnType::Type(_, ty) => return_type = ty.to_token_stream(),
     }
 
     // Construct storage for the memoized keys and return values.
-    let input_type = input_type.unwrap();
-    let input_names = input_names.unwrap();
     let store_ident = syn::Ident::new(&map_name.to_uppercase(), sig.span());
     let store = quote::quote! {
         lazy_static::lazy_static! {
-            static ref #store_ident : std::sync::Mutex<std::collections::HashMap<#input_type, #type_out>> =
+            static ref #store_ident : std::sync::Mutex<std::collections::HashMap<#input_tuple_type, #return_type>> =
                 std::sync::Mutex::new(std::collections::HashMap::new());
         }
     };
@@ -131,5 +106,30 @@
     .into()
 }
 
+fn check_signature(sig: &syn::Signature) -> Result<(Vec<Box<syn::Type>>, Vec<Box<syn::Pat>>), syn::Error> {
+    if let syn::FnArg::Receiver(_) = sig.inputs[0] {
+        return Err(
+            syn::Error::new(
+                sig.span(),
+                "Cannot memoize method (self-receiver) without arguments!",
+            ));
+    }
+
+    let mut types = vec![];
+    let mut names = vec![];
+    for a in &sig.inputs {
+        if let syn::FnArg::Typed(ref arg) = a {
+            types.push(arg.ty.clone());
+
+            if let syn::Pat::Ident(_) = &*arg.pat {
+                names.push(arg.pat.clone());
+            } else {
+                return Err(syn::Error::new(sig.span(), "Cannot memoize arbitrary patterns!"));
+            }
+        }
+    }
+    Ok((types, names))
+}
+
 #[cfg(test)]
 mod tests {}