windowed_stats/experimental/
vec1.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::ops::{Deref, DerefMut};
6use std::slice;
7
8/// A contiguous growable array type that contains one or more items (never zero).
9///
10/// This vector type is similar to [`Vec`], but is **never** empty and guarantees that it contains
11/// at least one item.
12///
13/// [`Vec`]: std::vec::Vec
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct Vec1<T> {
16    items: Vec<T>,
17}
18
19impl<T> Vec1<T> {
20    /// Constructs a `Vec1` from an item.
21    pub fn from_item(item: T) -> Self {
22        Vec1 { items: vec![item] }
23    }
24
25    /// Constructs a `Vec1` from a head item and zero or more tail items.
26    pub fn from_head_and_tail(head: T, tail: impl IntoIterator<Item = T>) -> Self {
27        Vec1 { items: Some(head).into_iter().chain(tail).collect() }
28    }
29
30    /// Constructs a `Vec1` from an [`IntoIterator`] of items.
31    ///
32    /// # Errors
33    ///
34    /// Returns an error if the [`IntoIterator`] is empty.
35    ///
36    /// [`IntoIterator`]: std::iter::IntoIterator
37    pub fn try_from_iter(items: impl IntoIterator<Item = T>) -> Result<Self, ()> {
38        let mut items = items.into_iter();
39        match items.next() {
40            Some(head) => Ok(Vec1::from_head_and_tail(head, items)),
41            _ => Err(()),
42        }
43    }
44
45    // TODO(https://fxbug.dev/352335343): These iterator-like operations should instead be
46    // implemented by an `Iterator1` (and arguably `Slice1`) type.
47    /// Maps the items from the vector into another.
48    pub fn map_into<U, F>(self, f: F) -> Vec1<U>
49    where
50        F: FnMut(T) -> U,
51    {
52        Vec1 { items: self.items.into_iter().map(f).collect() }
53    }
54
55    /// Fallibly maps the items in the vector by reference to either another vector or an error.
56    ///
57    /// # Errors
58    ///
59    /// Returns an error if the mapping function returns an error for some item in the vector.
60    pub fn try_map_ref<U, E, F>(&self, f: F) -> Result<Vec1<U>, E>
61    where
62        F: FnMut(&T) -> Result<U, E>,
63    {
64        self.items.iter().map(f).collect::<Result<Vec<_>, _>>().map(|items| Vec1 { items })
65    }
66
67    /// Fallibly maps the items in the vector by mutable reference to either another vector or an
68    /// error.
69    ///
70    /// # Errors
71    ///
72    /// Returns an error if the mapping function returns an error for some item in the vector.
73    pub fn try_map_mut<U, E, F>(&mut self, f: F) -> Result<Vec1<U>, E>
74    where
75        F: FnMut(&mut T) -> Result<U, E>,
76    {
77        self.items.iter_mut().map(f).collect::<Result<Vec<_>, _>>().map(|items| Vec1 { items })
78    }
79
80    /// Gets an iterator over the items in the vector.
81    pub fn iter(&self) -> slice::Iter<'_, T> {
82        self.items.iter()
83    }
84
85    /// Gets an iterator over the items in the vector.
86    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
87        self.items.iter_mut()
88    }
89
90    /// Gets a slice over the items in the vector.
91    pub fn as_slice(&self) -> &[T] {
92        self.items.as_slice()
93    }
94
95    /// Gets a slice over the items in the vector.
96    pub fn as_mut_slice(&mut self) -> &mut [T] {
97        self.items.as_mut_slice()
98    }
99}
100
101impl<T> AsMut<[T]> for Vec1<T> {
102    fn as_mut(&mut self) -> &mut [T] {
103        self.items.as_mut()
104    }
105}
106
107impl<T> AsRef<[T]> for Vec1<T> {
108    fn as_ref(&self) -> &[T] {
109        self.items.as_ref()
110    }
111}
112
113impl<T> Deref for Vec1<T> {
114    type Target = [T];
115
116    fn deref(&self) -> &Self::Target {
117        self.items.deref()
118    }
119}
120
121impl<T> DerefMut for Vec1<T> {
122    fn deref_mut(&mut self) -> &mut Self::Target {
123        self.items.deref_mut()
124    }
125}
126
127impl<T> From<Vec1<T>> for Vec<T> {
128    fn from(one_or_more: Vec1<T>) -> Self {
129        one_or_more.items
130    }
131}
132
133impl<T> IntoIterator for Vec1<T> {
134    type Item = T;
135    type IntoIter = std::vec::IntoIter<T>;
136
137    fn into_iter(self) -> Self::IntoIter {
138        self.items.into_iter()
139    }
140}
141
142impl<T> TryFrom<Vec<T>> for Vec1<T> {
143    type Error = ();
144
145    fn try_from(items: Vec<T>) -> Result<Self, Self::Error> {
146        if items.is_empty() { Err(()) } else { Ok(Vec1 { items }) }
147    }
148}
149
150macro_rules! with_literals {
151    ($f:ident$(,)?) => {};
152    ($f:ident, [ $($N:literal),+ $(,)? ]$(,)?) => {
153        $(
154            $f!($N);
155        )+
156    };
157}
158macro_rules! impl_from_array_for_vec1 {
159    ($N:literal $(,)?) => {
160        impl<T> From<[T; $N]> for Vec1<T> {
161            fn from(items: [T; $N]) -> Self {
162                Vec1 { items: items.into() }
163            }
164        }
165    };
166}
167with_literals!(impl_from_array_for_vec1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
168
169#[cfg(test)]
170mod tests {
171    use crate::experimental::vec1::Vec1;
172
173    #[test]
174    fn vec1_from_item_or_head_and_tail() {
175        let xs = Vec1::from_item(0i32);
176        assert_eq!(xs.as_slice(), &[0]);
177
178        let xs = Vec1::from_head_and_tail(0i32, []);
179        assert_eq!(xs.as_slice(), &[0]);
180
181        let xs = Vec1::from_head_and_tail(0i32, [1, 2]);
182        assert_eq!(xs.as_slice(), &[0, 1, 2]);
183    }
184
185    #[test]
186    fn vec1_ref() {
187        let mut xs = Vec1::from_item(0i32);
188        assert_eq!(xs.as_slice(), &[0]);
189        assert_eq!(xs.as_ref(), &[0]);
190        assert_eq!(xs.as_mut_slice(), &mut [0]);
191        assert_eq!(xs.as_mut(), &mut [0]);
192    }
193
194    #[test]
195    fn vec1_from_array() {
196        let xs = Vec1::from([0i32]);
197        assert_eq!(xs.as_slice(), &[0]);
198
199        let xs = Vec1::from([0i32, 1, 2]);
200        assert_eq!(xs.as_slice(), &[0, 1, 2]);
201    }
202
203    #[test]
204    fn vec1_try_from_vec() {
205        let xs = Vec1::<i32>::try_from(vec![]);
206        assert!(xs.is_err());
207
208        let xs = Vec1::try_from(vec![0i32]).unwrap();
209        assert_eq!(xs.as_slice(), &[0]);
210
211        let xs = Vec1::try_from(vec![0i32, 1, 2]).unwrap();
212        assert_eq!(xs.as_slice(), &[0, 1, 2]);
213    }
214
215    #[test]
216    fn vec1_try_from_iter() {
217        let xs = Vec1::<i32>::try_from_iter([]);
218        assert!(xs.is_err());
219
220        let xs = Vec1::try_from_iter([0i32]).unwrap();
221        assert_eq!(xs.as_slice(), &[0]);
222
223        let xs = Vec1::try_from_iter([0i32, 1, 2]).unwrap();
224        assert_eq!(xs.as_slice(), &[0, 1, 2]);
225    }
226
227    #[test]
228    fn vec1_iter() {
229        let xs = Vec1::from([0i32, 1, 2]);
230        let ys: Vec<_> = xs.iter().map(|x| x + 1).collect();
231        assert_eq!(ys.as_slice(), &[1, 2, 3]);
232    }
233
234    #[test]
235    fn vec1_map_into() {
236        let xs = Vec1::from([0i32, 1, 2]);
237        let ys = xs.map_into(|x| x + 1);
238        assert_eq!(ys.as_slice(), &[1, 2, 3]);
239    }
240
241    #[test]
242    fn vec1_try_map_ref() {
243        let xs = Vec1::from([0i32, 1, 2]);
244        let ys: Result<_, ()> = xs.try_map_ref(|x| Ok(*x + 1));
245        assert_eq!(ys.unwrap().as_slice(), &[1, 2, 3]);
246    }
247
248    #[test]
249    fn vec1_try_map_mut() {
250        let mut xs = Vec1::from([0i32, 1, 2]);
251        let ys: Result<_, ()> = xs.try_map_mut(|x| Ok(*x + 1));
252        assert_eq!(ys.unwrap().as_slice(), &[1, 2, 3]);
253    }
254}