1#![cfg(any(feature = "alloc", feature = "heapless"))]
12
13use crate::{
14 Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind, FixedTag, Header, Length,
15 Reader, Tag, ValueOrd, Writer, ord::iter_cmp,
16};
17use core::cmp::Ordering;
18
19#[cfg(feature = "alloc")]
20use alloc::vec::Vec;
21#[cfg(any(feature = "alloc", feature = "heapless"))]
22use core::slice;
23
24#[cfg(feature = "heapless")]
30#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
31pub struct SetOf<T, const N: usize>
32where
33 T: DerOrd,
34{
35 inner: heapless::Vec<T, N>,
36}
37
38#[cfg(feature = "heapless")]
39impl<T, const N: usize> SetOf<T, N>
40where
41 T: DerOrd,
42{
43 #[must_use]
45 pub fn new() -> Self {
46 Self {
47 inner: heapless::Vec::default(),
48 }
49 }
50
51 pub fn insert(&mut self, item: T) -> Result<(), Error> {
56 check_duplicate(&item, self.iter())?;
57 self.try_push(item)?;
58 der_sort(self.inner.as_mut())
59 }
60
61 pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> {
68 if let Some(last) = self.inner.last() {
70 check_der_ordering(last, &item)?;
71 }
72
73 self.try_push(item)
74 }
75
76 pub fn as_slice(&self) -> &[T] {
78 self.inner.as_slice()
79 }
80
81 pub fn get(&self, index: usize) -> Option<&T> {
83 self.inner.get(index)
84 }
85
86 pub fn into_inner(self) -> heapless::Vec<T, N> {
88 self.inner
89 }
90
91 pub fn iter(&self) -> SetOfIter<'_, T> {
93 SetOfIter {
94 inner: self.inner.iter(),
95 }
96 }
97
98 pub fn is_empty(&self) -> bool {
100 self.inner.is_empty()
101 }
102
103 pub fn len(&self) -> usize {
105 self.inner.len()
106 }
107
108 fn try_push(&mut self, item: T) -> Result<(), Error> {
112 self.inner
113 .push(item)
114 .map_err(|_| ErrorKind::Overlength.into())
115 }
116}
117
118#[cfg(feature = "heapless")]
119impl<T, const N: usize> AsRef<[T]> for SetOf<T, N>
120where
121 T: DerOrd,
122{
123 fn as_ref(&self) -> &[T] {
124 self.as_slice()
125 }
126}
127
128#[cfg(feature = "heapless")]
129impl<T, const N: usize> Default for SetOf<T, N>
130where
131 T: DerOrd,
132{
133 fn default() -> Self {
134 Self::new()
135 }
136}
137
138#[cfg(feature = "heapless")]
139impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
140where
141 T: Decode<'a> + DerOrd,
142{
143 type Error = T::Error;
144
145 fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
146 let mut result = Self::new();
147
148 while !reader.is_finished() {
149 result.try_push(T::decode(reader)?)?;
150 }
151
152 if reader.encoding_rules().is_der() {
153 der_sort(result.inner.as_mut())?;
155 }
156
157 Ok(result)
158 }
159}
160
161#[cfg(feature = "heapless")]
162impl<T, const N: usize> EncodeValue for SetOf<T, N>
163where
164 T: Encode + DerOrd,
165{
166 fn value_len(&self) -> Result<Length, Error> {
167 self.iter()
168 .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
169 }
170
171 fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
172 for elem in self.iter() {
173 elem.encode(writer)?;
174 }
175
176 Ok(())
177 }
178}
179
180#[cfg(feature = "heapless")]
181impl<T, const N: usize> FixedTag for SetOf<T, N>
182where
183 T: DerOrd,
184{
185 const TAG: Tag = Tag::Set;
186}
187
188#[cfg(feature = "heapless")]
189impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
190where
191 T: DerOrd,
192{
193 type Error = Error;
194
195 fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>, Error> {
196 der_sort(&mut arr)?;
197
198 let mut result = SetOf::new();
199
200 for elem in arr {
201 result.insert_ordered(elem)?;
202 }
203
204 Ok(result)
205 }
206}
207
208#[cfg(feature = "heapless")]
209impl<T, const N: usize> ValueOrd for SetOf<T, N>
210where
211 T: DerOrd,
212{
213 fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
214 iter_cmp(self.iter(), other.iter())
215 }
216}
217
218#[derive(Clone, Debug)]
220pub struct SetOfIter<'a, T> {
221 inner: slice::Iter<'a, T>,
223}
224
225impl<'a, T: 'a> Iterator for SetOfIter<'a, T> {
226 type Item = &'a T;
227
228 fn next(&mut self) -> Option<&'a T> {
229 self.inner.next()
230 }
231
232 fn size_hint(&self) -> (usize, Option<usize>) {
233 self.inner.size_hint()
234 }
235}
236
237impl<'a, T: 'a> ExactSizeIterator for SetOfIter<'a, T> {}
238
239#[cfg(feature = "alloc")]
244#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
245pub struct SetOfVec<T>
246where
247 T: DerOrd,
248{
249 inner: Vec<T>,
250}
251
252#[cfg(feature = "alloc")]
253impl<T: DerOrd> Default for SetOfVec<T> {
254 fn default() -> Self {
255 Self {
256 inner: Default::default(),
257 }
258 }
259}
260
261#[cfg(feature = "alloc")]
262impl<T> SetOfVec<T>
263where
264 T: DerOrd,
265{
266 #[must_use]
268 pub fn new() -> Self {
269 Self {
270 inner: Vec::default(),
271 }
272 }
273
274 #[allow(clippy::should_implement_trait)]
282 pub fn from_iter<I>(iter: I) -> Result<Self, Error>
283 where
284 I: IntoIterator<Item = T>,
285 {
286 Vec::from_iter(iter).try_into()
287 }
288
289 pub fn extend<I>(&mut self, iter: I) -> Result<(), Error>
297 where
298 I: IntoIterator<Item = T>,
299 {
300 self.inner.extend(iter);
301 der_sort(&mut self.inner)
302 }
303
304 pub fn insert(&mut self, item: T) -> Result<(), Error> {
309 check_duplicate(&item, self.iter())?;
310 self.inner.push(item);
311 der_sort(&mut self.inner)
312 }
313
314 pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> {
321 if let Some(last) = self.inner.last() {
323 check_der_ordering(last, &item)?;
324 }
325
326 self.inner.push(item);
327 Ok(())
328 }
329
330 #[must_use]
332 pub fn as_slice(&self) -> &[T] {
333 self.inner.as_slice()
334 }
335
336 #[must_use]
338 pub fn get(&self, index: usize) -> Option<&T> {
339 self.inner.get(index)
340 }
341
342 #[must_use]
344 pub fn into_vec(self) -> Vec<T> {
345 self.inner
346 }
347
348 #[must_use]
350 pub fn iter(&self) -> SetOfIter<'_, T> {
351 SetOfIter {
352 inner: self.inner.iter(),
353 }
354 }
355
356 #[must_use]
358 pub fn is_empty(&self) -> bool {
359 self.inner.is_empty()
360 }
361
362 #[must_use]
364 pub fn len(&self) -> usize {
365 self.inner.len()
366 }
367}
368
369#[cfg(feature = "alloc")]
370impl<T> AsRef<[T]> for SetOfVec<T>
371where
372 T: DerOrd,
373{
374 fn as_ref(&self) -> &[T] {
375 self.as_slice()
376 }
377}
378
379#[cfg(feature = "alloc")]
380impl<'a, T> DecodeValue<'a> for SetOfVec<T>
381where
382 T: Decode<'a> + DerOrd,
383{
384 type Error = T::Error;
385
386 fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> Result<Self, Self::Error> {
387 let mut inner = Vec::new();
388
389 while !reader.is_finished() {
390 inner.push(T::decode(reader)?);
391 }
392
393 if reader.encoding_rules().is_der() {
394 der_sort(inner.as_mut())?;
395 }
396
397 Ok(Self { inner })
398 }
399}
400
401#[cfg(feature = "alloc")]
402impl<T> EncodeValue for SetOfVec<T>
403where
404 T: Encode + DerOrd,
405{
406 fn value_len(&self) -> Result<Length, Error> {
407 self.iter()
408 .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?)
409 }
410
411 fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
412 for elem in self.iter() {
413 elem.encode(writer)?;
414 }
415
416 Ok(())
417 }
418}
419
420#[cfg(feature = "alloc")]
421impl<T> FixedTag for SetOfVec<T>
422where
423 T: DerOrd,
424{
425 const TAG: Tag = Tag::Set;
426}
427
428#[cfg(feature = "alloc")]
429impl<T> From<SetOfVec<T>> for Vec<T>
430where
431 T: DerOrd,
432{
433 fn from(set: SetOfVec<T>) -> Vec<T> {
434 set.into_vec()
435 }
436}
437
438#[cfg(feature = "alloc")]
439impl<T> TryFrom<Vec<T>> for SetOfVec<T>
440where
441 T: DerOrd,
442{
443 type Error = Error;
444
445 fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>, Error> {
446 der_sort(vec.as_mut_slice())?;
448 Ok(SetOfVec { inner: vec })
449 }
450}
451
452#[cfg(feature = "alloc")]
453impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
454where
455 T: DerOrd,
456{
457 type Error = Error;
458
459 fn try_from(arr: [T; N]) -> Result<SetOfVec<T>, Error> {
460 Vec::from(arr).try_into()
461 }
462}
463
464#[cfg(feature = "alloc")]
465impl<T> ValueOrd for SetOfVec<T>
466where
467 T: DerOrd,
468{
469 fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
470 iter_cmp(self.iter(), other.iter())
471 }
472}
473
474#[cfg(feature = "arbitrary")]
477impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
478where
479 T: DerOrd + arbitrary::Arbitrary<'a>,
480{
481 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
482 Self::try_from(u.arbitrary_iter()?.collect::<Result<Vec<_>, _>>()?)
483 .map_err(|_| arbitrary::Error::IncorrectFormat)
484 }
485
486 fn size_hint(_depth: usize) -> (usize, Option<usize>) {
487 (0, None)
488 }
489}
490
491fn check_duplicate<'a, T, I>(item: &T, iter: I) -> Result<(), Error>
494where
495 T: DerOrd + 'a,
496 I: Iterator<Item = &'a T>,
497{
498 for item2 in iter {
499 match item.der_cmp(item2)? {
500 Ordering::Less => return Ok(()), Ordering::Equal => return Err(ErrorKind::SetDuplicate.into()),
502 Ordering::Greater => continue,
503 }
504 }
505
506 Ok(())
507}
508
509fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<(), Error> {
511 match a.der_cmp(b)? {
512 Ordering::Less => Ok(()),
513 Ordering::Equal => Err(ErrorKind::SetDuplicate.into()),
514 Ordering::Greater => Err(ErrorKind::SetOrdering.into()),
515 }
516}
517
518#[allow(clippy::arithmetic_side_effects)]
528fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<(), Error> {
529 for i in 0..slice.len() {
530 let mut j = i;
531
532 while j > 0 {
533 match slice[j - 1].der_cmp(&slice[j])? {
534 Ordering::Less => break,
535 Ordering::Equal => return Err(ErrorKind::SetDuplicate.into()),
536 Ordering::Greater => {
537 slice.swap(j - 1, j);
538 j -= 1;
539 }
540 }
541 }
542 }
543
544 Ok(())
545}
546
547#[cfg(test)]
548#[allow(clippy::unwrap_used)]
549mod tests {
550 #[cfg(feature = "alloc")]
551 use super::SetOfVec;
552 use crate::ErrorKind;
553 #[cfg(feature = "heapless")]
554 use {super::SetOf, crate::DerOrd};
555
556 #[cfg(feature = "heapless")]
557 #[test]
558 fn setof_insert() {
559 let mut setof = SetOf::<u8, 10>::new();
560 setof.insert(42).unwrap();
561 assert_eq!(setof.len(), 1);
562 assert_eq!(*setof.iter().next().unwrap(), 42);
563
564 assert_eq!(
566 setof.insert(42).unwrap_err().kind(),
567 ErrorKind::SetDuplicate
568 );
569 assert_eq!(setof.len(), 1);
570 }
571
572 #[cfg(feature = "heapless")]
573 #[test]
574 fn setof_tryfrom_array() {
575 let arr = [3u16, 2, 1, 65535, 0];
576 let set = SetOf::try_from(arr).unwrap();
577 assert!(set.iter().copied().eq([0, 1, 2, 3, 65535]));
578 }
579
580 #[cfg(feature = "heapless")]
581 #[test]
582 fn setof_tryfrom_array_reject_duplicates() {
583 let arr = [1u16, 1];
584 let err = SetOf::try_from(arr).err().unwrap();
585 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
586 }
587
588 #[cfg(feature = "heapless")]
589 #[test]
590 fn setof_valueord_value_cmp() {
591 use core::cmp::Ordering;
592
593 let arr1 = [3u16, 2, 1, 5, 0];
594 let arr2 = [3u16, 2, 1, 4, 0];
595 let set1 = SetOf::try_from(arr1).unwrap();
596 let set2 = SetOf::try_from(arr2).unwrap();
597 assert_eq!(set1.der_cmp(&set2), Ok(Ordering::Greater));
598 }
599
600 #[cfg(feature = "alloc")]
601 #[test]
602 fn setofvec_insert() {
603 let mut setof = SetOfVec::new();
604 setof.insert(42).unwrap();
605 assert_eq!(setof.len(), 1);
606 assert_eq!(*setof.iter().next().unwrap(), 42);
607
608 assert_eq!(
610 setof.insert(42).unwrap_err().kind(),
611 ErrorKind::SetDuplicate
612 );
613 assert_eq!(setof.len(), 1);
614 }
615
616 #[cfg(feature = "alloc")]
617 #[test]
618 fn setofvec_tryfrom_array() {
619 let arr = [3u16, 2, 1, 65535, 0];
620 let set = SetOfVec::try_from(arr).unwrap();
621 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
622 }
623
624 #[cfg(feature = "alloc")]
625 #[test]
626 fn setofvec_tryfrom_vec() {
627 let vec = vec![3u16, 2, 1, 65535, 0];
628 let set = SetOfVec::try_from(vec).unwrap();
629 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
630 }
631
632 #[cfg(feature = "alloc")]
633 #[test]
634 fn setofvec_tryfrom_vec_reject_duplicates() {
635 let vec = vec![1u16, 1];
636 let err = SetOfVec::try_from(vec).err().unwrap();
637 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
638 }
639}