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() {
147            Err(())
148        } else {
149            Ok(Vec1 { items })
150        }
151    }
152}
153
154macro_rules! with_literals {
155    ($f:ident$(,)?) => {};
156    ($f:ident, [ $($N:literal),+ $(,)? ]$(,)?) => {
157        $(
158            $f!($N);
159        )+
160    };
161}
162macro_rules! impl_from_array_for_vec1 {
163    ($N:literal $(,)?) => {
164        impl<T> From<[T; $N]> for Vec1<T> {
165            fn from(items: [T; $N]) -> Self {
166                Vec1 { items: items.into() }
167            }
168        }
169    };
170}
171with_literals!(impl_from_array_for_vec1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
172
173#[cfg(test)]
174mod tests {
175    use crate::experimental::vec1::Vec1;
176
177    #[test]
178    fn vec1_from_item_or_head_and_tail() {
179        let xs = Vec1::from_item(0i32);
180        assert_eq!(xs.as_slice(), &[0]);
181
182        let xs = Vec1::from_head_and_tail(0i32, []);
183        assert_eq!(xs.as_slice(), &[0]);
184
185        let xs = Vec1::from_head_and_tail(0i32, [1, 2]);
186        assert_eq!(xs.as_slice(), &[0, 1, 2]);
187    }
188
189    #[test]
190    fn vec1_ref() {
191        let mut xs = Vec1::from_item(0i32);
192        assert_eq!(xs.as_slice(), &[0]);
193        assert_eq!(xs.as_ref(), &[0]);
194        assert_eq!(xs.as_mut_slice(), &mut [0]);
195        assert_eq!(xs.as_mut(), &mut [0]);
196    }
197
198    #[test]
199    fn vec1_from_array() {
200        let xs = Vec1::from([0i32]);
201        assert_eq!(xs.as_slice(), &[0]);
202
203        let xs = Vec1::from([0i32, 1, 2]);
204        assert_eq!(xs.as_slice(), &[0, 1, 2]);
205    }
206
207    #[test]
208    fn vec1_try_from_vec() {
209        let xs = Vec1::<i32>::try_from(vec![]);
210        assert!(xs.is_err());
211
212        let xs = Vec1::try_from(vec![0i32]).unwrap();
213        assert_eq!(xs.as_slice(), &[0]);
214
215        let xs = Vec1::try_from(vec![0i32, 1, 2]).unwrap();
216        assert_eq!(xs.as_slice(), &[0, 1, 2]);
217    }
218
219    #[test]
220    fn vec1_try_from_iter() {
221        let xs = Vec1::<i32>::try_from_iter([]);
222        assert!(xs.is_err());
223
224        let xs = Vec1::try_from_iter([0i32]).unwrap();
225        assert_eq!(xs.as_slice(), &[0]);
226
227        let xs = Vec1::try_from_iter([0i32, 1, 2]).unwrap();
228        assert_eq!(xs.as_slice(), &[0, 1, 2]);
229    }
230
231    #[test]
232    fn vec1_iter() {
233        let xs = Vec1::from([0i32, 1, 2]);
234        let ys: Vec<_> = xs.iter().map(|x| x + 1).collect();
235        assert_eq!(ys.as_slice(), &[1, 2, 3]);
236    }
237
238    #[test]
239    fn vec1_map_into() {
240        let xs = Vec1::from([0i32, 1, 2]);
241        let ys = xs.map_into(|x| x + 1);
242        assert_eq!(ys.as_slice(), &[1, 2, 3]);
243    }
244
245    #[test]
246    fn vec1_try_map_ref() {
247        let xs = Vec1::from([0i32, 1, 2]);
248        let ys: Result<_, ()> = xs.try_map_ref(|x| Ok(*x + 1));
249        assert_eq!(ys.unwrap().as_slice(), &[1, 2, 3]);
250    }
251
252    #[test]
253    fn vec1_try_map_mut() {
254        let mut xs = Vec1::from([0i32, 1, 2]);
255        let ys: Result<_, ()> = xs.try_map_mut(|x| Ok(*x + 1));
256        assert_eq!(ys.unwrap().as_slice(), &[1, 2, 3]);
257    }
258}