1use crate::{
14 arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error,
15 ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer,
16};
17use core::cmp::Ordering;
18
19#[cfg(feature = "alloc")]
20use {alloc::vec::Vec, core::slice};
21
22#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
29pub struct SetOf<T, const N: usize>
30where
31 T: DerOrd,
32{
33 inner: ArrayVec<T, N>,
34}
35
36impl<T, const N: usize> SetOf<T, N>
37where
38 T: DerOrd,
39{
40 pub fn new() -> Self {
42 Self {
43 inner: ArrayVec::default(),
44 }
45 }
46
47 pub fn add(&mut self, new_elem: T) -> Result<()> {
52 if let Some(last_elem) = self.inner.last() {
54 if new_elem.der_cmp(last_elem)? != Ordering::Greater {
55 return Err(ErrorKind::SetOrdering.into());
56 }
57 }
58
59 self.inner.add(new_elem)
60 }
61
62 pub fn get(&self, index: usize) -> Option<&T> {
64 self.inner.get(index)
65 }
66
67 pub fn iter(&self) -> SetOfIter<'_, T> {
69 SetOfIter {
70 inner: self.inner.iter(),
71 }
72 }
73
74 pub fn is_empty(&self) -> bool {
76 self.inner.is_empty()
77 }
78
79 pub fn len(&self) -> usize {
81 self.inner.len()
82 }
83}
84
85impl<T, const N: usize> Default for SetOf<T, N>
86where
87 T: DerOrd,
88{
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
95where
96 T: Decode<'a> + DerOrd,
97{
98 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
99 reader.read_nested(header.length, |reader| {
100 let mut result = Self::new();
101
102 while !reader.is_finished() {
103 result.inner.add(T::decode(reader)?)?;
104 }
105
106 der_sort(result.inner.as_mut())?;
107 validate(result.inner.as_ref())?;
108 Ok(result)
109 })
110 }
111}
112
113impl<'a, T, const N: usize> EncodeValue for SetOf<T, N>
114where
115 T: 'a + Decode<'a> + Encode + DerOrd,
116{
117 fn value_len(&self) -> Result<Length> {
118 self.iter()
119 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
120 }
121
122 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
123 for elem in self.iter() {
124 elem.encode(writer)?;
125 }
126
127 Ok(())
128 }
129}
130
131impl<'a, T, const N: usize> FixedTag for SetOf<T, N>
132where
133 T: Decode<'a> + DerOrd,
134{
135 const TAG: Tag = Tag::Set;
136}
137
138impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
139where
140 T: DerOrd,
141{
142 type Error = Error;
143
144 fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>> {
145 der_sort(&mut arr)?;
146
147 let mut result = SetOf::new();
148
149 for elem in arr {
150 result.add(elem)?;
151 }
152
153 Ok(result)
154 }
155}
156
157impl<T, const N: usize> ValueOrd for SetOf<T, N>
158where
159 T: DerOrd,
160{
161 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
162 iter_cmp(self.iter(), other.iter())
163 }
164}
165
166#[derive(Clone, Debug)]
168pub struct SetOfIter<'a, T> {
169 inner: arrayvec::Iter<'a, T>,
171}
172
173impl<'a, T> Iterator for SetOfIter<'a, T> {
174 type Item = &'a T;
175
176 fn next(&mut self) -> Option<&'a T> {
177 self.inner.next()
178 }
179}
180
181impl<'a, T> ExactSizeIterator for SetOfIter<'a, T> {}
182
183#[cfg(feature = "alloc")]
188#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
189#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
190pub struct SetOfVec<T>
191where
192 T: DerOrd,
193{
194 inner: Vec<T>,
195}
196
197#[cfg(feature = "alloc")]
198#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
199impl<T: DerOrd> Default for SetOfVec<T> {
200 fn default() -> Self {
201 Self {
202 inner: Default::default(),
203 }
204 }
205}
206
207#[cfg(feature = "alloc")]
208#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
209impl<T> SetOfVec<T>
210where
211 T: DerOrd,
212{
213 pub fn new() -> Self {
215 Self {
216 inner: Vec::default(),
217 }
218 }
219
220 pub fn add(&mut self, new_elem: T) -> Result<()> {
225 if let Some(last_elem) = self.inner.last() {
227 if new_elem.der_cmp(last_elem)? != Ordering::Greater {
228 return Err(ErrorKind::SetOrdering.into());
229 }
230 }
231
232 self.inner.push(new_elem);
233 Ok(())
234 }
235
236 pub fn as_slice(&self) -> &[T] {
238 self.inner.as_slice()
239 }
240
241 pub fn get(&self, index: usize) -> Option<&T> {
243 self.inner.get(index)
244 }
245
246 pub fn into_vec(self) -> Vec<T> {
248 self.inner
249 }
250
251 pub fn iter(&self) -> slice::Iter<'_, T> {
253 self.inner.iter()
254 }
255
256 pub fn is_empty(&self) -> bool {
258 self.inner.is_empty()
259 }
260
261 pub fn len(&self) -> usize {
263 self.inner.len()
264 }
265}
266
267#[cfg(feature = "alloc")]
268#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
269impl<T> AsRef<[T]> for SetOfVec<T>
270where
271 T: DerOrd,
272{
273 fn as_ref(&self) -> &[T] {
274 self.as_slice()
275 }
276}
277
278#[cfg(feature = "alloc")]
279#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
280impl<'a, T> DecodeValue<'a> for SetOfVec<T>
281where
282 T: Decode<'a> + DerOrd,
283{
284 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
285 reader.read_nested(header.length, |reader| {
286 let mut inner = Vec::new();
287
288 while !reader.is_finished() {
289 inner.push(T::decode(reader)?);
290 }
291
292 der_sort(inner.as_mut())?;
293 validate(inner.as_ref())?;
294 Ok(Self { inner })
295 })
296 }
297}
298
299#[cfg(feature = "alloc")]
300#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
301impl<'a, T> EncodeValue for SetOfVec<T>
302where
303 T: 'a + Decode<'a> + Encode + DerOrd,
304{
305 fn value_len(&self) -> Result<Length> {
306 self.iter()
307 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
308 }
309
310 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
311 for elem in self.iter() {
312 elem.encode(writer)?;
313 }
314
315 Ok(())
316 }
317}
318
319#[cfg(feature = "alloc")]
320#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
321impl<T> FixedTag for SetOfVec<T>
322where
323 T: DerOrd,
324{
325 const TAG: Tag = Tag::Set;
326}
327
328#[cfg(feature = "alloc")]
329#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
330impl<T> From<SetOfVec<T>> for Vec<T>
331where
332 T: DerOrd,
333{
334 fn from(set: SetOfVec<T>) -> Vec<T> {
335 set.into_vec()
336 }
337}
338
339#[cfg(feature = "alloc")]
340#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
341impl<T> TryFrom<Vec<T>> for SetOfVec<T>
342where
343 T: DerOrd,
344{
345 type Error = Error;
346
347 fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>> {
348 der_sort(vec.as_mut_slice())?;
350 Ok(SetOfVec { inner: vec })
351 }
352}
353
354#[cfg(feature = "alloc")]
355#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
356impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
357where
358 T: DerOrd,
359{
360 type Error = Error;
361
362 fn try_from(arr: [T; N]) -> Result<SetOfVec<T>> {
363 Vec::from(arr).try_into()
364 }
365}
366
367#[cfg(feature = "alloc")]
368#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
369impl<T> ValueOrd for SetOfVec<T>
370where
371 T: DerOrd,
372{
373 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
374 iter_cmp(self.iter(), other.iter())
375 }
376}
377
378#[allow(clippy::integer_arithmetic)]
388fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<()> {
389 for i in 0..slice.len() {
390 let mut j = i;
391
392 while j > 0 && slice[j - 1].der_cmp(&slice[j])? == Ordering::Greater {
393 slice.swap(j - 1, j);
394 j -= 1;
395 }
396 }
397
398 Ok(())
399}
400
401fn validate<T: DerOrd>(slice: &[T]) -> Result<()> {
404 if let Some(len) = slice.len().checked_sub(1) {
405 for i in 0..len {
406 let j = i.checked_add(1).ok_or(ErrorKind::Overflow)?;
407
408 match slice.get(i..=j) {
409 Some([a, b]) => {
410 if a.der_cmp(b)? != Ordering::Less {
411 return Err(ErrorKind::SetOrdering.into());
412 }
413 }
414 _ => return Err(Tag::Set.value_error()),
415 }
416 }
417 }
418
419 Ok(())
420}
421
422#[cfg(all(test, feature = "alloc"))]
423mod tests {
424 use super::{SetOf, SetOfVec};
425 use alloc::vec::Vec;
426
427 #[test]
428 fn setof_tryfrom_array() {
429 let arr = [3u16, 2, 1, 65535, 0];
430 let set = SetOf::try_from(arr).unwrap();
431 assert_eq!(
432 set.iter().cloned().collect::<Vec<u16>>(),
433 &[0, 1, 2, 3, 65535]
434 );
435 }
436
437 #[test]
438 fn setofvec_tryfrom_array() {
439 let arr = [3u16, 2, 1, 65535, 0];
440 let set = SetOfVec::try_from(arr).unwrap();
441 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
442 }
443
444 #[cfg(feature = "alloc")]
445 #[test]
446 fn setofvec_tryfrom_vec() {
447 let vec = vec![3u16, 2, 1, 65535, 0];
448 let set = SetOfVec::try_from(vec).unwrap();
449 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
450 }
451}