Skip to main content

multiversx_sc/types/heap/
queue.rs

1use crate::{
2    abi::{TypeAbi, TypeAbiFrom, TypeName},
3    codec::*,
4};
5use alloc::vec::Vec;
6
7/// A simple queue struct that is able to push and pop without moving elements.
8/// New items are pushed at the end, just like for a regular Vec.
9/// When popping, instead of performing a regular Vec remove that would shift items,
10/// a start index is moved up 1 position.
11/// When serializing, items before the start index are ignored.
12pub struct Queue<T> {
13    vec: Vec<T>,
14    start: usize,
15}
16
17impl<T> Queue<T> {
18    #[inline]
19    pub fn new() -> Self {
20        Queue {
21            vec: Vec::new(),
22            start: 0,
23        }
24    }
25}
26
27impl<T> Default for Queue<T> {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl<T> Queue<T> {
34    #[inline]
35    pub fn len(&self) -> usize {
36        self.vec.len() - self.start
37    }
38
39    #[inline]
40    pub fn is_empty(&self) -> bool {
41        self.len() == 0
42    }
43
44    #[inline]
45    pub fn as_slice(&self) -> &[T] {
46        &self.vec[self.start..]
47    }
48
49    #[inline]
50    pub fn push(&mut self, value: T) {
51        self.vec.push(value);
52    }
53
54    /// Returns a reference to the first item in the queue, without removing it.
55    /// Returns None if the queue is empty.
56    pub fn peek(&self) -> Option<&T> {
57        if self.start == self.vec.len() {
58            return None;
59        }
60        let head_ref = &self.vec[self.start];
61        Some(head_ref)
62    }
63
64    /// Returns a mutable reference to the first item in the queue, without removing it.
65    /// Returns None if the queue is empty.
66    pub fn peek_mut(&mut self) -> Option<&mut T> {
67        if self.start == self.vec.len() {
68            return None;
69        }
70        let head_ref = &mut self.vec[self.start];
71        Some(head_ref)
72    }
73
74    /// Removes the first element from the queue and returns a reference to it.
75    /// Does not physically extract the element from the underlying structure.
76    /// Does nothing and returns None if the queue is empty.
77    pub fn pop(&mut self) -> Option<&T> {
78        if self.start == self.vec.len() {
79            return None;
80        }
81        let head_ref = &self.vec[self.start];
82        self.start += 1;
83        Some(head_ref)
84    }
85}
86
87/// Serializes identically to a Vec, entries before start index are ignored.
88impl<T: NestedEncode> NestedEncode for Queue<T> {
89    #[inline]
90    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
91    where
92        O: NestedEncodeOutput,
93        H: EncodeErrorHandler,
94    {
95        self.as_slice().dep_encode_or_handle_err(dest, h)
96    }
97}
98
99impl<T: NestedEncode> TopEncode for Queue<T> {
100    #[inline]
101    fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
102    where
103        O: TopEncodeOutput,
104        H: EncodeErrorHandler,
105    {
106        self.as_slice().top_encode_or_handle_err(output, h)
107    }
108}
109
110/// Deserializes like a Vec.
111impl<T: NestedDecode> NestedDecode for Queue<T> {
112    #[inline]
113    fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
114    where
115        I: NestedDecodeInput,
116        H: DecodeErrorHandler,
117    {
118        Ok(Queue {
119            vec: Vec::<T>::dep_decode_or_handle_err(input, h)?,
120            start: 0,
121        })
122    }
123}
124
125/// Deserializes like a Vec.
126impl<T: NestedDecode> TopDecode for Queue<T> {
127    fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
128    where
129        I: TopDecodeInput,
130        H: DecodeErrorHandler,
131    {
132        Ok(Queue {
133            vec: Vec::<T>::top_decode_or_handle_err(input, h)?,
134            start: 0,
135        })
136    }
137}
138
139impl<T: TypeAbi> TypeAbiFrom<Self> for Queue<T> {}
140
141impl<T: TypeAbi> TypeAbi for Queue<T> {
142    type Unmanaged = Self;
143
144    fn type_name() -> TypeName {
145        let mut repr = TypeName::from("Queue<");
146        repr.push_str(T::type_name().as_str());
147        repr.push('>');
148        repr
149    }
150}