1use std::{any::type_name, convert::TryInto, marker::PhantomData};
2
3use cosmwasm_std::{
4 from_json, storage_keys::namespace_with_key, to_json_vec, StdError, StdResult, Storage,
5};
6use serde::{de::DeserializeOwned, Serialize};
7
8use crate::namespace::Namespace;
9
10const TAIL_KEY: &[u8] = b"t";
12const HEAD_KEY: &[u8] = b"h";
13
14pub struct Deque<T> {
20 namespace: Namespace,
22 item_type: PhantomData<T>,
24}
25
26impl<T> Deque<T> {
27 pub const fn new(prefix: &'static str) -> Self {
30 Self {
31 namespace: Namespace::from_static_str(prefix),
32 item_type: PhantomData,
33 }
34 }
35
36 pub fn new_dyn(prefix: impl Into<Namespace>) -> Self {
39 Self {
40 namespace: prefix.into(),
41 item_type: PhantomData,
42 }
43 }
44}
45
46impl<T: Serialize + DeserializeOwned> Deque<T> {
47 pub fn push_back(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> {
49 let pos = self.tail(storage)?;
51 self.set_unchecked(storage, pos, value)?;
52 self.set_tail(storage, pos.wrapping_add(1));
54
55 Ok(())
56 }
57
58 pub fn push_front(&self, storage: &mut dyn Storage, value: &T) -> StdResult<()> {
60 let pos = self.head(storage)?.wrapping_sub(1);
62 self.set_unchecked(storage, pos, value)?;
63 self.set_head(storage, pos);
65
66 Ok(())
67 }
68
69 pub fn pop_back(&self, storage: &mut dyn Storage) -> StdResult<Option<T>> {
71 let pos = self.tail(storage)?.wrapping_sub(1);
73 let value = self.get_unchecked(storage, pos)?;
74 if value.is_some() {
75 self.remove_unchecked(storage, pos);
76 self.set_tail(storage, pos);
78 }
79 Ok(value)
80 }
81
82 pub fn pop_front(&self, storage: &mut dyn Storage) -> StdResult<Option<T>> {
84 let pos = self.head(storage)?;
86 let value = self.get_unchecked(storage, pos)?;
87 if value.is_some() {
88 self.remove_unchecked(storage, pos);
89 self.set_head(storage, pos.wrapping_add(1));
91 }
92 Ok(value)
93 }
94
95 pub fn front(&self, storage: &dyn Storage) -> StdResult<Option<T>> {
97 let pos = self.head(storage)?;
98 self.get_unchecked(storage, pos)
99 }
100
101 pub fn back(&self, storage: &dyn Storage) -> StdResult<Option<T>> {
103 let pos = self.tail(storage)?.wrapping_sub(1);
104 self.get_unchecked(storage, pos)
105 }
106
107 #[allow(clippy::len_without_is_empty)]
109 pub fn len(&self, storage: &dyn Storage) -> StdResult<u32> {
110 Ok(calc_len(self.head(storage)?, self.tail(storage)?))
111 }
112
113 pub fn is_empty(&self, storage: &dyn Storage) -> StdResult<bool> {
115 Ok(self.len(storage)? == 0)
116 }
117
118 #[inline]
122 fn head(&self, storage: &dyn Storage) -> StdResult<u32> {
123 self.read_meta_key(storage, HEAD_KEY)
124 }
125
126 #[inline]
130 fn tail(&self, storage: &dyn Storage) -> StdResult<u32> {
131 self.read_meta_key(storage, TAIL_KEY)
132 }
133
134 #[inline]
135 fn set_head(&self, storage: &mut dyn Storage, value: u32) {
136 self.set_meta_key(storage, HEAD_KEY, value);
137 }
138
139 #[inline]
140 fn set_tail(&self, storage: &mut dyn Storage, value: u32) {
141 self.set_meta_key(storage, TAIL_KEY, value);
142 }
143
144 fn read_meta_key(&self, storage: &dyn Storage, key: &[u8]) -> StdResult<u32> {
146 let full_key = namespace_with_key(&[self.namespace.as_slice()], key);
147 storage
148 .get(&full_key)
149 .map(|vec| {
150 Ok(u32::from_be_bytes(vec.as_slice().try_into().map_err(
151 |e| StdError::msg(format!("parse error u32: {e}")),
152 )?))
153 })
154 .unwrap_or(Ok(0))
155 }
156
157 #[inline]
159 fn set_meta_key(&self, storage: &mut dyn Storage, key: &[u8], value: u32) {
160 let full_key = namespace_with_key(&[self.namespace.as_slice()], key);
161 storage.set(&full_key, &value.to_be_bytes());
162 }
163
164 pub fn get(&self, storage: &dyn Storage, pos: u32) -> StdResult<Option<T>> {
166 let head = self.head(storage)?;
167 let tail = self.tail(storage)?;
168
169 if pos >= calc_len(head, tail) {
170 return Ok(None);
172 }
173
174 let pos = head.wrapping_add(pos);
175 self.get_unchecked(storage, pos)
176 .and_then(|v| v.ok_or_else(|| StdError::msg(format!("deque position {pos} not found"))))
177 .map(Some)
178 }
179
180 pub fn set(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> {
182 let head = self.head(storage)?;
183 let tail = self.tail(storage)?;
184
185 if pos >= calc_len(head, tail) {
186 return Err(StdError::msg(format!("deque position {pos} not found")));
188 }
189
190 self.set_unchecked(storage, pos, value)
191 }
192
193 fn get_unchecked(&self, storage: &dyn Storage, pos: u32) -> StdResult<Option<T>> {
196 let prefixed_key = namespace_with_key(&[self.namespace.as_slice()], &pos.to_be_bytes());
197 let value = storage.get(&prefixed_key);
198 value.map(|v| from_json(v)).transpose()
199 }
200
201 fn remove_unchecked(&self, storage: &mut dyn Storage, pos: u32) {
204 let prefixed_key = namespace_with_key(&[self.namespace.as_slice()], &pos.to_be_bytes());
205 storage.remove(&prefixed_key);
206 }
207
208 fn set_unchecked(&self, storage: &mut dyn Storage, pos: u32, value: &T) -> StdResult<()> {
211 let prefixed_key = namespace_with_key(&[self.namespace.as_slice()], &pos.to_be_bytes());
212 storage.set(&prefixed_key, &to_json_vec(value)?);
213
214 Ok(())
215 }
216}
217
218#[inline]
220fn calc_len(head: u32, tail: u32) -> u32 {
221 tail.wrapping_sub(head)
222}
223
224impl<T: Serialize + DeserializeOwned> Deque<T> {
225 pub fn iter<'a>(&'a self, storage: &'a dyn Storage) -> StdResult<DequeIter<'a, T>> {
226 Ok(DequeIter {
227 deque: self,
228 storage,
229 start: self.head(storage)?,
230 end: self.tail(storage)?,
231 })
232 }
233}
234
235pub struct DequeIter<'a, T>
236where
237 T: Serialize + DeserializeOwned,
238{
239 deque: &'a Deque<T>,
240 storage: &'a dyn Storage,
241 start: u32,
242 end: u32,
243}
244
245impl<T> Iterator for DequeIter<'_, T>
246where
247 T: Serialize + DeserializeOwned,
248{
249 type Item = StdResult<T>;
250
251 fn next(&mut self) -> Option<Self::Item> {
252 if self.start == self.end {
253 return None;
254 }
255
256 let item = self
257 .deque
258 .get_unchecked(self.storage, self.start)
259 .and_then(|item| item.ok_or_else(|| StdError::msg(type_name::<T>())));
260 self.start = self.start.wrapping_add(1);
261
262 Some(item)
263 }
264
265 fn size_hint(&self) -> (usize, Option<usize>) {
266 let len = calc_len(self.start, self.end) as usize;
267 (len, Some(len))
268 }
269
270 fn nth(&mut self, n: usize) -> Option<Self::Item> {
275 if calc_len(self.start, self.end) < n as u32 {
277 self.start = self.end;
279 } else {
280 self.start = self.start.wrapping_add(n as u32);
281 }
282 self.next()
283 }
284}
285
286impl<T> DoubleEndedIterator for DequeIter<'_, T>
287where
288 T: Serialize + DeserializeOwned,
289{
290 fn next_back(&mut self) -> Option<Self::Item> {
291 if self.start == self.end {
292 return None;
293 }
294
295 let item = self
296 .deque
297 .get_unchecked(self.storage, self.end.wrapping_sub(1)) .and_then(|item| item.ok_or_else(|| StdError::msg(type_name::<T>())));
299 self.end = self.end.wrapping_sub(1);
300
301 Some(item)
302 }
303
304 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
306 if calc_len(self.start, self.end) < n as u32 {
308 self.end = self.start;
310 } else {
311 self.end = self.end.wrapping_sub(n as u32);
312 }
313 self.next_back()
314 }
315}
316#[cfg(test)]
317mod tests {
318 use crate::deque::Deque;
319
320 use cosmwasm_std::testing::MockStorage;
321 use cosmwasm_std::StdResult;
322 use serde::{Deserialize, Serialize};
323
324 #[test]
325 fn owned_key() {
326 let mut store = MockStorage::new();
327
328 for i in 1..4 {
329 let key = format!("key{i}");
330 let item = Deque::new_dyn(key);
331 for i in 0..i {
332 item.push_back(&mut store, &i).unwrap();
333 }
334 }
335
336 assert_eq!(
337 Deque::<u32>::new("key1")
338 .iter(&store)
339 .unwrap()
340 .collect::<Result<Vec<_>, _>>()
341 .unwrap(),
342 vec![0]
343 );
344 assert_eq!(
345 Deque::<u32>::new("key2")
346 .iter(&store)
347 .unwrap()
348 .collect::<Result<Vec<_>, _>>()
349 .unwrap(),
350 vec![0, 1]
351 );
352 assert_eq!(
353 Deque::<u32>::new("key3")
354 .iter(&store)
355 .unwrap()
356 .collect::<Result<Vec<_>, _>>()
357 .unwrap(),
358 vec![0, 1, 2]
359 );
360 }
361
362 #[test]
363 fn push_and_pop() {
364 const PEOPLE: Deque<String> = Deque::new("people");
365 let mut store = MockStorage::new();
366
367 PEOPLE.push_back(&mut store, &"jack".to_owned()).unwrap();
369 PEOPLE.push_back(&mut store, &"john".to_owned()).unwrap();
370 PEOPLE.push_back(&mut store, &"joanne".to_owned()).unwrap();
371
372 assert_eq!("jack", PEOPLE.pop_front(&mut store).unwrap().unwrap());
374 assert_eq!("john", PEOPLE.pop_front(&mut store).unwrap().unwrap());
375
376 PEOPLE.push_back(&mut store, &"jason".to_owned()).unwrap();
378
379 assert_eq!("joanne", PEOPLE.pop_front(&mut store).unwrap().unwrap());
381
382 assert_eq!("jason", PEOPLE.pop_front(&mut store).unwrap().unwrap());
384
385 assert_eq!(None, PEOPLE.pop_front(&mut store).unwrap());
387
388 PEOPLE.push_front(&mut store, &"pascal".to_owned()).unwrap();
390 PEOPLE.push_front(&mut store, &"peter".to_owned()).unwrap();
391 PEOPLE.push_front(&mut store, &"paul".to_owned()).unwrap();
392
393 assert_eq!("pascal", PEOPLE.pop_back(&mut store).unwrap().unwrap());
394 assert_eq!("paul", PEOPLE.pop_front(&mut store).unwrap().unwrap());
395 assert_eq!("peter", PEOPLE.pop_back(&mut store).unwrap().unwrap());
396 }
397
398 #[test]
399 fn length() {
400 let deque: Deque<u32> = Deque::new("test");
401 let mut store = MockStorage::new();
402
403 assert_eq!(deque.len(&store).unwrap(), 0);
404 assert!(deque.is_empty(&store).unwrap());
405
406 deque.push_front(&mut store, &1234).unwrap();
408 deque.push_back(&mut store, &2345).unwrap();
409 deque.push_front(&mut store, &3456).unwrap();
410 deque.push_back(&mut store, &4567).unwrap();
411 assert_eq!(deque.len(&store).unwrap(), 4);
412 assert!(!deque.is_empty(&store).unwrap());
413
414 deque.pop_front(&mut store).unwrap();
416 deque.pop_back(&mut store).unwrap();
417 deque.pop_front(&mut store).unwrap();
418 assert_eq!(deque.len(&store).unwrap(), 1);
419 assert!(!deque.is_empty(&store).unwrap());
420
421 deque.pop_front(&mut store).unwrap();
423 assert_eq!(deque.len(&store).unwrap(), 0);
424 assert!(deque.is_empty(&store).unwrap());
425
426 assert_eq!(deque.pop_back(&mut store).unwrap(), None);
428 assert_eq!(
429 deque.len(&store).unwrap(),
430 0,
431 "popping from empty deque should keep length 0"
432 );
433 assert!(deque.is_empty(&store).unwrap());
434 }
435
436 #[test]
437 fn iterator() {
438 let deque: Deque<u32> = Deque::new("test");
439 let mut store = MockStorage::new();
440
441 deque.push_back(&mut store, &1).unwrap();
443 deque.push_back(&mut store, &2).unwrap();
444 deque.push_back(&mut store, &3).unwrap();
445 deque.push_back(&mut store, &4).unwrap();
446
447 let items: StdResult<Vec<_>> = deque.iter(&store).unwrap().collect();
448 assert_eq!(items.unwrap(), [1, 2, 3, 4]);
449
450 let mut iter = deque.iter(&store).unwrap();
452 assert!(iter.nth(6).is_none());
453 assert_eq!(iter.start, iter.end, "iter should detect skipping too far");
454 assert!(iter.next().is_none());
455
456 let mut iter = deque.iter(&store).unwrap();
457 assert_eq!(iter.nth(1).unwrap().unwrap(), 2);
458 assert_eq!(iter.next().unwrap().unwrap(), 3);
459 }
460
461 #[test]
462 fn reverse_iterator() {
463 let deque: Deque<u32> = Deque::new("test");
464 let mut store = MockStorage::new();
465
466 deque.push_back(&mut store, &1).unwrap();
468 deque.push_back(&mut store, &2).unwrap();
469 deque.push_back(&mut store, &3).unwrap();
470 deque.push_back(&mut store, &4).unwrap();
471
472 let items: StdResult<Vec<_>> = deque.iter(&store).unwrap().rev().collect();
473 assert_eq!(items.unwrap(), [4, 3, 2, 1]);
474
475 let mut iter = deque.iter(&store).unwrap();
477 assert!(iter.nth_back(6).is_none());
478 assert_eq!(iter.start, iter.end, "iter should detect skipping too far");
479 assert!(iter.next_back().is_none());
480
481 let mut iter = deque.iter(&store).unwrap().rev();
482 assert_eq!(iter.nth(1).unwrap().unwrap(), 3);
483 assert_eq!(iter.next().unwrap().unwrap(), 2);
484
485 let mut iter = deque.iter(&store).unwrap();
487 assert_eq!(iter.next().unwrap().unwrap(), 1);
488 assert_eq!(iter.next_back().unwrap().unwrap(), 4);
489 assert_eq!(iter.next_back().unwrap().unwrap(), 3);
490 assert_eq!(iter.next().unwrap().unwrap(), 2);
491 assert!(iter.next().is_none());
492 assert!(iter.next_back().is_none());
493 }
494
495 #[test]
496 fn wrapping() {
497 let deque: Deque<u32> = Deque::new("test");
498 let mut store = MockStorage::new();
499
500 deque.set_head(&mut store, u32::MAX);
502 deque.set_tail(&mut store, u32::MAX);
503
504 assert_eq!(deque.pop_front(&mut store).unwrap(), None);
506 assert_eq!(deque.len(&store).unwrap(), 0);
507
508 deque.push_back(&mut store, &1).unwrap();
510 assert_eq!(
511 deque.len(&store).unwrap(),
512 1,
513 "length should calculate correctly, even when wrapping"
514 );
515 assert_eq!(
516 deque.pop_front(&mut store).unwrap(),
517 Some(1),
518 "popping should work, even when wrapping"
519 );
520 }
521
522 #[test]
523 fn wrapping_iterator() {
524 let deque: Deque<u32> = Deque::new("test");
525 let mut store = MockStorage::new();
526
527 deque.set_head(&mut store, u32::MAX);
528 deque.set_tail(&mut store, u32::MAX);
529
530 deque.push_back(&mut store, &1).unwrap();
531 deque.push_back(&mut store, &2).unwrap();
532 deque.push_back(&mut store, &3).unwrap();
533 deque.push_back(&mut store, &4).unwrap();
534 deque.push_back(&mut store, &5).unwrap();
535
536 let mut iter = deque.iter(&store).unwrap();
537 assert_eq!(iter.next().unwrap().unwrap(), 1);
538 assert_eq!(iter.next().unwrap().unwrap(), 2);
539 assert_eq!(iter.next_back().unwrap().unwrap(), 5);
540 assert_eq!(iter.nth(1).unwrap().unwrap(), 4);
541 assert!(iter.nth(1).is_none());
542 assert_eq!(iter.start, iter.end);
543 }
544
545 #[test]
546 fn front_back() {
547 let deque: Deque<u64> = Deque::new("test");
548 let mut store = MockStorage::new();
549
550 assert_eq!(deque.back(&store).unwrap(), None);
551 deque.push_back(&mut store, &1).unwrap();
552 assert_eq!(deque.back(&store).unwrap(), Some(1));
553 assert_eq!(deque.front(&store).unwrap(), Some(1));
554 deque.push_back(&mut store, &2).unwrap();
555 assert_eq!(deque.back(&store).unwrap(), Some(2));
556 assert_eq!(deque.front(&store).unwrap(), Some(1));
557 deque.push_front(&mut store, &3).unwrap();
558 assert_eq!(deque.back(&store).unwrap(), Some(2));
559 assert_eq!(deque.front(&store).unwrap(), Some(3));
560 }
561
562 #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
563 struct Data {
564 pub name: String,
565 pub age: i32,
566 }
567
568 const DATA: Deque<Data> = Deque::new("data");
569
570 #[test]
571 fn readme_works() -> StdResult<()> {
572 let mut store = MockStorage::new();
573
574 let empty = DATA.front(&store)?;
576 assert_eq!(None, empty);
577
578 let p1 = Data {
580 name: "admin".to_string(),
581 age: 1234,
582 };
583 let p2 = Data {
584 name: "user".to_string(),
585 age: 123,
586 };
587
588 DATA.push_back(&mut store, &p1)?;
590 DATA.push_back(&mut store, &p2)?;
591
592 let admin = DATA.pop_front(&mut store)?;
593 assert_eq!(admin.as_ref(), Some(&p1));
594 let user = DATA.pop_front(&mut store)?;
595 assert_eq!(user.as_ref(), Some(&p2));
596
597 DATA.push_back(&mut store, &p1)?;
599 DATA.push_back(&mut store, &p2)?;
600
601 let user = DATA.pop_back(&mut store)?;
602 assert_eq!(user.as_ref(), Some(&p2));
603 let admin = DATA.pop_back(&mut store)?;
604 assert_eq!(admin.as_ref(), Some(&p1));
605
606 DATA.push_front(&mut store, &p1)?;
608 DATA.push_front(&mut store, &p2)?;
609
610 let all: StdResult<Vec<_>> = DATA.iter(&store)?.collect();
611 assert_eq!(all?, [p2.clone(), p1.clone()]);
612
613 assert_eq!(DATA.get(&store, 0)?, Some(p2));
615 assert_eq!(DATA.get(&store, 1)?, Some(p1));
616 assert_eq!(DATA.get(&store, 3)?, None);
617
618 Ok(())
619 }
620
621 #[test]
622 fn iterator_errors_when_item_missing() {
623 let mut store = MockStorage::new();
624
625 let deque = Deque::new("error_test");
626
627 deque.push_back(&mut store, &1u32).unwrap();
628 deque.remove_unchecked(&mut store, 0);
630
631 let mut iter = deque.iter(&store).unwrap();
632
633 assert_eq!(
634 "kind: Other, error: u32",
635 iter.next().unwrap().unwrap_err().to_string(),
636 "iterator should error when item is missing"
637 );
638
639 let mut iter = deque.iter(&store).unwrap().rev();
640
641 assert_eq!(
642 "kind: Other, error: u32",
643 iter.next().unwrap().unwrap_err().to_string(),
644 "reverse iterator should error when item is missing"
645 );
646 }
647
648 #[test]
649 fn get() {
650 let mut store = MockStorage::new();
651
652 let deque = Deque::new("test");
653
654 deque.push_back(&mut store, &1u32).unwrap();
655 deque.push_back(&mut store, &2).unwrap();
656
657 assert_eq!(deque.get(&store, 0).unwrap(), Some(1));
658 assert_eq!(deque.get(&store, 1).unwrap(), Some(2));
659 assert_eq!(
660 deque.get(&store, 2).unwrap(),
661 None,
662 "out of bounds access should return None"
663 );
664
665 deque.remove_unchecked(&mut store, 1);
667
668 assert_eq!(
669 "kind: Other, error: deque position 1 not found",
670 deque.get(&store, 1).unwrap_err().to_string(),
671 "missing deque item should error"
672 );
673
674 let deque = Deque::new("test2");
676
677 deque.push_back(&mut store, &0u32).unwrap();
678 deque.push_back(&mut store, &1).unwrap();
679 deque.push_front(&mut store, &u32::MAX).unwrap();
681 deque.push_front(&mut store, &(u32::MAX - 1)).unwrap();
682
683 assert_eq!(deque.get(&store, 0).unwrap().unwrap(), u32::MAX - 1);
684 assert_eq!(deque.get(&store, 1).unwrap().unwrap(), u32::MAX);
685 assert_eq!(deque.get(&store, 2).unwrap().unwrap(), 0);
686 assert_eq!(deque.get(&store, 3).unwrap().unwrap(), 1);
687 assert_eq!(
688 deque.get(&store, 5).unwrap(),
689 None,
690 "out of bounds access should return None"
691 );
692 }
693
694 #[test]
695 fn set() {
696 let mut store = MockStorage::new();
697 let deque = Deque::new("test");
698
699 deque.push_back(&mut store, &1u32).unwrap();
700 deque.push_back(&mut store, &2).unwrap();
701
702 deque.set(&mut store, 1, &3).unwrap();
703
704 assert_eq!(deque.get(&store, 1).unwrap(), Some(3));
705 assert_eq!(deque.back(&store).unwrap(), Some(3));
706 assert_eq!(
707 deque.get(&store, 2).unwrap(),
708 None,
709 "out of bounds access should return None"
710 );
711
712 assert_eq!(
713 "kind: Other, error: deque position 2 not found",
714 deque.set(&mut store, 2, &3).unwrap_err().to_string(),
715 "setting value at an out of bounds index should error"
716 );
717
718 assert_eq!(deque.pop_back(&mut store).unwrap(), Some(3));
719
720 assert_eq!(
721 "kind: Other, error: deque position 1 not found",
722 deque.set(&mut store, 1, &3).unwrap_err().to_string(),
723 "setting value at an out of bounds index should error"
724 );
725 }
726}