1use crate::{
4 asn1::*, ByteSlice, Choice, Decodable, DecodeValue, Decoder, DerOrd, EncodeValue, Encoder,
5 Error, ErrorKind, FixedTag, Header, Length, Result, Tag, Tagged, ValueOrd,
6};
7use core::cmp::Ordering;
8
9#[cfg(feature = "oid")]
10use crate::asn1::ObjectIdentifier;
11
12#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
22pub struct Any<'a> {
23 tag: Tag,
25
26 value: ByteSlice<'a>,
28}
29
30impl<'a> Any<'a> {
31 pub const NULL: Self = Self {
33 tag: Tag::Null,
34 value: ByteSlice::EMPTY,
35 };
36
37 pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self> {
39 let value = ByteSlice::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
40 Ok(Self { tag, value })
41 }
42
43 pub(crate) fn from_tag_and_value(tag: Tag, value: ByteSlice<'a>) -> Self {
45 Self { tag, value }
46 }
47
48 pub fn value(self) -> &'a [u8] {
50 self.value.as_bytes()
51 }
52
53 pub fn decode_into<T>(self) -> Result<T>
55 where
56 T: DecodeValue<'a> + FixedTag,
57 {
58 self.tag.assert_eq(T::TAG)?;
59 let mut decoder = Decoder::new(self.value())?;
60 let result = T::decode_value(&mut decoder, self.value.len())?;
61 decoder.finish(result)
62 }
63
64 pub fn is_null(self) -> bool {
66 self == Self::NULL
67 }
68
69 pub fn bit_string(self) -> Result<BitString<'a>> {
71 self.try_into()
72 }
73
74 pub fn context_specific<T>(self) -> Result<ContextSpecific<T>>
76 where
77 T: Decodable<'a>,
78 {
79 self.try_into()
80 }
81
82 pub fn generalized_time(self) -> Result<GeneralizedTime> {
84 self.try_into()
85 }
86
87 pub fn ia5_string(self) -> Result<Ia5String<'a>> {
89 self.try_into()
90 }
91
92 pub fn octet_string(self) -> Result<OctetString<'a>> {
94 self.try_into()
95 }
96
97 #[cfg(feature = "oid")]
99 #[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
100 pub fn oid(self) -> Result<ObjectIdentifier> {
101 self.try_into()
102 }
103
104 pub fn optional<T>(self) -> Result<Option<T>>
106 where
107 T: Choice<'a> + TryFrom<Self, Error = Error>,
108 {
109 if T::can_decode(self.tag) {
110 T::try_from(self).map(Some)
111 } else {
112 Ok(None)
113 }
114 }
115
116 pub fn printable_string(self) -> Result<PrintableString<'a>> {
118 self.try_into()
119 }
120
121 pub fn sequence<F, T>(self, f: F) -> Result<T>
124 where
125 F: FnOnce(&mut Decoder<'a>) -> Result<T>,
126 {
127 self.tag.assert_eq(Tag::Sequence)?;
128 let mut seq_decoder = Decoder::new(self.value.as_bytes())?;
129 let result = f(&mut seq_decoder)?;
130 seq_decoder.finish(result)
131 }
132
133 pub fn utc_time(self) -> Result<UtcTime> {
135 self.try_into()
136 }
137
138 pub fn utf8_string(self) -> Result<Utf8String<'a>> {
140 self.try_into()
141 }
142}
143
144impl<'a> Choice<'a> for Any<'a> {
145 fn can_decode(_: Tag) -> bool {
146 true
147 }
148}
149
150impl<'a> Decodable<'a> for Any<'a> {
151 fn decode(decoder: &mut Decoder<'a>) -> Result<Any<'a>> {
152 let header = Header::decode(decoder)?;
153 let tag = header.tag;
154 let value = ByteSlice::decode_value(decoder, header.length)?;
155 Ok(Self { tag, value })
156 }
157}
158
159impl EncodeValue for Any<'_> {
160 fn value_len(&self) -> Result<Length> {
161 Ok(self.value.len())
162 }
163
164 fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
165 encoder.bytes(self.value())
166 }
167}
168
169impl Tagged for Any<'_> {
170 fn tag(&self) -> Tag {
171 self.tag
172 }
173}
174
175impl ValueOrd for Any<'_> {
176 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
177 self.value.der_cmp(&other.value)
178 }
179}
180
181impl<'a> From<Any<'a>> for ByteSlice<'a> {
182 fn from(any: Any<'a>) -> ByteSlice<'a> {
183 any.value
184 }
185}
186
187impl<'a> TryFrom<&'a [u8]> for Any<'a> {
188 type Error = Error;
189
190 fn try_from(bytes: &'a [u8]) -> Result<Any<'a>> {
191 Any::from_der(bytes)
192 }
193}