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