1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
extern crate r2d2; extern crate r2d2_redis; extern crate redis; extern crate dns_lookup; mod error; mod memory_cache; mod redis_cache; use std::{any::Any, collections::HashMap}; use memory_cache::MemoryCache; use redis_cache::RedisCache; pub use error::CacheError; pub type Result<T> = std::result::Result<T, CacheError>; pub trait Cacheable { fn model_name() -> &'static str where Self: Sized; fn to_redis_obj(&self) -> Vec<(String, String)>; fn from_redis_obj(obj: HashMap<String, String>) -> Result<Self> where Self: Sized; fn expires_after(&self) -> Option<usize>; fn as_any(&self) -> &Any; } #[cfg(feature = "hashset")] trait HashSetAccess { fn set_insert<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<()>; fn set_contains<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<bool>; fn set_remove<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<()>; } trait CacheAccess { fn insert<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O) -> Result<()>; fn get<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<Option<O>>; fn contains_key<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<bool>; fn remove<K: ToString, O: Cacheable>(&self, key: K) -> Result<()>; } pub enum Cache { Memory(MemoryCache), Redis(RedisCache), } impl Clone for Cache { fn clone(&self) -> Self { match *self { Memory(ref c) => Memory(c.clone()), Redis(ref c) => Redis(c.clone()), } } } use Cache::*; impl Cache { pub fn insert<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K, obj: O) -> Result<()> { match *self { Memory(ref c) => c.insert(key, obj), Redis(ref c) => c.insert(key, obj), } } pub fn get<K: ToString, O: Cacheable + Clone + 'static>(&self, key: K) -> Result<Option<O>> { match *self { Memory(ref c) => c.get::<K, O>(key), Redis(ref c) => c.get::<K, O>(key), } } pub fn remove<K: ToString, O: Cacheable>(&self, key: K) -> Result<()> { match *self { Memory(ref c) => c.remove::<K, O>(key), Redis(ref c) => c.remove::<K, O>(key), } } #[cfg(feature = "hashset")] pub fn set_insert<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<()> { match *self { Memory(ref c) => c.set_insert(group_id, member), Redis(ref c) => c.set_insert(group_id, member), } } #[cfg(feature = "hashset")] pub fn set_contains<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<bool> { match *self { Memory(ref c) => c.set_contains(group_id, member), Redis(ref c) => c.set_contains(group_id, member), } } #[cfg(feature = "hashset")] pub fn set_remove<G: ToString, K: ToString>(&self, group_id: G, member: K) -> Result<()> { match *self { Memory(ref c) => c.set_remove(group_id, member), Redis(ref c) => c.set_remove(group_id, member), } } } unsafe impl Send for Cache {} unsafe impl Sync for Cache {} pub fn memory() -> Cache { Memory(MemoryCache::new()) } pub fn redis(host: &str, password: Option<&str>, db: Option<u16>) -> Result<Cache> { match RedisCache::new(host, password, db) { Ok(rc) => Ok(Redis(rc)), Err(e) => Err(e), } }