checked_array/
wrapper.rs

1use crate::{
2    misc::{ BufferTooSmall, RangeBoundsExt },
3    traits::{ ArrayRef, ArrayMut, ArrayAlloc, CanAlloc },
4    std::{
5        cmp::Ordering, ops::RangeBounds,
6        fmt::{ self, Debug, Formatter },
7        hash::{ Hash, Hasher },
8        slice::{ Iter as SliceIter, IterMut as SliceIterMut }
9    }
10};
11
12
13/// A wrapper for array types that exposes checked APIs only
14pub struct Array<Wrapped> {
15    /// The wrapped element
16    wrapped: Wrapped
17}
18impl<Wrapped> Array<Wrapped> {
19    /// Wraps an `array`
20    pub const fn new(array: Wrapped) -> Self {
21        Self { wrapped: array }
22    }
23
24    /// Returns the wrapped array
25    #[inline(always)]
26    pub fn into_inner(self) -> Wrapped {
27        self.wrapped
28    }
29}
30impl<Wrapped> AsRef<Array<Wrapped>> for Array<Wrapped> {
31    fn as_ref(&self) -> &Array<Wrapped> {
32        self
33    }
34}
35impl<T, Wrapped> ArrayRef<T> for Array<Wrapped> where Wrapped: AsRef<[T]> {
36    fn as_slice(&self) -> &[T] {
37        self.wrapped.as_ref()
38    }
39    fn len(&self) -> usize {
40        self.as_slice().len()
41    }
42    fn is_empty(&self) -> bool {
43        self.as_slice().is_empty()
44    }
45
46    fn get(&self, index: usize) -> Option<&T> {
47        self.as_slice().get(index)
48    }
49    fn get_n<Range>(&self, range: Range) -> Option<Array<&[T]>> where Range: RangeBounds<usize> {
50        let slice = self.as_slice();
51        let range = range.into_absolute(0, slice.len())?;
52        slice.get(range).map(Array::new)
53    }
54
55    fn first(&self) -> Option<&T> {
56        self.as_slice().first()
57    }
58    fn last(&self) -> Option<&T> {
59        self.as_slice().last()
60    }
61
62    fn iter(&self) -> SliceIter<T> {
63        self.as_slice().iter()
64    }
65
66    fn clone_to<Source>(&self, dest: &mut Source) -> Result<(), BufferTooSmall> where Source: ArrayMut<T>, T: Clone {
67        // Validate length
68        if self.len() > dest.len() {
69            Err(BufferTooSmall)?;
70        }
71
72        // Clone the source elements to dest
73        dest.iter_mut().zip(self.iter()).for_each(|(t, e)| *t = e.clone());
74        Ok(())
75    }
76}
77impl<T, Wrapped> ArrayMut<T> for Array<Wrapped> where Wrapped: AsRef<[T]> + AsMut<[T]> {
78    fn as_slice_mut(&mut self) -> &mut [T] {
79        self.wrapped.as_mut()
80    }
81
82    fn get_mut(&mut self, index: usize) -> Option<&mut T> {
83        self.as_slice_mut().get_mut(index)
84    }
85    fn get_n_mut<Range>(&mut self, range: Range) -> Option<Array<&mut [T]>> where Range: RangeBounds<usize> {
86        let slice = self.as_slice_mut();
87        let range = range.into_absolute(0, slice.len())?;
88        slice.get_mut(range).map(Array::new)
89    }
90
91    fn first_mut(&mut self) -> Option<&mut T> {
92        self.as_slice_mut().first_mut()
93    }
94    fn last_mut(&mut self) -> Option<&mut T> {
95        self.as_slice_mut().last_mut()
96    }
97
98    fn iter_mut(&mut self) -> SliceIterMut<T> {
99        self.as_slice_mut().iter_mut()
100    }
101
102    fn rotate_left(&mut self, count: usize) {
103        // Avoid division by zero
104        if self.is_empty() {
105            return;
106        }
107
108        let count = count % self.len();
109        self.as_slice_mut().rotate_left(count);
110    }
111    fn rotate_right(&mut self, count: usize) {
112        // Avoid division by zero
113        if self.is_empty() {
114            return;
115        }
116
117        let count = count % self.len();
118        self.as_slice_mut().rotate_right(count);
119    }
120    fn reverse(&mut self) {
121        self.as_slice_mut().reverse()
122    }
123}
124impl<T, Wrapped> ArrayAlloc<T> for Array<Wrapped> where Wrapped: AsRef<[T]> + AsMut<[T]> + CanAlloc<T> {
125    type Error = Wrapped::Error;
126    
127    fn alloc_new() -> Result<Self, Self::Error> {
128        Ok(Self::new(Wrapped::alloc_new()?))
129    }
130    fn alloc_clone<Source>(elements: &Source) -> Result<Self, Self::Error> where Source: ArrayRef<T>, T: Clone {
131        let mut this = Self::alloc_new()?;
132        this.push_n_back(elements)?;
133        Ok(this)
134    }
135    
136    fn grow_with(&mut self, len: usize, mut init: impl FnMut() -> T) -> Result<(), Self::Error> {
137        for _ in 0 .. len.saturating_sub(self.len()) {
138            self.push_back(init())?;
139        }
140        Ok(())
141    }
142    fn grow(&mut self, len: usize) -> Result<(), Self::Error> where T: Default {
143        self.grow_with(len, T::default)
144    }
145    fn shrink(&mut self, len: usize) -> Result<(), Self::Error> {
146        for _ in 0 .. self.len().saturating_sub(len) {
147            let _ = self.wrapped.pop()?;
148        }
149        Ok(())
150    }
151
152    fn push_front(&mut self, element: T) -> Result<(), Self::Error> {
153        self.push_back(element)?;
154        self.rotate_right(1);
155        Ok(())
156    }
157    fn push_n_front<Source>(&mut self, elements: &Source) -> Result<(), Self::Error>
158        where Source: ArrayRef<T>, T: Clone
159    {
160        self.push_n_back(elements)?;
161        self.rotate_right(elements.len());
162        Ok(())
163    }
164    fn push_back(&mut self, element: T) -> Result<(), Self::Error> {
165        self.wrapped.push(element)
166    }
167    fn push_n_back<Source>(&mut self, elements: &Source) -> Result<(), Self::Error>
168        where Source: ArrayRef<T>, T: Clone
169    {
170        elements.iter().cloned().try_for_each(|e| self.push_back(e))
171    }
172
173    fn pop_front(&mut self) -> Result<Option<T>, Self::Error> {
174        self.rotate_left(1);
175        self.pop_back()
176    }
177    fn pop_n_front(&mut self, len: usize) -> Result<Option<Self>, Self::Error> {
178        self.rotate_left(len);
179        self.pop_n_back(len)
180    }
181    fn pop_back(&mut self) -> Result<Option<T>, Self::Error> {
182        self.wrapped.pop()
183    }
184    fn pop_n_back(&mut self, len: usize) -> Result<Option<Self>, Self::Error> {
185        // Don't mutate `self` if the operation cannot succeed
186        if self.len() < len {
187            return Ok(None)
188        }
189
190        // Move element by element into the new array
191        let mut popped = Self::alloc_new()?;
192        for _ in 0 .. len {
193            let element = self.pop_back()?.expect("Failed to pop existing element?!");
194            popped.push_back(element)?;
195        }
196
197        // Reverse the order in the new array and return it
198        popped.reverse();
199        Ok(Some(popped))
200    }
201}
202// - MARK: Propagate common trait implementations
203impl<Wrapped> Debug for Array<Wrapped> where Wrapped: Debug {
204    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
205        self.wrapped.fmt(f)
206    }
207}
208impl<Wrapped> Default for Array<Wrapped> where Wrapped: Default {
209    fn default() -> Self {
210        Self { wrapped: Wrapped::default() }
211    }
212}
213impl<Wrapped> Copy for Array<Wrapped> where Wrapped: Copy {
214    /* Copy is an intrinsic marker trait; no implementation required */
215}
216impl<Wrapped> Clone for Array<Wrapped> where Wrapped: Clone {
217    fn clone(&self) -> Self {
218        Self { wrapped: self.wrapped.clone() }
219    }
220}
221impl<Wrapped> PartialEq for Array<Wrapped> where Wrapped: PartialEq {
222    fn eq(&self, other: &Self) -> bool {
223        self.wrapped.eq(&other.wrapped)
224    }
225}
226impl<Wrapped> Eq for Array<Wrapped> where Wrapped: Eq {
227    /* Copy is a marker trait; no implementation required */
228}
229impl<Wrapped> PartialOrd for Array<Wrapped> where Wrapped: PartialOrd {
230    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
231        self.wrapped.partial_cmp(&other.wrapped)
232    }
233}
234impl<Wrapped> Ord for Array<Wrapped> where Wrapped: Ord {
235    fn cmp(&self, other: &Self) -> Ordering {
236        self.wrapped.cmp(&other.wrapped)
237    }
238}
239impl<Wrapped> Hash for Array<Wrapped> where Wrapped: Hash {
240    fn hash<H: Hasher>(&self, state: &mut H) {
241        self.wrapped.hash(state)
242    }
243}
244impl<Wrapped> IntoIterator for Array<Wrapped> where Wrapped: IntoIterator {
245    type Item = Wrapped::Item;
246    type IntoIter = Wrapped::IntoIter;
247
248    fn into_iter(self) -> Self::IntoIter {
249        self.wrapped.into_iter()
250    }
251}