changeset 17:cf5a71de7e50

Improve mishandling detection
author Lewin Bormann <lbo@spheniscida.de>
date Thu, 15 Oct 2020 20:52:24 +0200
parents 2c254214df2e
children 46dbc34d5e19
files src/lib.rs
diffstat 1 files changed, 21 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib.rs	Thu Oct 15 20:34:20 2020 +0200
+++ b/src/lib.rs	Thu Oct 15 20:52:24 2020 +0200
@@ -6,33 +6,26 @@
 use proc_macro::TokenStream;
 use quote::{self, ToTokens};
 
-trait MemoizeStore<K, V>
-where
-    K: std::hash::Hash,
-{
-    fn get(&mut self, k: &K) -> Option<&V>;
-    fn put(&mut self, k: K, v: V);
-}
-
-impl<K: std::hash::Hash + Eq + Clone, V> MemoizeStore<K, V> for std::collections::HashMap<K, V> {
-    fn get(&mut self, k: &K) -> Option<&V> {
-        std::collections::HashMap::<K, V>::get(self, k)
-    }
-    fn put(&mut self, k: K, v: V) {
-        self.insert(k, v);
-    }
-}
-
+// This implementation of the storage backend does not depend on any more crates.
 #[cfg(not(feature = "full"))]
 mod store {
     use proc_macro::TokenStream;
 
     /// Returns tokenstreams (for quoting) of the store type and an expression to initialize it.
     pub fn construct_cache(
-        _attr: TokenStream,
+        attr: &TokenStream,
         key_type: proc_macro2::TokenStream,
         value_type: proc_macro2::TokenStream,
     ) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) {
+        if !attr.is_empty() {
+            return (
+                syn::Error::new_spanned(proc_macro2::TokenStream::from(attr.clone()),
+                    "memoize error: Attributes are specified, but the feature 'full' is not enabled! To fix this, compile with `--features=full`.",
+                )
+                .to_compile_error(),
+                proc_macro2::TokenStream::new(),
+            );
+        }
         // This is the unbounded default.
         (
             quote::quote! { std::collections::HashMap<#key_type, #value_type> },
@@ -49,21 +42,12 @@
     }
 }
 
+// This implementation of the storage backend also depends on the `lru` crate.
 #[cfg(feature = "full")]
 mod store {
-    use super::MemoizeStore;
     use proc_macro::TokenStream;
     use syn::parse as p;
 
-    impl<K: std::hash::Hash + Eq + Clone, V> MemoizeStore<K, V> for lru::LruCache<K, V> {
-        fn get(&mut self, k: &K) -> Option<&V> {
-            lru::LruCache::<K, V>::get(self, k)
-        }
-        fn put(&mut self, k: K, v: V) {
-            lru::LruCache::<K, V>::put(self, k, v);
-        }
-    }
-
     #[derive(Default, Debug, Clone)]
     struct CacheOptions {
         lru_max_entries: Option<usize>,
@@ -119,7 +103,7 @@
         // This is the unbounded default.
         match options.lru_max_entries {
             None => (quote::quote! { insert }, quote::quote! { get }),
-            Some(cap) => (quote::quote! { put }, quote::quote! { get }),
+            Some(_) => (quote::quote! { put }, quote::quote! { get }),
         }
     }
 }
@@ -153,10 +137,16 @@
  * If you need to use the un-memoized function, it is always available as `memoized_original_{fn}`,
  * in this case: `memoized_original_hello()`.
  *
+ * See the `examples` for concrete applications.
+ *
+ * *The following descriptions need the `full` feature enabled.*
+ *
  * The `memoize` attribute can take further parameters in order to use an LRU cache:
- * `#[memoize(Capacity: 1234)]`.
+ * `#[memoize(Capacity: 1234)]`. In that case, instead of a `HashMap` we use an `lru::LruCache`
+ * with the given capacity.
  *
- * See the `examples` for concrete applications.
+ * This mechanism can, in principle, be extended (in the source code) to any other cache mechanism.
+ *
  */
 #[proc_macro_attribute]
 pub fn memoize(attr: TokenStream, item: TokenStream) -> TokenStream {