Mercurial > lbo > hg > memoize
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 {}