backhopper_core/model/
non_empty.rs1use serde::{Deserialize, Serialize, Serializer};
8use thiserror::Error;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
11#[error("a non-empty list was expected, got an empty one")]
12pub struct EmptyListError;
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize)]
15#[serde(try_from = "Vec<T>")]
16pub struct NonEmpty<T>(Vec<T>);
17
18impl<T> NonEmpty<T> {
19 #[must_use]
20 pub fn new(first: T, rest: impl IntoIterator<Item = T>) -> Self {
21 let mut items = vec![first];
22 items.extend(rest);
23 Self(items)
24 }
25
26 pub fn push(&mut self, item: T) {
27 self.0.push(item);
28 }
29
30 #[must_use]
31 pub fn first(&self) -> &T {
32 &self.0[0]
33 }
34
35 #[must_use]
36 pub fn last(&self) -> &T {
37 &self.0[self.0.len() - 1]
38 }
39
40 #[must_use]
41 pub fn as_slice(&self) -> &[T] {
42 &self.0
43 }
44
45 pub fn iter(&self) -> std::slice::Iter<'_, T> {
46 self.0.iter()
47 }
48
49 #[must_use]
50 pub fn map<U>(self, f: impl FnMut(T) -> U) -> NonEmpty<U> {
51 NonEmpty(self.0.into_iter().map(f).collect())
52 }
53
54 #[must_use]
55 pub fn into_vec(self) -> Vec<T> {
56 self.0
57 }
58
59 pub fn sort_dedup(&mut self)
61 where
62 T: Ord,
63 {
64 self.0.sort();
65 self.0.dedup();
66 }
67}
68
69impl<T> TryFrom<Vec<T>> for NonEmpty<T> {
70 type Error = EmptyListError;
71
72 fn try_from(items: Vec<T>) -> Result<Self, EmptyListError> {
73 if items.is_empty() {
74 Err(EmptyListError)
75 } else {
76 Ok(Self(items))
77 }
78 }
79}
80
81impl<T> From<NonEmpty<T>> for Vec<T> {
82 fn from(list: NonEmpty<T>) -> Self {
83 list.0
84 }
85}
86
87impl<T> AsRef<[T]> for NonEmpty<T> {
88 fn as_ref(&self) -> &[T] {
89 &self.0
90 }
91}
92
93impl<T> IntoIterator for NonEmpty<T> {
94 type Item = T;
95 type IntoIter = std::vec::IntoIter<T>;
96
97 fn into_iter(self) -> Self::IntoIter {
98 self.0.into_iter()
99 }
100}
101
102impl<'a, T> IntoIterator for &'a NonEmpty<T> {
103 type Item = &'a T;
104 type IntoIter = std::slice::Iter<'a, T>;
105
106 fn into_iter(self) -> Self::IntoIter {
107 self.0.iter()
108 }
109}
110
111impl<T: Serialize> Serialize for NonEmpty<T> {
112 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
113 self.0.serialize(serializer)
114 }
115}