sans_io_runtime/collections/
vec.rs

1/// A dynamic vector that can store elements on both the stack and the heap.
2///
3/// The `DynamicVec` struct provides a flexible vector implementation that can store elements
4/// on the stack using the `heapless::Vec` type and on the heap using the `Vec` type.
5/// It allows for efficient storage of small vectors on the stack while automatically
6/// falling back to the heap for larger vectors.
7///
8/// # Examples
9///
10/// Creating a new `DynamicVec`:
11///
12/// ```
13/// use sans_io_runtime::collections::DynamicVec;
14///
15/// let mut vec: DynamicVec<u32, 10> = DynamicVec::default();
16/// ```
17///
18/// Pushing elements into the `DynamicVec`:
19///
20/// ```
21/// use sans_io_runtime::collections::DynamicVec;
22///
23/// let mut vec: DynamicVec<u32, 10> = DynamicVec::default();
24/// vec.push(1);
25/// vec.push(2);
26/// vec.push_stack(3).unwrap();
27/// ```
28///
29/// Accessing elements in the `DynamicVec`:
30///
31/// ```
32/// use sans_io_runtime::collections::DynamicVec;
33///
34/// let mut vec: DynamicVec<u32, 10> = DynamicVec::default();
35/// vec.push(1);
36/// vec.push(2);
37/// vec.push_stack(3).unwrap();
38///
39/// assert_eq!(vec.get(0), Some(&1));
40/// assert_eq!(vec.get(1), Some(&2));
41/// assert_eq!(vec.get(2), Some(&3));
42/// ```
43#[derive(Debug)]
44pub struct DynamicVec<T, const STACK_SIZE: usize> {
45    stack: heapless::Vec<T, STACK_SIZE>,
46    heap: Vec<T>,
47}
48
49impl<T, const STACK_SIZE: usize> Default for DynamicVec<T, STACK_SIZE> {
50    fn default() -> Self {
51        Self {
52            stack: heapless::Vec::new(),
53            heap: Vec::new(),
54        }
55    }
56}
57
58#[allow(unused)]
59impl<T, const STACK_SIZE: usize> DynamicVec<T, STACK_SIZE> {
60    /// Creates a new instance of `DynamicVec` from an array of elements.
61    pub fn from<const SIZE: usize>(prepare: [T; SIZE]) -> Self {
62        let mut instance = DynamicVec::<T, STACK_SIZE>::default();
63        for item in prepare {
64            instance.push(item);
65        }
66        instance
67    }
68
69    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
70        self.stack.iter_mut().chain(self.heap.iter_mut())
71    }
72
73    pub fn iter(&self) -> impl Iterator<Item = &T> {
74        self.stack.iter().chain(self.heap.iter())
75    }
76
77    /// Get the element at the given index.
78    pub fn get(&self, index: usize) -> Option<&T> {
79        if index < self.stack.len() {
80            Some(&self.stack[index])
81        } else {
82            self.heap.get(index - self.stack.len())
83        }
84    }
85
86    /// Set the element at the given index.
87    pub fn set(&mut self, index: usize, value: T) {
88        if index < self.stack.len() {
89            self.stack[index] = value;
90        } else {
91            self.heap[index - self.stack.len()] = value;
92        }
93    }
94
95    /// Get the mutable element at the given index.
96    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
97        if index < self.stack.len() {
98            Some(&mut self.stack[index])
99        } else {
100            self.heap.get_mut(index - self.stack.len())
101        }
102    }
103
104    /// Get the mutable element at the given index or panic if not exists.
105    pub fn get_mut_or_panic(&mut self, index: usize) -> &mut T {
106        if index < self.stack.len() {
107            &mut self.stack[index]
108        } else {
109            &mut self.heap[index - self.stack.len()]
110        }
111    }
112
113    /// Push an element to the stack of the vector.
114    pub fn push_stack(&mut self, value: T) -> Result<(), T> {
115        self.stack.push(value)
116    }
117
118    /// Push an element to the stack or the heap of the vector.
119    pub fn push(&mut self, value: T) {
120        if let Err(value) = self.stack.push(value) {
121            self.heap.push(value);
122        }
123    }
124
125    /// Pops the element from the end of the vector.
126    pub fn pop(&mut self) -> Option<T> {
127        if let Some(t) = self.heap.pop() {
128            Some(t)
129        } else {
130            self.stack.pop()
131        }
132    }
133
134    pub fn last(&self) -> Option<&T> {
135        if let Some(t) = self.heap.last() {
136            Some(t)
137        } else {
138            self.stack.last()
139        }
140    }
141
142    /// Check if the vector is empty.
143    pub fn is_empty(&self) -> bool {
144        self.stack.is_empty()
145    }
146
147    /// Returns the number of elements in the vector.
148    pub fn len(&self) -> usize {
149        self.stack.len() + self.heap.len()
150    }
151}
152
153#[cfg(test)]
154mod tests {
155    use super::*;
156
157    #[test]
158    fn test_new() {
159        let vec: DynamicVec<u32, 10> = DynamicVec::default();
160        assert!(vec.is_empty());
161        assert_eq!(vec.len(), 0);
162    }
163
164    #[test]
165    fn test_from() {
166        let arr = [1, 2, 3, 4, 5];
167        let vec: DynamicVec<u32, 10> = DynamicVec::from(arr);
168        assert_eq!(vec.len(), arr.len());
169        for (i, item) in arr.iter().enumerate() {
170            assert_eq!(vec.get(i), Some(item));
171        }
172    }
173
174    #[test]
175    fn test_push() {
176        let mut vec: DynamicVec<u32, 2> = DynamicVec::default();
177        vec.push(1);
178        vec.push(2);
179        vec.push(3);
180        assert_eq!(vec.push_stack(4), Err(4));
181        assert_eq!(vec.len(), 3);
182        assert_eq!(vec.get(0), Some(&1));
183        assert_eq!(vec.get(1), Some(&2));
184        assert_eq!(vec.get(2), Some(&3));
185    }
186
187    #[test]
188    fn test_push_stack() {
189        let mut vec: DynamicVec<u32, 2> = DynamicVec::default();
190        assert_eq!(vec.push_stack(1), Ok(()));
191        assert_eq!(vec.push_stack(2), Ok(()));
192        assert_eq!(vec.push_stack(3), Err(3));
193        assert_eq!(vec.len(), 2);
194        assert_eq!(vec.get(0), Some(&1));
195        assert_eq!(vec.get(1), Some(&2));
196    }
197
198    #[test]
199    fn test_push_safe() {
200        let mut vec: DynamicVec<u32, 2> = DynamicVec::default();
201        vec.push(1);
202        vec.push(2);
203        vec.push(3);
204        assert_eq!(vec.len(), 3);
205        assert_eq!(vec.get(0), Some(&1));
206        assert_eq!(vec.get_mut_or_panic(0), &1);
207        assert_eq!(vec.get(1), Some(&2));
208        assert_eq!(vec.get_mut_or_panic(1), &2);
209        assert_eq!(vec.get(2), Some(&3));
210        assert_eq!(vec.get_mut_or_panic(2), &3);
211    }
212
213    #[test]
214    fn test_pop() {
215        let mut vec: DynamicVec<u32, 2> = DynamicVec::default();
216        vec.push(1);
217        vec.push(2);
218        assert_eq!(vec.pop(), Some(2));
219        assert_eq!(vec.pop(), Some(1));
220        assert_eq!(vec.pop(), None);
221        assert_eq!(vec.len(), 0);
222        assert!(vec.is_empty());
223    }
224}