omaha_client/storage/
memory.rs1use super::*;
10use futures::future::BoxFuture;
11use futures::prelude::*;
12use std::collections::HashMap;
13use thiserror::Error;
14
15#[derive(Debug)]
18pub struct MemStorage {
19 data: HashMap<String, Value>,
21
22 committed: bool,
24}
25
26#[derive(Debug)]
28enum Value {
29 String(String),
30 Int(i64),
31 Bool(bool),
32}
33
34#[derive(Debug, Error)]
36pub enum StorageErrors {
37 #[error("Unknown error occurred")]
38 Unknown,
39}
40
41impl MemStorage {
42 pub fn new() -> Self {
43 MemStorage { data: HashMap::new(), committed: true }
44 }
45
46 pub fn committed(&self) -> bool {
47 self.committed
48 }
49
50 pub fn len(&self) -> usize {
51 self.data.len()
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.data.is_empty()
56 }
57}
58
59impl Default for MemStorage {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl Storage for MemStorage {
66 type Error = StorageErrors;
67
68 fn get_string<'a>(&'a self, key: &'a str) -> BoxFuture<'a, Option<String>> {
70 future::ready(match self.data.get(key) {
71 Some(Value::String(s)) => Some(s.clone()),
72 _ => None,
73 })
74 .boxed()
75 }
76
77 fn get_int<'a>(&'a self, key: &'a str) -> BoxFuture<'a, Option<i64>> {
79 future::ready(match self.data.get(key) {
80 Some(Value::Int(i)) => Some(*i),
81 _ => None,
82 })
83 .boxed()
84 }
85
86 fn get_bool<'a>(&'a self, key: &'a str) -> BoxFuture<'a, Option<bool>> {
88 future::ready(match self.data.get(key) {
89 Some(Value::Bool(b)) => Some(*b),
90 _ => None,
91 })
92 .boxed()
93 }
94
95 fn set_string<'a>(
98 &'a mut self,
99 key: &'a str,
100 value: &'a str,
101 ) -> BoxFuture<'a, Result<(), Self::Error>> {
102 self.data.insert(key.to_string(), Value::String(value.to_string()));
103 self.committed = false;
104 future::ready(Ok(())).boxed()
105 }
106
107 fn set_int<'a>(
110 &'a mut self,
111 key: &'a str,
112 value: i64,
113 ) -> BoxFuture<'a, Result<(), Self::Error>> {
114 self.data.insert(key.to_string(), Value::Int(value));
115 self.committed = false;
116 future::ready(Ok(())).boxed()
117 }
118
119 fn set_bool<'a>(
122 &'a mut self,
123 key: &'a str,
124 value: bool,
125 ) -> BoxFuture<'a, Result<(), Self::Error>> {
126 self.data.insert(key.to_string(), Value::Bool(value));
127 self.committed = false;
128 future::ready(Ok(())).boxed()
129 }
130
131 fn remove<'a>(&'a mut self, key: &'a str) -> BoxFuture<'a, Result<(), Self::Error>> {
132 self.data.remove(key);
133 self.committed = false;
134 future::ready(Ok(())).boxed()
135 }
136
137 fn commit(&mut self) -> BoxFuture<'_, Result<(), Self::Error>> {
139 self.committed = true;
140 future::ready(Ok(())).boxed()
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use crate::storage::tests::*;
148 use futures::executor::block_on;
149
150 #[test]
151 fn test_set_get_remove_string() {
152 block_on(do_test_set_get_remove_string(&mut MemStorage::new()));
153 }
154
155 #[test]
156 fn test_set_get_remove_int() {
157 block_on(do_test_set_get_remove_int(&mut MemStorage::new()));
158 }
159
160 #[test]
161 fn test_set_option_int() {
162 block_on(do_test_set_option_int(&mut MemStorage::new()));
163 }
164
165 #[test]
166 fn test_set_get_remove_bool() {
167 block_on(do_test_set_get_remove_bool(&mut MemStorage::new()));
168 }
169
170 #[test]
171 fn test_set_get_remove_time() {
172 block_on(do_test_set_get_remove_time(&mut MemStorage::new()));
173 }
174
175 #[test]
176 fn test_return_none_for_wrong_value_type() {
177 block_on(do_return_none_for_wrong_value_type(&mut MemStorage::new()));
178 }
179
180 #[test]
181 fn test_ensure_no_error_remove_nonexistent_key() {
182 block_on(do_ensure_no_error_remove_nonexistent_key(&mut MemStorage::new()));
183 }
184
185 #[test]
186 fn test_committed() {
187 block_on(async {
188 let mut storage = MemStorage::new();
189 assert!(storage.committed());
190 storage.set_bool("some bool key", false).await.unwrap();
191 assert!(!storage.committed());
192 storage.commit().await.unwrap();
193 assert!(storage.committed());
194 storage.set_string("some string key", "some string").await.unwrap();
195 assert!(!storage.committed());
196 storage.set_int("some int key", 42).await.unwrap();
197 assert!(!storage.committed());
198 storage.commit().await.unwrap();
199 assert!(storage.committed());
200 });
201 }
202}