/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-0.7.10/src/asn1/optional.rs
Line | Count | Source |
1 | | //! ASN.1 `OPTIONAL` as mapped to Rust's `Option` type |
2 | | |
3 | | use crate::{Choice, Decode, DerOrd, Encode, Length, Reader, Result, Tag, Writer}; |
4 | | use core::cmp::Ordering; |
5 | | |
6 | | impl<'a, T> Decode<'a> for Option<T> |
7 | | where |
8 | | T: Choice<'a>, // NOTE: all `Decode + Tagged` types receive a blanket `Choice` impl |
9 | | { |
10 | 0 | fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Option<T>> { |
11 | 0 | if let Some(byte) = reader.peek_byte() { |
12 | 0 | if T::can_decode(Tag::try_from(byte)?) { |
13 | 0 | return T::decode(reader).map(Some); |
14 | 0 | } |
15 | 0 | } |
16 | | |
17 | 0 | Ok(None) |
18 | 0 | } |
19 | | } |
20 | | |
21 | | impl<T> DerOrd for Option<T> |
22 | | where |
23 | | T: DerOrd, |
24 | | { |
25 | 0 | fn der_cmp(&self, other: &Self) -> Result<Ordering> { |
26 | 0 | match self { |
27 | 0 | Some(a) => match other { |
28 | 0 | Some(b) => a.der_cmp(b), |
29 | 0 | None => Ok(Ordering::Greater), |
30 | | }, |
31 | 0 | None => Ok(Ordering::Less), |
32 | | } |
33 | 0 | } |
34 | | } |
35 | | |
36 | | impl<T> Encode for Option<T> |
37 | | where |
38 | | T: Encode, |
39 | | { |
40 | 0 | fn encoded_len(&self) -> Result<Length> { |
41 | 0 | (&self).encoded_len() |
42 | 0 | } |
43 | | |
44 | 0 | fn encode(&self, writer: &mut impl Writer) -> Result<()> { |
45 | 0 | (&self).encode(writer) |
46 | 0 | } |
47 | | } |
48 | | |
49 | | impl<T> Encode for &Option<T> |
50 | | where |
51 | | T: Encode, |
52 | | { |
53 | 0 | fn encoded_len(&self) -> Result<Length> { |
54 | 0 | match self { |
55 | 0 | Some(encodable) => encodable.encoded_len(), |
56 | 0 | None => Ok(0u8.into()), |
57 | | } |
58 | 0 | } |
59 | | |
60 | 0 | fn encode(&self, encoder: &mut impl Writer) -> Result<()> { |
61 | 0 | match self { |
62 | 0 | Some(encodable) => encodable.encode(encoder), |
63 | 0 | None => Ok(()), |
64 | | } |
65 | 0 | } |
66 | | } |