penumbra_sdk_tct/internal/
three.rs1use std::marker::PhantomData;
8
9use serde::{de::Visitor, Deserialize, Serialize};
10
11#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Derivative, Serialize)]
13#[derivative(Debug = "transparent")]
14pub struct Three<T> {
15 elems: Vec<T>,
16}
17
18impl<T: Clone> Clone for Three<T> {
21 fn clone(&self) -> Self {
22 let mut elems = Vec::with_capacity(4);
23 elems.extend(self.elems.iter().cloned());
24 Self { elems }
25 }
26}
27
28impl<T> Three<T> {
29 pub fn new() -> Self {
34 Self {
35 elems: Vec::with_capacity(4),
38 }
39 }
40
41 #[inline]
47 pub fn push(mut self, item: T) -> Result<Self, [T; 4]> {
48 self.elems.push(item);
50 debug_assert!(self.elems.len() <= 4);
52 match self.elems.try_into() {
54 Ok(elems) => Err(elems),
55 Err(elems) => Ok(Self { elems }),
56 }
57 }
58
59 #[inline]
61 #[cfg_attr(not(feature = "internal"), allow(unused))]
62 pub fn push_mut(&mut self, item: T) -> Self {
63 if let Ok(three) = std::mem::take(self).push(item) {
64 three
65 } else {
66 panic!("Three::push_unchecked: already full");
67 }
68 }
69
70 #[inline]
75 pub fn is_full(&self) -> bool {
76 self.elems.len() == 3
77 }
78
79 #[inline]
81 #[cfg_attr(not(feature = "internal"), allow(unused))]
82 pub fn is_empty(&self) -> bool {
83 self.elems.is_empty()
84 }
85
86 #[inline]
88 pub fn len(&self) -> u8 {
89 self.elems.len() as u8
90 }
91
92 #[inline]
94 pub fn iter(&self) -> impl Iterator<Item = &T> {
95 self.elems.iter()
96 }
97
98 #[inline]
100 #[allow(unused)]
101 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
102 self.elems.iter_mut()
103 }
104
105 pub fn elems(&self) -> Elems<T> {
107 match self.elems.len() {
108 0 => Elems::_0([]),
109 1 => Elems::_1([&self.elems[0]]),
110 2 => Elems::_2([&self.elems[0], &self.elems[1]]),
111 3 => Elems::_3([&self.elems[0], &self.elems[1], &self.elems[2]]),
112 _ => unreachable!("impossible for `Three` to contain more than 3 elements"),
113 }
114 }
115
116 pub fn elems_mut(&mut self) -> ElemsMut<T> {
118 match self.elems.as_mut_slice() {
119 [] => ElemsMut::_0([]),
120 [a] => ElemsMut::_1([a]),
121 [a, b] => ElemsMut::_2([a, b]),
122 [a, b, c] => ElemsMut::_3([a, b, c]),
123 _ => unreachable!("impossible for `Three` to contain more than 3 elements"),
124 }
125 }
126
127 pub fn into_elems(self) -> IntoElems<T> {
129 match self.elems.len() {
130 0 => IntoElems::_0([]),
131 1 => IntoElems::_1(if let Ok(elems) = self.elems.try_into() {
132 elems
133 } else {
134 unreachable!("already checked the length of elements")
135 }),
136 2 => IntoElems::_2(if let Ok(elems) = self.elems.try_into() {
137 elems
138 } else {
139 unreachable!("already checked the length of elements")
140 }),
141 3 => IntoElems::_3(if let Ok(elems) = self.elems.try_into() {
142 elems
143 } else {
144 unreachable!("already checked the length of elements")
145 }),
146 _ => unreachable!("impossible for `Three` to contain more than 3 elements"),
147 }
148 }
149}
150
151impl<T> Default for Three<T> {
152 fn default() -> Self {
153 Self::new()
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159pub enum Elems<'a, T> {
160 _0([&'a T; 0]),
162 _1([&'a T; 1]),
164 _2([&'a T; 2]),
166 _3([&'a T; 3]),
168}
169
170#[derive(Debug, PartialEq, Eq)]
172pub enum ElemsMut<'a, T> {
173 _0([&'a mut T; 0]),
175 _1([&'a mut T; 1]),
177 _2([&'a mut T; 2]),
179 _3([&'a mut T; 3]),
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq)]
185pub enum IntoElems<T> {
186 _0([T; 0]),
188 _1([T; 1]),
190 _2([T; 2]),
192 _3([T; 3]),
194}
195
196impl<T> From<IntoElems<T>> for Three<T> {
197 fn from(elems: IntoElems<T>) -> Self {
198 match elems {
199 IntoElems::_0(elems) => Self {
200 elems: elems.into(),
201 },
202 IntoElems::_1(elems) => Self {
203 elems: elems.into(),
204 },
205 IntoElems::_2(elems) => Self {
206 elems: elems.into(),
207 },
208 IntoElems::_3(elems) => Self {
209 elems: elems.into(),
210 },
211 }
212 }
213}
214
215impl<T> From<Three<T>> for IntoElems<T> {
216 fn from(three: Three<T>) -> Self {
217 three.into_elems()
218 }
219}
220
221struct ThreeVisitor<T>(PhantomData<T>);
222
223impl<'de, T: Deserialize<'de>> Visitor<'de> for ThreeVisitor<T> {
224 type Value = Three<T>;
225
226 fn expecting(
227 &self,
228 f: &mut std::fmt::Formatter<'_>,
229 ) -> std::result::Result<(), std::fmt::Error> {
230 write!(f, "a vector of at most 3 elements")
231 }
232
233 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
234 where
235 A: serde::de::SeqAccess<'de>,
236 {
237 let mut elems = Vec::with_capacity(4);
238 for _ in 0..=3 {
239 if let Some(elem) = seq.next_element()? {
240 elems.push(elem);
241 } else {
242 break;
243 }
244 }
245 if seq.next_element::<T>()?.is_some() {
246 return Err(serde::de::Error::invalid_length(3, &"at most 3 elements"));
247 }
248 Ok(Three { elems })
249 }
250}
251
252impl<'de, T: Deserialize<'de>> Deserialize<'de> for Three<T> {
253 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
254 where
255 D: serde::Deserializer<'de>,
256 {
257 deserializer.deserialize_seq(ThreeVisitor(PhantomData))
258 }
259}