cal_redis/
lib.rs

1use bb8_redis::bb8::{Pool, PooledConnection};
2use bb8_redis::RedisConnectionManager;
3use cal_core::Account;
4use redis::AsyncCommands;
5use std::env;
6
7pub type BB8Pool = Pool<RedisConnectionManager>;
8
9#[derive(Debug)]
10pub struct CacheError {
11    pub msg: String,
12}
13
14impl CacheError {
15    pub fn new_string(s: String) -> CacheError {
16        CacheError { msg: s }
17    }
18}
19
20fn get_redis_host() -> String {
21    let name = "CAL_REDIS_HOST";
22    match env::var(name) {
23        Ok(v) => v,
24        Err(e) => panic!("${} is not set ({})", name, e),
25    }
26}
27
28pub async fn create_pool() -> Result<BB8Pool, CacheError> {
29    let host = get_redis_host();
30
31    let manager =
32        RedisConnectionManager::new(host).map_err(|e| CacheError::new_string(e.to_string()))?;
33
34    Pool::builder()
35        .build(manager)
36        .await
37        .map_err(|e| CacheError::new_string(e.to_string()))
38}
39
40async fn get_connection(
41    pool: &BB8Pool,
42) -> Result<PooledConnection<RedisConnectionManager>, CacheError> {
43    let con = pool
44        .get()
45        .await
46        .map_err(|e| CacheError::new_string(e.to_string()))?;
47    Ok(con)
48}
49
50async fn get_str(pool: &BB8Pool, key: &str) -> Result<Option<String>, CacheError> {
51    let mut con = get_connection(pool).await?;
52
53    let res: Result<Option<String>, CacheError> = con
54        .get(key)
55        .await
56        .map_err(|e| CacheError::new_string(e.to_string()));
57
58    match res {
59        Ok(r) => match r {
60            None => Ok(None),
61            Some(value) => Ok(Some(value)),
62        },
63        Err(e) => Err(e),
64    }
65}
66
67async fn get_hash(pool: &BB8Pool, key: &str, field: &str) -> Result<Option<String>, CacheError> {
68    let mut con = get_connection(pool).await?;
69
70    let res: Result<Option<String>, CacheError> = con
71        .hget(key, field)
72        .await
73        .map_err(|e| CacheError::new_string(e.to_string()));
74
75    match res {
76        Ok(r) => match r {
77            None => Ok(None),
78            Some(value) => Ok(Some(value)),
79        },
80        Err(e) => Err(e),
81    }
82}
83
84pub async fn get_account_by_ident(
85    pool: &BB8Pool,
86    key: &str,
87) -> Result<Option<Account>, CacheError> {
88    let result = get_hash(pool, "cb:accounts", key).await;
89    match result {
90        Ok(r) => match r {
91            None => Ok(None),
92            Some(value) => get_account_by_id(pool, &value).await,
93        },
94        Err(e) => Err(e),
95    }
96}
97
98pub async fn get_account_by_id(pool: &BB8Pool, key: &str) -> Result<Option<Account>, CacheError> {
99    let _key = format!("cb:account:{}", key);
100    let result = get_str(pool, key).await;
101    match result {
102        Ok(r) => match r {
103            None => Ok(None),
104            Some(value) => {
105                let account: Account = serde_json::from_str(&value).unwrap();
106                Ok(Some(account))
107            }
108        },
109        Err(e) => Err(e),
110    }
111}