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}