Skip to main content

telltale_language/ast/
non_empty.rs

1//! Non-empty collection utilities for protocol ASTs.
2
3use std::fmt;
4use std::ops::Deref;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct NonEmptyError;
8
9impl fmt::Display for NonEmptyError {
10    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11        f.write_str("collection must be non-empty")
12    }
13}
14
15impl std::error::Error for NonEmptyError {}
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub struct NonEmptyVec<T>(Vec<T>);
19
20impl<T> NonEmptyVec<T> {
21    pub fn new(values: Vec<T>) -> Result<Self, NonEmptyError> {
22        if values.is_empty() {
23            Err(NonEmptyError)
24        } else {
25            Ok(Self(values))
26        }
27    }
28
29    pub fn from_head_tail(head: T, tail: Vec<T>) -> Self {
30        let mut values = Vec::with_capacity(1 + tail.len());
31        values.push(head);
32        values.extend(tail);
33        Self(values)
34    }
35
36    pub fn len(&self) -> usize {
37        self.0.len()
38    }
39
40    /// NonEmptyVec is never empty by construction
41    pub fn is_empty(&self) -> bool {
42        false
43    }
44
45    pub fn first(&self) -> &T {
46        &self.0[0]
47    }
48
49    pub fn as_slice(&self) -> &[T] {
50        &self.0
51    }
52
53    pub fn into_vec(self) -> Vec<T> {
54        self.0
55    }
56
57    pub fn push(&mut self, value: T) {
58        self.0.push(value);
59    }
60}
61
62impl<T> Deref for NonEmptyVec<T> {
63    type Target = [T];
64
65    fn deref(&self) -> &Self::Target {
66        &self.0
67    }
68}
69
70impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
71    type Error = NonEmptyError;
72
73    fn try_from(values: Vec<T>) -> Result<Self, Self::Error> {
74        Self::new(values)
75    }
76}
77
78impl<T> IntoIterator for NonEmptyVec<T> {
79    type Item = T;
80    type IntoIter = std::vec::IntoIter<T>;
81
82    fn into_iter(self) -> Self::IntoIter {
83        self.0.into_iter()
84    }
85}
86
87impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
88    type Item = &'a T;
89    type IntoIter = std::slice::Iter<'a, T>;
90
91    fn into_iter(self) -> Self::IntoIter {
92        self.0.iter()
93    }
94}
95
96impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
97    type Item = &'a mut T;
98    type IntoIter = std::slice::IterMut<'a, T>;
99
100    fn into_iter(self) -> Self::IntoIter {
101        self.0.iter_mut()
102    }
103}