1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use super::*;
#[derive(Debug, Clone, PartialEq)]
pub enum Open {
BitString(BitString),
BmpString(BmpString),
Bool(bool),
GeneralizedTime(GeneralizedTime),
IA5String(IA5String),
Integer(Integer),
Null,
OctetString(OctetString),
PrintableString(PrintableString),
UniversalString(UniversalString),
UtcTime(UtcTime),
VisibleString(VisibleString),
InstanceOf(alloc::boxed::Box<InstanceOf<Open>>),
Unknown {
tag: Tag,
value: alloc::vec::Vec<u8>,
},
}
impl Open {
pub fn tag(&self) -> Tag {
match self {
Self::BitString(_) => BitString::TAG,
Self::BmpString(_) => BmpString::TAG,
Self::Bool(_) => bool::TAG,
Self::GeneralizedTime(_) => GeneralizedTime::TAG,
Self::IA5String(_) => IA5String::TAG,
Self::InstanceOf(_) => <InstanceOf<Open>>::TAG,
Self::Integer(_) => Integer::TAG,
Self::Null => <()>::TAG,
Self::OctetString(_) => OctetString::TAG,
Self::PrintableString(_) => PrintableString::TAG,
Self::UniversalString(_) => UniversalString::TAG,
Self::UtcTime(_) => UtcTime::TAG,
Self::VisibleString(_) => VisibleString::TAG,
Self::Unknown { tag, .. } => *tag,
}
}
}
impl crate::AsnType for Open {
const TAG: Tag = Tag::EOC;
}
impl crate::Decode for Open {
fn decode_with_tag<D: crate::Decoder>(_: &mut D, _: Tag) -> Result<Self, D::Error> {
Err(crate::de::Error::custom(
"`CHOICE`-style enums cannot be implicitly tagged.",
))
}
fn decode<D: crate::Decoder>(decoder: &mut D) -> Result<Self, D::Error> {
Ok(match decoder.peek_tag()? {
Tag::EOC => return Err(crate::de::Error::custom("Invalid ASN.1 Type")),
Tag::BIT_STRING => Open::BitString(<_>::decode(decoder)?),
Tag::BMP_STRING => Open::BmpString(<_>::decode(decoder)?),
Tag::BOOL => Open::Bool(<_>::decode(decoder)?),
Tag::IA5_STRING => Open::IA5String(<_>::decode(decoder)?),
Tag::INTEGER => Open::Integer(<_>::decode(decoder)?),
Tag::OCTET_STRING => Open::OctetString(<_>::decode(decoder)?),
Tag::PRINTABLE_STRING => Open::PrintableString(<_>::decode(decoder)?),
Tag::UNIVERSAL_STRING => Open::UniversalString(<_>::decode(decoder)?),
Tag::VISIBLE_STRING => Open::VisibleString(<_>::decode(decoder)?),
Tag::UTC_TIME => Open::UtcTime(<_>::decode(decoder)?),
Tag::EXTERNAL => Open::InstanceOf(alloc::boxed::Box::new(<_>::decode(decoder)?)),
Tag::GENERALIZED_TIME => Open::GeneralizedTime(<_>::decode(decoder)?),
Tag::NULL => {
decoder.decode_null(<()>::TAG)?;
Open::Null
}
tag => Open::Unknown {
tag,
value: decoder.decode_any(tag)?,
},
})
}
}
impl crate::Encode for Open {
fn encode_with_tag<EN: crate::Encoder>(&self, _: &mut EN, _: Tag) -> Result<(), EN::Error> {
Err(crate::enc::Error::custom(
"CHOICE-style enums do not allow implicit tagging.",
))
}
fn encode<E: crate::Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
match self {
Open::BitString(value) => value.encode(encoder),
Open::BmpString(value) => crate::Encode::encode(value, encoder),
Open::Bool(value) => crate::Encode::encode(value, encoder),
Open::GeneralizedTime(value) => crate::Encode::encode(value, encoder),
Open::IA5String(value) => crate::Encode::encode(value, encoder),
Open::InstanceOf(value) => crate::Encode::encode(&**value, encoder),
Open::Integer(value) => crate::Encode::encode(value, encoder),
Open::Null => ().encode(encoder),
Open::OctetString(value) => crate::Encode::encode(value, encoder),
Open::PrintableString(value) => crate::Encode::encode(value, encoder),
Open::UniversalString(value) => crate::Encode::encode(value, encoder),
Open::UtcTime(value) => crate::Encode::encode(value, encoder),
Open::VisibleString(value) => crate::Encode::encode(value, encoder),
Open::Unknown { tag, value } => encoder.encode_any(*tag, value).map(drop),
}
.map(drop)
}
}