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 #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
52 pub fn add(&mut self, new_elem: T) -> Result<()> {
53 self.insert_ordered(new_elem)
54 }
55
56 pub fn insert(&mut self, item: T) -> Result<()> {
58 self.inner.push(item)?;
59 der_sort(self.inner.as_mut())
60 }
61
62 pub fn insert_ordered(&mut self, item: T) -> Result<()> {
67 if let Some(last) = self.inner.last() {
69 check_der_ordering(last, &item)?;
70 }
71
72 self.inner.push(item)
73 }
74
75 pub fn get(&self, index: usize) -> Option<&T> {
77 self.inner.get(index)
78 }
79
80 pub fn iter(&self) -> SetOfIter<'_, T> {
82 SetOfIter {
83 inner: self.inner.iter(),
84 }
85 }
86
87 pub fn is_empty(&self) -> bool {
89 self.inner.is_empty()
90 }
91
92 pub fn len(&self) -> usize {
94 self.inner.len()
95 }
96}
97
98impl<T, const N: usize> Default for SetOf<T, N>
99where
100 T: DerOrd,
101{
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
108where
109 T: Decode<'a> + DerOrd,
110{
111 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
112 reader.read_nested(header.length, |reader| {
113 let mut result = Self::new();
114
115 while !reader.is_finished() {
116 result.inner.push(T::decode(reader)?)?;
117 }
118
119 der_sort(result.inner.as_mut())?;
120 validate(result.inner.as_ref())?;
121 Ok(result)
122 })
123 }
124}
125
126impl<'a, T, const N: usize> EncodeValue for SetOf<T, N>
127where
128 T: 'a + Decode<'a> + Encode + DerOrd,
129{
130 fn value_len(&self) -> Result<Length> {
131 self.iter()
132 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
133 }
134
135 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136 for elem in self.iter() {
137 elem.encode(writer)?;
138 }
139
140 Ok(())
141 }
142}
143
144impl<'a, T, const N: usize> FixedTag for SetOf<T, N>
145where
146 T: Decode<'a> + DerOrd,
147{
148 const TAG: Tag = Tag::Set;
149}
150
151impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
152where
153 T: DerOrd,
154{
155 type Error = Error;
156
157 fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>> {
158 der_sort(&mut arr)?;
159
160 let mut result = SetOf::new();
161
162 for elem in arr {
163 result.insert_ordered(elem)?;
164 }
165
166 Ok(result)
167 }
168}
169
170impl<T, const N: usize> ValueOrd for SetOf<T, N>
171where
172 T: DerOrd,
173{
174 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
175 iter_cmp(self.iter(), other.iter())
176 }
177}
178
179#[derive(Clone, Debug)]
181pub struct SetOfIter<'a, T> {
182 inner: arrayvec::Iter<'a, T>,
184}
185
186impl<'a, T> Iterator for SetOfIter<'a, T> {
187 type Item = &'a T;
188
189 fn next(&mut self) -> Option<&'a T> {
190 self.inner.next()
191 }
192}
193
194impl<'a, T> ExactSizeIterator for SetOfIter<'a, T> {}
195
196#[cfg(feature = "alloc")]
201#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
202pub struct SetOfVec<T>
203where
204 T: DerOrd,
205{
206 inner: Vec<T>,
207}
208
209#[cfg(feature = "alloc")]
210impl<T: DerOrd> Default for SetOfVec<T> {
211 fn default() -> Self {
212 Self {
213 inner: Default::default(),
214 }
215 }
216}
217
218#[cfg(feature = "alloc")]
219impl<T> SetOfVec<T>
220where
221 T: DerOrd,
222{
223 pub fn new() -> Self {
225 Self {
226 inner: Vec::default(),
227 }
228 }
229
230 #[allow(clippy::should_implement_trait)]
235 pub fn from_iter<I>(iter: I) -> Result<Self>
236 where
237 I: IntoIterator<Item = T>,
238 {
239 Vec::from_iter(iter).try_into()
240 }
241
242 #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
247 pub fn add(&mut self, item: T) -> Result<()> {
248 self.insert_ordered(item)
249 }
250
251 pub fn extend<I>(&mut self, iter: I) -> Result<()>
256 where
257 I: IntoIterator<Item = T>,
258 {
259 self.inner.extend(iter);
260 der_sort(&mut self.inner)
261 }
262
263 pub fn insert(&mut self, item: T) -> Result<()> {
265 self.inner.push(item);
266 der_sort(&mut self.inner)
267 }
268
269 pub fn insert_ordered(&mut self, item: T) -> Result<()> {
274 if let Some(last) = self.inner.last() {
276 check_der_ordering(last, &item)?;
277 }
278
279 self.inner.push(item);
280 Ok(())
281 }
282
283 pub fn as_slice(&self) -> &[T] {
285 self.inner.as_slice()
286 }
287
288 pub fn get(&self, index: usize) -> Option<&T> {
290 self.inner.get(index)
291 }
292
293 pub fn into_vec(self) -> Vec<T> {
295 self.inner
296 }
297
298 pub fn iter(&self) -> slice::Iter<'_, T> {
300 self.inner.iter()
301 }
302
303 pub fn is_empty(&self) -> bool {
305 self.inner.is_empty()
306 }
307
308 pub fn len(&self) -> usize {
310 self.inner.len()
311 }
312}
313
314#[cfg(feature = "alloc")]
315impl<T> AsRef<[T]> for SetOfVec<T>
316where
317 T: DerOrd,
318{
319 fn as_ref(&self) -> &[T] {
320 self.as_slice()
321 }
322}
323
324#[cfg(feature = "alloc")]
325impl<'a, T> DecodeValue<'a> for SetOfVec<T>
326where
327 T: Decode<'a> + DerOrd,
328{
329 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
330 reader.read_nested(header.length, |reader| {
331 let mut inner = Vec::new();
332
333 while !reader.is_finished() {
334 inner.push(T::decode(reader)?);
335 }
336
337 der_sort(inner.as_mut())?;
338 validate(inner.as_ref())?;
339 Ok(Self { inner })
340 })
341 }
342}
343
344#[cfg(feature = "alloc")]
345impl<'a, T> EncodeValue for SetOfVec<T>
346where
347 T: 'a + Decode<'a> + Encode + DerOrd,
348{
349 fn value_len(&self) -> Result<Length> {
350 self.iter()
351 .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
352 }
353
354 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
355 for elem in self.iter() {
356 elem.encode(writer)?;
357 }
358
359 Ok(())
360 }
361}
362
363#[cfg(feature = "alloc")]
364impl<T> FixedTag for SetOfVec<T>
365where
366 T: DerOrd,
367{
368 const TAG: Tag = Tag::Set;
369}
370
371#[cfg(feature = "alloc")]
372impl<T> From<SetOfVec<T>> for Vec<T>
373where
374 T: DerOrd,
375{
376 fn from(set: SetOfVec<T>) -> Vec<T> {
377 set.into_vec()
378 }
379}
380
381#[cfg(feature = "alloc")]
382impl<T> TryFrom<Vec<T>> for SetOfVec<T>
383where
384 T: DerOrd,
385{
386 type Error = Error;
387
388 fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>> {
389 der_sort(vec.as_mut_slice())?;
390 Ok(SetOfVec { inner: vec })
391 }
392}
393
394#[cfg(feature = "alloc")]
395impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
396where
397 T: DerOrd,
398{
399 type Error = Error;
400
401 fn try_from(arr: [T; N]) -> Result<SetOfVec<T>> {
402 Vec::from(arr).try_into()
403 }
404}
405
406#[cfg(feature = "alloc")]
407impl<T> ValueOrd for SetOfVec<T>
408where
409 T: DerOrd,
410{
411 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
412 iter_cmp(self.iter(), other.iter())
413 }
414}
415
416#[cfg(feature = "arbitrary")]
419impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
420where
421 T: DerOrd + arbitrary::Arbitrary<'a>,
422{
423 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
424 Self::try_from(
425 u.arbitrary_iter()?
426 .collect::<std::result::Result<Vec<_>, _>>()?,
427 )
428 .map_err(|_| arbitrary::Error::IncorrectFormat)
429 }
430
431 fn size_hint(_depth: usize) -> (usize, Option<usize>) {
432 (0, None)
433 }
434}
435
436fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<()> {
438 match a.der_cmp(b)? {
439 Ordering::Less => Ok(()),
440 Ordering::Equal => Err(ErrorKind::SetDuplicate.into()),
441 Ordering::Greater => Err(ErrorKind::SetOrdering.into()),
442 }
443}
444
445#[allow(clippy::integer_arithmetic)]
455fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<()> {
456 for i in 0..slice.len() {
457 let mut j = i;
458
459 while j > 0 {
460 match slice[j - 1].der_cmp(&slice[j])? {
461 Ordering::Less => break,
462 Ordering::Equal => return Err(ErrorKind::SetDuplicate.into()),
463 Ordering::Greater => {
464 slice.swap(j - 1, j);
465 j -= 1;
466 }
467 }
468 }
469 }
470
471 Ok(())
472}
473
474fn validate<T: DerOrd>(slice: &[T]) -> Result<()> {
477 if let Some(len) = slice.len().checked_sub(1) {
478 for i in 0..len {
479 let j = i.checked_add(1).ok_or(ErrorKind::Overflow)?;
480
481 match slice.get(i..=j) {
482 Some([a, b]) => {
483 if a.der_cmp(b)? != Ordering::Less {
484 return Err(ErrorKind::SetOrdering.into());
485 }
486 }
487 _ => return Err(Tag::Set.value_error()),
488 }
489 }
490 }
491
492 Ok(())
493}
494
495#[cfg(test)]
496mod tests {
497 use super::SetOf;
498 #[cfg(feature = "alloc")]
499 use super::SetOfVec;
500 use crate::ErrorKind;
501
502 #[test]
503 fn setof_tryfrom_array() {
504 let arr = [3u16, 2, 1, 65535, 0];
505 let set = SetOf::try_from(arr).unwrap();
506 assert!(set.iter().copied().eq([0, 1, 2, 3, 65535]));
507 }
508
509 #[test]
510 fn setof_tryfrom_array_reject_duplicates() {
511 let arr = [1u16, 1];
512 let err = SetOf::try_from(arr).err().unwrap();
513 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
514 }
515
516 #[cfg(feature = "alloc")]
517 #[test]
518 fn setofvec_tryfrom_array() {
519 let arr = [3u16, 2, 1, 65535, 0];
520 let set = SetOfVec::try_from(arr).unwrap();
521 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
522 }
523
524 #[cfg(feature = "alloc")]
525 #[test]
526 fn setofvec_tryfrom_vec() {
527 let vec = vec![3u16, 2, 1, 65535, 0];
528 let set = SetOfVec::try_from(vec).unwrap();
529 assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
530 }
531
532 #[cfg(feature = "alloc")]
533 #[test]
534 fn setofvec_tryfrom_vec_reject_duplicates() {
535 let vec = vec![1u16, 1];
536 let err = SetOfVec::try_from(vec).err().unwrap();
537 assert_eq!(err.kind(), ErrorKind::SetDuplicate);
538 }
539}