graphcal_compiler/syntax/
non_empty.rs1use std::ops::{Index, IndexMut};
8
9use thiserror::Error;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
17pub struct NonEmpty<T> {
18 items: Vec<T>,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
23#[error("expected at least one item, got an empty vector")]
24pub struct EmptyVecError;
25
26impl<T> NonEmpty<T> {
27 #[must_use]
29 pub fn new(first: T, rest: Vec<T>) -> Self {
30 let mut items = Vec::with_capacity(1 + rest.len());
31 items.push(first);
32 items.extend(rest);
33 Self { items }
34 }
35
36 #[must_use]
38 pub fn singleton(first: T) -> Self {
39 Self { items: vec![first] }
40 }
41
42 pub fn try_from_vec(items: Vec<T>) -> Result<Self, EmptyVecError> {
48 if items.is_empty() {
49 Err(EmptyVecError)
50 } else {
51 Ok(Self { items })
52 }
53 }
54
55 #[must_use]
57 pub fn into_vec(self) -> Vec<T> {
58 self.items
59 }
60
61 #[must_use]
63 pub fn as_slice(&self) -> &[T] {
64 &self.items
65 }
66
67 #[must_use]
69 pub fn as_mut_slice(&mut self) -> &mut [T] {
70 &mut self.items
71 }
72
73 #[must_use]
75 pub const fn len(&self) -> usize {
76 self.items.len()
77 }
78
79 #[must_use]
81 pub const fn is_empty(&self) -> bool {
82 false
83 }
84
85 #[must_use]
87 pub fn first(&self) -> &T {
88 &self.items[0]
89 }
90
91 #[must_use]
93 pub fn last(&self) -> &T {
94 &self.items[self.items.len() - 1]
95 }
96
97 #[must_use]
99 pub fn split_last(&self) -> (&T, &[T]) {
100 let last_index = self.items.len() - 1;
101 (&self.items[last_index], &self.items[..last_index])
102 }
103
104 pub fn iter(&self) -> std::slice::Iter<'_, T> {
106 self.items.iter()
107 }
108
109 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
111 self.items.iter_mut()
112 }
113
114 pub fn push(&mut self, item: T) {
116 self.items.push(item);
117 }
118
119 pub fn map<U>(self, f: impl FnMut(T) -> U) -> NonEmpty<U> {
121 NonEmpty {
122 items: self.items.into_iter().map(f).collect(),
123 }
124 }
125}
126
127impl<T> TryFrom<Vec<T>> for NonEmpty<T> {
128 type Error = EmptyVecError;
129
130 fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
131 Self::try_from_vec(value)
132 }
133}
134
135impl<T> From<(T, Vec<T>)> for NonEmpty<T> {
136 fn from((first, rest): (T, Vec<T>)) -> Self {
137 Self::new(first, rest)
138 }
139}
140
141impl<T> From<T> for NonEmpty<T> {
142 fn from(first: T) -> Self {
143 Self::singleton(first)
144 }
145}
146
147impl<T> IntoIterator for NonEmpty<T> {
148 type Item = T;
149 type IntoIter = std::vec::IntoIter<T>;
150
151 fn into_iter(self) -> Self::IntoIter {
152 self.items.into_iter()
153 }
154}
155
156impl<'a, T> IntoIterator for &'a NonEmpty<T> {
157 type Item = &'a T;
158 type IntoIter = std::slice::Iter<'a, T>;
159
160 fn into_iter(self) -> Self::IntoIter {
161 self.items.iter()
162 }
163}
164
165impl<'a, T> IntoIterator for &'a mut NonEmpty<T> {
166 type Item = &'a mut T;
167 type IntoIter = std::slice::IterMut<'a, T>;
168
169 fn into_iter(self) -> Self::IntoIter {
170 self.items.iter_mut()
171 }
172}
173
174impl<T> Index<usize> for NonEmpty<T> {
175 type Output = T;
176
177 fn index(&self, index: usize) -> &Self::Output {
178 &self.items[index]
179 }
180}
181
182impl<T> IndexMut<usize> for NonEmpty<T> {
183 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
184 &mut self.items[index]
185 }
186}
187
188impl<T, const N: usize> TryFrom<[T; N]> for NonEmpty<T> {
189 type Error = EmptyVecError;
190
191 fn try_from(value: [T; N]) -> Result<Self, Self::Error> {
192 Self::try_from_vec(value.into_iter().collect())
193 }
194}