1#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
4
5use crate::{
6 BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length,
7 Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
8};
9use core::cmp::Ordering;
10
11#[cfg(feature = "alloc")]
12use crate::SliceWriter;
13
14#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
26#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
27pub struct AnyRef<'a> {
28 tag: Tag,
30
31 value: BytesRef<'a>,
33}
34
35impl<'a> AnyRef<'a> {
36 pub const NULL: Self = Self {
38 tag: Tag::Null,
39 value: BytesRef::EMPTY,
40 };
41
42 pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self> {
44 let value = BytesRef::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: BytesRef<'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_as<T>(self) -> Result<T>
60 where
61 T: Choice<'a> + DecodeValue<'a>,
62 {
63 if !T::can_decode(self.tag) {
64 return Err(self.tag.unexpected_error(None));
65 }
66
67 let header = Header {
68 tag: self.tag,
69 length: self.value.len(),
70 };
71
72 let mut decoder = SliceReader::new(self.value())?;
73 let result = T::decode_value(&mut decoder, header)?;
74 decoder.finish(result)
75 }
76
77 pub fn is_null(self) -> bool {
79 self == Self::NULL
80 }
81
82 pub fn sequence<F, T>(self, f: F) -> Result<T>
85 where
86 F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
87 {
88 self.tag.assert_eq(Tag::Sequence)?;
89 let mut reader = SliceReader::new(self.value.as_slice())?;
90 let result = f(&mut reader)?;
91 reader.finish(result)
92 }
93}
94
95impl<'a> Choice<'a> for AnyRef<'a> {
96 fn can_decode(_: Tag) -> bool {
97 true
98 }
99}
100
101impl<'a> Decode<'a> for AnyRef<'a> {
102 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
103 let header = Header::decode(reader)?;
104 Self::decode_value(reader, header)
105 }
106}
107
108impl<'a> DecodeValue<'a> for AnyRef<'a> {
109 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
110 Ok(Self {
111 tag: header.tag,
112 value: BytesRef::decode_value(reader, header)?,
113 })
114 }
115}
116
117impl EncodeValue for AnyRef<'_> {
118 fn value_len(&self) -> Result<Length> {
119 Ok(self.value.len())
120 }
121
122 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
123 writer.write(self.value())
124 }
125}
126
127impl Tagged for AnyRef<'_> {
128 fn tag(&self) -> Tag {
129 self.tag
130 }
131}
132
133impl ValueOrd for AnyRef<'_> {
134 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
135 self.value.der_cmp(&other.value)
136 }
137}
138
139impl<'a> From<AnyRef<'a>> for BytesRef<'a> {
140 fn from(any: AnyRef<'a>) -> BytesRef<'a> {
141 any.value
142 }
143}
144
145impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
146 type Error = Error;
147
148 fn try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>> {
149 AnyRef::from_der(bytes)
150 }
151}
152
153#[cfg(feature = "alloc")]
154pub use self::allocating::Any;
155
156#[cfg(feature = "alloc")]
157mod allocating {
158 use super::*;
159 use crate::{referenced::*, BytesOwned};
160 use alloc::boxed::Box;
161
162 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
167 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
168 pub struct Any {
169 tag: Tag,
171
172 value: BytesOwned,
174 }
175
176 impl Any {
177 pub fn new(tag: Tag, bytes: impl Into<Box<[u8]>>) -> Result<Self> {
179 let value = BytesOwned::new(bytes)?;
180
181 AnyRef::new(tag, value.as_slice())?;
183 Ok(Self { tag, value })
184 }
185
186 pub fn value(&self) -> &[u8] {
188 self.value.as_slice()
189 }
190
191 pub fn decode_as<'a, T>(&'a self) -> Result<T>
193 where
194 T: Choice<'a> + DecodeValue<'a>,
195 {
196 AnyRef::from(self).decode_as()
197 }
198
199 pub fn encode_from<T>(msg: &T) -> Result<Self>
201 where
202 T: Tagged + EncodeValue,
203 {
204 let encoded_len = usize::try_from(msg.value_len()?)?;
205 let mut buf = vec![0u8; encoded_len];
206 let mut writer = SliceWriter::new(&mut buf);
207 msg.encode_value(&mut writer)?;
208 writer.finish()?;
209 Any::new(msg.tag(), buf)
210 }
211
212 pub fn sequence<'a, F, T>(&'a self, f: F) -> Result<T>
215 where
216 F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
217 {
218 AnyRef::from(self).sequence(f)
219 }
220
221 pub fn null() -> Self {
223 Self {
224 tag: Tag::Null,
225 value: BytesOwned::default(),
226 }
227 }
228 }
229
230 impl Choice<'_> for Any {
231 fn can_decode(_: Tag) -> bool {
232 true
233 }
234 }
235
236 impl<'a> Decode<'a> for Any {
237 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
238 let header = Header::decode(reader)?;
239 Self::decode_value(reader, header)
240 }
241 }
242
243 impl<'a> DecodeValue<'a> for Any {
244 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
245 let value = reader.read_vec(header.length)?;
246 Self::new(header.tag, value)
247 }
248 }
249
250 impl EncodeValue for Any {
251 fn value_len(&self) -> Result<Length> {
252 Ok(self.value.len())
253 }
254
255 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
256 writer.write(self.value.as_slice())
257 }
258 }
259
260 impl<'a> From<&'a Any> for AnyRef<'a> {
261 fn from(any: &'a Any) -> AnyRef<'a> {
262 AnyRef::new(any.tag, any.value.as_slice()).expect("invalid ANY")
264 }
265 }
266
267 impl Tagged for Any {
268 fn tag(&self) -> Tag {
269 self.tag
270 }
271 }
272
273 impl ValueOrd for Any {
274 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
275 self.value.der_cmp(&other.value)
276 }
277 }
278
279 impl<'a, T> From<T> for Any
280 where
281 T: Into<AnyRef<'a>>,
282 {
283 fn from(input: T) -> Any {
284 let anyref: AnyRef<'a> = input.into();
285 Self {
286 tag: anyref.tag(),
287 value: BytesOwned::from(anyref.value),
288 }
289 }
290 }
291
292 impl<'a> RefToOwned<'a> for AnyRef<'a> {
293 type Owned = Any;
294 fn ref_to_owned(&self) -> Self::Owned {
295 Any {
296 tag: self.tag(),
297 value: BytesOwned::from(self.value),
298 }
299 }
300 }
301
302 impl OwnedToRef for Any {
303 type Borrowed<'a> = AnyRef<'a>;
304 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
305 self.into()
306 }
307 }
308
309 impl Any {
310 pub fn is_null(&self) -> bool {
312 self.owned_to_ref() == AnyRef::NULL
313 }
314 }
315}