asn1_rs/asn1_types/set/
hashset.rs

1#![cfg(feature = "std")]
2use crate::*;
3use core::fmt::Debug;
4use std::collections::HashSet;
5use std::convert::TryFrom;
6use std::hash::Hash;
7
8use self::debug::{trace, trace_generic};
9
10impl<T> Tagged for HashSet<T> {
11    const TAG: Tag = Tag::Set;
12}
13
14impl<'a, T> TryFrom<Any<'a>> for HashSet<T>
15where
16    T: FromBer<'a>,
17    T: Hash + Eq,
18{
19    type Error = Error;
20
21    fn try_from(any: Any<'a>) -> Result<Self> {
22        any.tag().assert_eq(Self::TAG)?;
23        any.header.assert_constructed()?;
24        let items = SetIterator::<T, BerParser>::new(any.data).collect::<Result<HashSet<T>>>()?;
25        Ok(items)
26    }
27}
28
29impl<T> CheckDerConstraints for HashSet<T>
30where
31    T: CheckDerConstraints,
32{
33    fn check_constraints(any: &Any) -> Result<()> {
34        any.tag().assert_eq(Self::TAG)?;
35        any.header.assert_constructed()?;
36        for item in SetIterator::<Any, DerParser>::new(any.data) {
37            let item = item?;
38            T::check_constraints(&item)?;
39        }
40        Ok(())
41    }
42}
43
44/// manual impl of FromDer, so we do not need to require `TryFrom<Any> + CheckDerConstraints`
45impl<'a, T, E> FromDer<'a, E> for HashSet<T>
46where
47    T: FromDer<'a, E>,
48    T: Hash + Eq,
49    E: From<Error> + Debug,
50{
51    fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, E> {
52        trace_generic(
53            core::any::type_name::<Self>(),
54            "BTreeSet::from_der",
55            |bytes| {
56                let (rem, any) = trace(core::any::type_name::<Self>(), Any::from_der, bytes)
57                    .map_err(Err::convert)?;
58                any.tag()
59                    .assert_eq(Self::TAG)
60                    .map_err(|e| Err::Error(e.into()))?;
61                any.header
62                    .assert_constructed()
63                    .map_err(|e| Err::Error(e.into()))?;
64                let items = SetIterator::<T, DerParser, E>::new(any.data)
65                    .collect::<Result<HashSet<T>, E>>()
66                    .map_err(Err::Error)?;
67                Ok((rem, items))
68            },
69            bytes,
70        )
71    }
72}
73
74impl<T> ToDer for HashSet<T>
75where
76    T: ToDer,
77{
78    fn to_der_len(&self) -> Result<usize> {
79        let mut len = 0;
80        for t in self.iter() {
81            len += t.to_der_len()?;
82        }
83        let header = Header::new(Class::Universal, true, Self::TAG, Length::Definite(len));
84        Ok(header.to_der_len()? + len)
85    }
86
87    fn write_der_header(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
88        let mut len = 0;
89        for t in self.iter() {
90            len += t.to_der_len().map_err(|_| SerializeError::InvalidLength)?;
91        }
92        let header = Header::new(Class::Universal, true, Self::TAG, Length::Definite(len));
93        header.write_der_header(writer).map_err(Into::into)
94    }
95
96    fn write_der_content(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
97        let mut sz = 0;
98        for t in self.iter() {
99            sz += t.write_der(writer)?;
100        }
101        Ok(sz)
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use crate::*;
108    use core::convert::TryFrom;
109    use hex_literal::hex;
110    use std::collections::HashSet;
111
112    #[test]
113    fn ber_hashset() {
114        let input = &hex! {"31 06 02 01 00 02 01 01"};
115        let (_, any) = Any::from_ber(input).expect("parsing hashset failed");
116        <HashSet<u32>>::check_constraints(&any).unwrap();
117
118        let h = <HashSet<u32>>::try_from(any).unwrap();
119
120        assert_eq!(h.len(), 2);
121    }
122
123    #[test]
124    fn der_hashset() {
125        let input = &hex! {"31 06 02 01 00 02 01 01"};
126        let r: IResult<_, _, Error> = HashSet::<u32>::from_der(input);
127        let (_, h) = r.expect("parsing hashset failed");
128
129        assert_eq!(h.len(), 2);
130
131        assert_eq!(h.to_der_len(), Ok(8));
132        let v = h.to_der_vec().expect("could not serialize");
133        let (_, h2) = SetOf::<u32>::from_der(&v).unwrap();
134        assert!(h.iter().eq(h2.iter()));
135    }
136}