Skip to main content

state_engine/
store.rs

1use crate::ports::required::{InMemoryClient, KVSClient};
2use crate::common::bit;
3use serde_json::Value;
4use std::collections::HashMap;
5
6pub struct Store<'a> {
7    in_memory: Option<&'a mut dyn InMemoryClient>,
8    kvs_client: Option<&'a mut dyn KVSClient>,
9}
10
11impl<'a> Store<'a> {
12    pub fn new() -> Self {
13        Self {
14            in_memory: None,
15            kvs_client: None,
16        }
17    }
18
19    pub fn with_in_memory(mut self, client: &'a mut dyn InMemoryClient) -> Self {
20        self.in_memory = Some(client);
21        self
22    }
23
24    pub fn with_kvs_client(mut self, client: &'a mut dyn KVSClient) -> Self {
25        self.kvs_client = Some(client);
26        self
27    }
28
29    /// Get value from store based on store_config
30    pub fn get(&self, store_config: &HashMap<String, Value>) -> Option<Value> {
31        let client = store_config.get("client")?.as_u64()?;
32
33        match client {
34            bit::CLIENT_IN_MEMORY => {
35                let in_memory = self.in_memory.as_ref()?;
36                let key = store_config.get("key")?.as_str()?;
37                in_memory.get(key)
38            }
39            bit::CLIENT_KVS => {
40                let kvs_client = self.kvs_client.as_ref()?;
41                let key = store_config.get("key")?.as_str()?;
42                let value_str = kvs_client.get(key)?;
43
44                // deserialize
45                serde_json::from_str(&value_str).ok()
46            }
47            _ => None,
48        }
49    }
50
51    /// Set value to store based on store_config
52    pub fn set(
53        &mut self,
54        store_config: &HashMap<String, Value>,
55        value: Value,
56        ttl: Option<u64>,
57    ) -> bool {
58        let client = match store_config.get("client").and_then(|v| v.as_u64()) {
59            Some(c) => c,
60            None => return false,
61        };
62
63        match client {
64            bit::CLIENT_IN_MEMORY => {
65                if let Some(in_memory) = self.in_memory.as_mut() {
66                    if let Some(key) = store_config.get("key").and_then(|v| v.as_str()) {
67                        in_memory.set(key, value);
68                        return true;
69                    }
70                }
71                false
72            }
73            bit::CLIENT_KVS => {
74                if let Some(kvs_client) = self.kvs_client.as_mut() {
75                    if let Some(key) = store_config.get("key").and_then(|v| v.as_str()) {
76                        // serialize
77                        let serialized = match serde_json::to_string(&value) {
78                            Ok(s) => s,
79                            Err(_) => return false,
80                        };
81
82                        let final_ttl =
83                            ttl.or_else(|| store_config.get("ttl").and_then(|v| v.as_u64()));
84                        return kvs_client.set(key, serialized, final_ttl);
85                    }
86                }
87                false
88            }
89            _ => false,
90        }
91    }
92
93    /// Delete value from store based on store_config
94    pub fn delete(&mut self, store_config: &HashMap<String, Value>) -> bool {
95        let client = match store_config.get("client").and_then(|v| v.as_u64()) {
96            Some(c) => c,
97            None => return false,
98        };
99
100        match client {
101            bit::CLIENT_IN_MEMORY => {
102                if let Some(in_memory) = self.in_memory.as_mut() {
103                    if let Some(key) = store_config.get("key").and_then(|v| v.as_str()) {
104                        return in_memory.delete(key);
105                    }
106                }
107                false
108            }
109            bit::CLIENT_KVS => {
110                if let Some(kvs_client) = self.kvs_client.as_mut() {
111                    if let Some(key) = store_config.get("key").and_then(|v| v.as_str()) {
112                        return kvs_client.delete(key);
113                    }
114                }
115                false
116            }
117            _ => false,
118        }
119    }
120}
121
122impl<'a> Default for Store<'a> {
123    fn default() -> Self {
124        Self::new()
125    }
126}