1use crate::{
4 asn1::*, ByteSlice, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind,
5 FixedTag, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
6};
7use core::cmp::Ordering;
8
9#[cfg(feature = "alloc")]
10use alloc::vec::Vec;
11
12#[cfg(feature = "oid")]
13use crate::asn1::ObjectIdentifier;
14
15#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
27pub struct AnyRef<'a> {
28 tag: Tag,
30
31 value: ByteSlice<'a>,
33}
34
35impl<'a> AnyRef<'a> {
36 pub const NULL: Self = Self {
38 tag: Tag::Null,
39 value: ByteSlice::EMPTY,
40 };
41
42 pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self> {
44 let value = ByteSlice::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
45 Ok(Self { tag, value })
46 }
47
48 pub(crate) fn from_tag_and_value(tag: Tag, value: ByteSlice<'a>) -> Self {
50 Self { tag, value }
51 }
52
53 pub fn value(self) -> &'a [u8] {
55 self.value.as_slice()
56 }
57
58 pub fn decode_into<T>(self) -> Result<T>
60 where
61 T: DecodeValue<'a> + FixedTag,
62 {
63 self.tag.assert_eq(T::TAG)?;
64 let header = Header {
65 tag: self.tag,
66 length: self.value.len(),
67 };
68
69 let mut decoder = SliceReader::new(self.value())?;
70 let result = T::decode_value(&mut decoder, header)?;
71 decoder.finish(result)
72 }
73
74 pub fn is_null(self) -> bool {
76 self == Self::NULL
77 }
78
79 pub fn bit_string(self) -> Result<BitStringRef<'a>> {
81 self.try_into()
82 }
83
84 pub fn context_specific<T>(self) -> Result<ContextSpecific<T>>
86 where
87 T: Decode<'a>,
88 {
89 self.try_into()
90 }
91
92 pub fn generalized_time(self) -> Result<GeneralizedTime> {
94 self.try_into()
95 }
96
97 pub fn ia5_string(self) -> Result<Ia5StringRef<'a>> {
99 self.try_into()
100 }
101
102 pub fn octet_string(self) -> Result<OctetStringRef<'a>> {
104 self.try_into()
105 }
106
107 #[cfg(feature = "oid")]
109 #[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
110 pub fn oid(self) -> Result<ObjectIdentifier> {
111 self.try_into()
112 }
113
114 pub fn optional<T>(self) -> Result<Option<T>>
116 where
117 T: Choice<'a> + TryFrom<Self, Error = Error>,
118 {
119 if T::can_decode(self.tag) {
120 T::try_from(self).map(Some)
121 } else {
122 Ok(None)
123 }
124 }
125
126 pub fn printable_string(self) -> Result<PrintableStringRef<'a>> {
128 self.try_into()
129 }
130
131 pub fn teletex_string(self) -> Result<TeletexStringRef<'a>> {
133 self.try_into()
134 }
135
136 pub fn videotex_string(self) -> Result<VideotexStringRef<'a>> {
138 self.try_into()
139 }
140
141 pub fn sequence<F, T>(self, f: F) -> Result<T>
144 where
145 F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
146 {
147 self.tag.assert_eq(Tag::Sequence)?;
148 let mut reader = SliceReader::new(self.value.as_slice())?;
149 let result = f(&mut reader)?;
150 reader.finish(result)
151 }
152
153 pub fn utc_time(self) -> Result<UtcTime> {
155 self.try_into()
156 }
157
158 pub fn utf8_string(self) -> Result<Utf8StringRef<'a>> {
160 self.try_into()
161 }
162}
163
164impl<'a> Choice<'a> for AnyRef<'a> {
165 fn can_decode(_: Tag) -> bool {
166 true
167 }
168}
169
170impl<'a> Decode<'a> for AnyRef<'a> {
171 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
172 let header = Header::decode(reader)?;
173
174 Ok(Self {
175 tag: header.tag,
176 value: ByteSlice::decode_value(reader, header)?,
177 })
178 }
179}
180
181impl EncodeValue for AnyRef<'_> {
182 fn value_len(&self) -> Result<Length> {
183 Ok(self.value.len())
184 }
185
186 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
187 writer.write(self.value())
188 }
189}
190
191impl Tagged for AnyRef<'_> {
192 fn tag(&self) -> Tag {
193 self.tag
194 }
195}
196
197impl ValueOrd for AnyRef<'_> {
198 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
199 self.value.der_cmp(&other.value)
200 }
201}
202
203impl<'a> From<AnyRef<'a>> for ByteSlice<'a> {
204 fn from(any: AnyRef<'a>) -> ByteSlice<'a> {
205 any.value
206 }
207}
208
209impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
210 type Error = Error;
211
212 fn try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>> {
213 AnyRef::from_der(bytes)
214 }
215}
216
217#[cfg(feature = "alloc")]
222#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
223#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
224pub struct Any {
225 tag: Tag,
227
228 value: Vec<u8>,
230}
231
232#[cfg(feature = "alloc")]
233impl Any {
234 pub fn new(tag: Tag, bytes: impl Into<Vec<u8>>) -> Result<Self> {
236 let value = bytes.into();
237
238 AnyRef::new(tag, &value)?;
240 Ok(Self { tag, value })
241 }
242}
243
244#[cfg(feature = "alloc")]
245impl Choice<'_> for Any {
246 fn can_decode(_: Tag) -> bool {
247 true
248 }
249}
250
251#[cfg(feature = "alloc")]
252impl<'a> Decode<'a> for Any {
253 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
254 let header = Header::decode(reader)?;
255 let value = reader.read_vec(header.length)?;
256 Self::new(header.tag, value)
257 }
258}
259
260#[cfg(feature = "alloc")]
261impl EncodeValue for Any {
262 fn value_len(&self) -> Result<Length> {
263 self.value.len().try_into()
264 }
265
266 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
267 writer.write(&self.value)
268 }
269}
270
271#[cfg(feature = "alloc")]
272impl<'a> From<&'a Any> for AnyRef<'a> {
273 fn from(any: &'a Any) -> AnyRef<'a> {
274 AnyRef::new(any.tag, &any.value).expect("invalid ANY")
276 }
277}
278
279#[cfg(feature = "alloc")]
280impl Tagged for Any {
281 fn tag(&self) -> Tag {
282 self.tag
283 }
284}