1use std::collections::VecDeque;
18
19use super::container::Container;
20use super::container::ContainerPtr;
21use super::container::ContainerImpl;
22
23type Key = super::Key;
24type Value = super::Value;
25type Arguments = super::Arguments;
26type ExecResult = super::ExecResult;
27
28type Inner = VecDeque<Value>;
29
30impl super::Storage {
31 async fn list_get_container(&self, key: Key) -> ContainerPtr {
32 self.get_container(key, ||Container::List(ContainerImpl::<Inner>::new())).await
33 }
34 async fn list_try_get_container(&self, key: &Key) -> Option<ContainerPtr> {
35 self.try_get_container(key).await
36 }
37 async fn list_unwrap_container(container: &Container) -> Result<&ContainerImpl<Inner>, String> {
38 match container {
39 Container::List(ref c) => Ok(c),
40 _ => Err(format!("Unexpected container type")),
41 }
42 }
43 async fn list_unwrap_mut_container(container: &mut Container) -> Result<&mut ContainerImpl<Inner>, String> {
44 match container {
45 Container::List(ref mut c) => Ok(c),
46 _ => Err(format!("Unexpected container type")),
47 }
48 }
49 async fn list_lock<F: FnOnce(&Inner) -> ExecResult>(&self, key: Key, processor: F) -> ExecResult {
50 let c1 = self.list_get_container(key).await;
51 let c2 = c1.lock().await;
52 let c3 = Self::list_unwrap_container(&c2).await?;
53 processor(&c3.inner)
54 }
55 async fn list_lock_mut<F: FnOnce(&mut Inner) -> ExecResult>(&self, key: Key, processor: F) -> ExecResult {
56 let c1 = self.list_get_container(key).await;
57 let mut c2 = c1.lock().await;
58 let c3 = Self::list_unwrap_mut_container(&mut c2).await?;
59 processor(&mut c3.inner)
60 }
61 async fn list_try_lock_mut<F: FnOnce(&mut Inner) -> ExecResult>(&self, key: Key, processor: F) -> ExecResult {
62 match self.list_try_get_container(&key).await {
63 None => Ok(Value::Nill),
64 Some(c1) => {
65 let mut c2 = c1.lock().await;
66 let c3 = Self::list_unwrap_mut_container(&mut c2).await?;
67 processor(&mut c3.inner)
68 }
69 }
70 }
71
72 pub async fn list_len(&self, mut args: Arguments) -> ExecResult {
73 let key = Self::extract_key(args.pop_front())?;
74 self.list_lock(key, |list| -> ExecResult {
75 Ok(Value::Integer(list.len() as i64))
76 }).await
77 }
78
79 pub async fn list_lpush(&self, mut args: Arguments) -> ExecResult {
80 let key = Self::extract_key(args.pop_front())?;
81 self.list_lock_mut(key, |list| -> ExecResult {
82 for arg in args {
83 list.push_front(arg);
84 }
85 Ok(Value::Integer(list.len() as i64))
86 }).await
87 }
88
89 pub async fn list_rpush(&self, mut args: Arguments) -> ExecResult {
90 let key = Self::extract_key(args.pop_front())?;
91 self.list_lock_mut(key, |list| -> ExecResult {
92 for arg in args {
93 list.push_back(arg);
94 }
95 Ok(Value::Integer(list.len() as i64))
96 }).await
97 }
98
99 pub async fn list_lpushx(&self, mut args: Arguments) -> ExecResult {
100 let key = Self::extract_key(args.pop_front())?;
101 self.list_try_lock_mut(key, |list| -> ExecResult {
102 for arg in args {
103 list.push_front(arg);
104 }
105 Ok(Value::Integer(list.len() as i64))
106 }).await
107 }
108
109 pub async fn list_rpushx(&self, mut args: Arguments) -> ExecResult {
110 let key = Self::extract_key(args.pop_front())?;
111 self.list_try_lock_mut(key, |list| -> ExecResult {
112 for arg in args {
113 list.push_back(arg);
114 }
115 Ok(Value::Integer(list.len() as i64))
116 }).await
117 }
118
119 pub async fn list_lpop(&self, mut args: Arguments) -> ExecResult {
120 let key = Self::extract_key(args.pop_front())?;
121 self.list_lock_mut(key, |list| -> ExecResult {
122 match list.pop_front() {
123 Some(v) => Ok(v),
124 None => Ok(Value::Nill),
125 }
126 }).await
127 }
128
129 pub async fn list_rpop(&self, mut args: Arguments) -> ExecResult {
130 let key = Self::extract_key(args.pop_front())?;
131 self.list_lock_mut(key, |list| -> ExecResult {
132 match list.pop_back() {
133 Some(v) => Ok(v),
134 None => Ok(Value::Nill),
135 }
136 }).await
137 }
138
139 pub async fn list_rem(&self, mut args: Arguments) -> ExecResult {
140 let key = Self::extract_key(args.pop_front())?;
141 let index = Self::extract_index(args.pop_front())?;
142 self.list_lock_mut(key, |list| -> ExecResult {
143 match list.remove(index) {
144 Some(v) => Ok(v),
145 None => Err(format!("{}", "Out of index")),
146 }
147 }).await
148 }
149
150 pub async fn list_set(&self, mut args: Arguments) -> ExecResult {
151 let key = Self::extract_key(args.pop_front())?;
152 let index = Self::extract_index(args.pop_front())?;
153 let value = Self::extract(args.pop_front())?;
154 self.list_lock_mut(key, |list| -> ExecResult {
155 match list.get_mut(index) {
156 None => Err(format!("{}\r\n", "Out of index")),
157 Some(v) => {
158 let mut x = value;
159 std::mem::swap(v, &mut x);
160 Ok(x)
161 },
162 }
163 }).await
164 }
165
166 pub async fn list_index(&self, mut args: Arguments) -> ExecResult {
167 let key = Self::extract_key(args.pop_front())?;
168 let index = Self::extract_index(args.pop_front())?;
169 self.list_lock(key, |list| -> ExecResult {
170 match list.get(index) {
171 Some(v) => Ok((*v).clone()),
172 None => Err(format!("{}\r\n", "Out of index")),
173 }
174 }).await
175 }
176
177 pub async fn list_range(&self, mut args: Arguments) -> ExecResult {
178 let key = Self::extract_key(args.pop_front())?;
179 let start = Self::extract_index(args.pop_front())?;
180 let stop = Self::extract_index(args.pop_front())?;
181 self.list_lock(key, |list| -> ExecResult {
182 let start = std::cmp::min(start, list.len());
183 let end = std::cmp::min(stop+1, list.len());
184 let mut out = VecDeque::with_capacity(end - start);
185 for i in start..end {
186 if let Some(v) = list.get(i) {
187 out.push_back((*v).clone());
188 }
189 }
190 Ok(Value::Array(out))
191 }).await
192 }
193
194 pub async fn list_insert(&self, mut args: Arguments) -> ExecResult {
195 let key = Self::extract_key(args.pop_front())?;
196 let before_after = Self::extract_string(args.pop_front())?;
197 let pivot = Self::extract(args.pop_front())?;
198 let value = Self::extract(args.pop_front())?;
199 self.list_lock_mut(key, |list| -> ExecResult {
200 let shift = match &before_after.to_lowercase()[..] {
201 "before" => 0,
202 "after" => 1,
203 dir => return Err(format!("Unexpected direction {}", dir)),
204 };
205
206 let index = list.iter().position(|v| *v == pivot);
207 if let Some(index) = index {
208 list.insert(index + shift, value);
209 Ok(Value::Integer(list.len() as i64))
210 } else {
211 Ok(Value::Integer(-1))
212 }
213 }).await
214 }
215
216 pub async fn list_trim(&self, mut args: Arguments) -> ExecResult {
217 let key = Self::extract_key(args.pop_front())?;
218 let start = Self::extract_integer(args.pop_front())?;
219 let stop = Self::extract_integer(args.pop_front())?;
220 self.list_lock_mut(key, |list| -> ExecResult {
221 let start = if start < 0 {list.len() as i64 + start} else {start} as usize;
222 let start = std::cmp::min(start, list.len());
223 let stop = if stop < 0 {list.len() as i64 + stop} else {stop} as usize;
224 let stop = std::cmp::min(stop, list.len());
225 if start > stop || start >= list.len() {
226 list.clear();
227 } else if start > 0 {
228 list.rotate_left(start);
229 list.truncate(stop+1 - start);
230 } else {
231 list.truncate(stop+1);
232 }
233
234 Ok(Value::Ok)
235 }).await
236 }
237
238 pub async fn _list_rpop_lpush(&self, mut args: Arguments) -> ExecResult {
239 let source = Self::extract_key(args.pop_front())?;
240 let destination = Self::extract_key(args.pop_front())?;
241 if source == destination {
242 self.list_try_lock_mut(source, |list| -> ExecResult {
243 if let Some(v) = list.pop_back() {
244 list.push_front(v.clone());
245 Ok(v)
246 } else {
247 Ok(Value::Nill)
248 }
249 }).await
250 } else {
251 Ok(Value::Error("Should be atomic!!!".to_string()))
252 }
253 }
254}
255