use alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
vec::Vec,
};
use num_bigint::BigInt;
use crate::error::DecodeError;
use crate::types::{self, AsnType, Constraints, Enumerated, SetOf, Tag};
pub use nom::Needed;
pub use rasn_derive::Decode;
#[must_use]
pub fn iter<D: Decode>(input: &[u8], codec: crate::codec::Codec) -> Iter<'_, D> {
Iter::new(input, codec)
}
enum IterBuffer<'a> {
Borrowed(&'a [u8]),
Owned { data: Vec<u8>, pos: usize },
}
impl IterBuffer<'_> {
fn as_slice(&self) -> &[u8] {
match self {
IterBuffer::Borrowed(slice) => slice,
IterBuffer::Owned { data, pos } => &data[*pos..],
}
}
fn update_after_consumption(&mut self, consumed: usize) {
match self {
IterBuffer::Borrowed(slice) => *slice = &slice[consumed..],
IterBuffer::Owned { data, pos } => {
*pos += consumed;
if *pos > data.len() / 2 {
data.drain(0..*pos);
*pos = 0;
}
}
}
}
#[allow(clippy::wrong_self_convention)]
fn to_owned(&mut self) {
if let IterBuffer::Borrowed(slice) = self {
let vec = slice.to_vec();
*self = IterBuffer::Owned { data: vec, pos: 0 };
}
}
fn extend(&mut self, bytes: &[u8]) {
self.to_owned();
if let IterBuffer::Owned { data, .. } = self {
data.extend_from_slice(bytes);
}
}
}
pub struct Iter<'input, D: Decode> {
buf: IterBuffer<'input>,
codec: crate::codec::Codec,
_kind: core::marker::PhantomData<D>,
}
impl<'input, D: Decode> Iter<'input, D> {
#[must_use]
pub fn new(input: &'input [u8], codec: crate::codec::Codec) -> Self {
Self {
buf: IterBuffer::Borrowed(input),
codec,
_kind: core::marker::PhantomData,
}
}
pub fn append_bytes(&mut self, bytes: &'input [u8]) {
self.buf.extend(bytes);
}
}
impl<D: Decode> Iterator for Iter<'_, D> {
type Item = Result<D, DecodeError>;
fn next(&mut self) -> Option<Self::Item> {
let input = self.buf.as_slice();
match self.codec.decode_from_binary_with_remainder(input) {
Ok((value, remainder)) => {
let consumed = input.len() - remainder.len();
self.buf.update_after_consumption(consumed);
Some(Ok(value))
}
Err(err) => Some(Err(err)),
}
}
}
pub trait Decode: Sized + AsnType {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, D::Error> {
Self::decode_with_tag(decoder, Self::TAG)
}
fn decode_with_tag<D: Decoder>(decoder: &mut D, tag: Tag) -> Result<Self, D::Error> {
Self::decode_with_tag_and_constraints(decoder, tag, Self::CONSTRAINTS)
}
fn decode_with_constraints<D: Decoder>(
decoder: &mut D,
constraints: Constraints,
) -> Result<Self, D::Error> {
Self::decode_with_tag_and_constraints(decoder, Self::TAG, constraints)
}
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error>;
}
pub trait Decoder<const RCL: usize = 0, const ECL: usize = 0>: Sized {
type Ok;
type Error: Error + Into<crate::error::DecodeError> + From<crate::error::DecodeError>;
type AnyDecoder<const R: usize, const E: usize>: Decoder<RCL, ECL, Ok = Self::Ok, Error = Self::Error>
+ Decoder;
#[must_use]
fn codec(&self) -> crate::Codec;
fn decode_any(&mut self, tag: Tag) -> Result<types::Any, Self::Error>;
fn decode_bit_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::BitString, Self::Error>;
fn decode_bool(&mut self, tag: Tag) -> Result<bool, Self::Error>;
fn decode_enumerated<E: Enumerated>(&mut self, tag: Tag) -> Result<E, Self::Error>;
fn decode_integer<I: types::IntegerType>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<I, Self::Error>;
fn decode_real<R: types::RealType>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<R, Self::Error>;
fn decode_null(&mut self, tag: Tag) -> Result<(), Self::Error>;
fn decode_object_identifier(
&mut self,
tag: Tag,
) -> Result<types::ObjectIdentifier, Self::Error>;
fn decode_sequence<const RC: usize, const EC: usize, D, DF, F>(
&mut self,
tag: Tag,
default_initializer_fn: Option<DF>,
decode_fn: F,
) -> Result<D, Self::Error>
where
D: crate::types::Constructed<RC, EC>,
DF: FnOnce() -> D,
F: FnOnce(&mut Self::AnyDecoder<RC, EC>) -> Result<D, Self::Error>;
fn decode_sequence_of<D: Decode>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<Vec<D>, Self::Error>;
fn decode_set_of<D: Decode + Eq + core::hash::Hash>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::SetOf<D>, Self::Error>;
fn decode_octet_string<'buf, T>(
&'buf mut self,
tag: Tag,
constraints: Constraints,
) -> Result<T, Self::Error>
where
T: From<&'buf [u8]> + From<Vec<u8>>;
fn decode_utf8_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::Utf8String, Self::Error>;
fn decode_visible_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::VisibleString, Self::Error>;
fn decode_general_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::GeneralString, Self::Error>;
fn decode_graphic_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::GraphicString, Self::Error>;
fn decode_ia5_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::Ia5String, Self::Error>;
fn decode_printable_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::PrintableString, Self::Error>;
fn decode_numeric_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::NumericString, Self::Error>;
fn decode_teletex_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::TeletexString, Self::Error>;
fn decode_bmp_string(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<types::BmpString, Self::Error>;
fn decode_explicit_prefix<D: Decode>(&mut self, tag: Tag) -> Result<D, Self::Error>;
fn decode_optional_with_explicit_prefix<D: Decode>(
&mut self,
tag: Tag,
) -> Result<Option<D>, Self::Error>;
fn decode_utc_time(&mut self, tag: Tag) -> Result<types::UtcTime, Self::Error>;
fn decode_generalized_time(&mut self, tag: Tag) -> Result<types::GeneralizedTime, Self::Error>;
fn decode_date(&mut self, tag: Tag) -> Result<types::Date, Self::Error>;
fn decode_set<const RC: usize, const EC: usize, FIELDS, SET, D, F>(
&mut self,
tag: Tag,
decode_fn: D,
field_fn: F,
) -> Result<SET, Self::Error>
where
SET: Decode + crate::types::Constructed<RC, EC>,
FIELDS: Decode,
D: Fn(&mut Self::AnyDecoder<RC, EC>, usize, Tag) -> Result<FIELDS, Self::Error>,
F: FnOnce(Vec<FIELDS>) -> Result<SET, Self::Error>;
fn decode_choice<D>(&mut self, constraints: Constraints) -> Result<D, Self::Error>
where
D: crate::types::DecodeChoice;
fn decode_optional<D: Decode>(&mut self) -> Result<Option<D>, Self::Error>;
fn decode_optional_with_tag<D: Decode>(&mut self, tag: Tag) -> Result<Option<D>, Self::Error>;
fn decode_optional_with_constraints<D: Decode>(
&mut self,
constraints: Constraints,
) -> Result<Option<D>, Self::Error>;
fn decode_optional_with_tag_and_constraints<D: Decode>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<Option<D>, Self::Error>;
fn decode_default<D: Decode, F: FnOnce() -> D>(
&mut self,
default_fn: F,
) -> Result<D, Self::Error> {
self.decode_default_with_tag(D::TAG, default_fn)
}
fn decode_default_with_tag<D: Decode, F: FnOnce() -> D>(
&mut self,
tag: Tag,
default_fn: F,
) -> Result<D, Self::Error> {
Ok(self
.decode_optional_with_tag::<D>(tag)?
.unwrap_or_else(default_fn))
}
fn decode_default_with_constraints<D: Decode, F: FnOnce() -> D>(
&mut self,
default_fn: F,
constraints: Constraints,
) -> Result<D, Self::Error> {
Ok(self
.decode_optional_with_constraints::<D>(constraints)?
.unwrap_or_else(default_fn))
}
fn decode_default_with_tag_and_constraints<D: Decode, F: FnOnce() -> D>(
&mut self,
tag: Tag,
default_fn: F,
constraints: Constraints,
) -> Result<D, Self::Error> {
Ok(self
.decode_optional_with_tag_and_constraints::<D>(tag, constraints)?
.unwrap_or_else(default_fn))
}
fn decode_extension_addition<D>(&mut self) -> Result<Option<D>, Self::Error>
where
D: Decode,
{
self.decode_extension_addition_with_constraints(Constraints::default())
}
fn decode_extension_addition_with_explicit_tag_and_constraints<D>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<Option<D>, Self::Error>
where
D: Decode;
fn decode_extension_addition_with_tag<D>(&mut self, tag: Tag) -> Result<Option<D>, Self::Error>
where
D: Decode,
{
self.decode_extension_addition_with_tag_and_constraints(tag, Constraints::default())
}
fn decode_extension_addition_with_constraints<D>(
&mut self,
constraints: Constraints,
) -> Result<Option<D>, Self::Error>
where
D: Decode,
{
self.decode_extension_addition_with_tag_and_constraints(D::TAG, constraints)
}
fn decode_extension_addition_with_tag_and_constraints<D>(
&mut self,
tag: Tag,
constraints: Constraints,
) -> Result<Option<D>, Self::Error>
where
D: Decode;
fn decode_extension_addition_with_default<D: Decode, F: FnOnce() -> D>(
&mut self,
default_fn: F,
) -> Result<D, Self::Error> {
self.decode_extension_addition_with_default_and_constraints(
default_fn,
Constraints::default(),
)
}
fn decode_extension_addition_with_default_and_tag<D: Decode, F: FnOnce() -> D>(
&mut self,
tag: Tag,
default_fn: F,
) -> Result<D, Self::Error> {
self.decode_extension_addition_with_default_and_tag_and_constraints::<D, F>(
tag,
default_fn,
Constraints::default(),
)
}
fn decode_extension_addition_with_default_and_constraints<D: Decode, F: FnOnce() -> D>(
&mut self,
default_fn: F,
constraints: Constraints,
) -> Result<D, Self::Error> {
Ok(self
.decode_extension_addition_with_constraints::<D>(constraints)?
.unwrap_or_else(default_fn))
}
fn decode_extension_addition_with_default_and_tag_and_constraints<
D: Decode,
F: FnOnce() -> D,
>(
&mut self,
tag: Tag,
default_fn: F,
constraints: Constraints,
) -> Result<D, Self::Error> {
Ok(self
.decode_extension_addition_with_tag_and_constraints::<D>(tag, constraints)?
.unwrap_or_else(default_fn))
}
fn decode_extension_addition_group<
const RC: usize,
const EC: usize,
D: Decode + crate::types::Constructed<RC, EC>,
>(
&mut self,
) -> Result<Option<D>, Self::Error>;
}
pub trait Error: core::fmt::Display {
#[must_use]
fn custom<D: core::fmt::Display>(msg: D, codec: crate::Codec) -> Self;
#[must_use]
fn incomplete(needed: Needed, codec: crate::Codec) -> Self;
#[must_use]
fn exceeds_max_length(length: num_bigint::BigUint, codec: crate::Codec) -> Self;
#[must_use]
fn missing_field(name: &'static str, codec: crate::Codec) -> Self;
#[must_use]
fn no_valid_choice(name: &'static str, codec: crate::Codec) -> Self;
#[must_use]
fn field_error(name: &'static str, error: DecodeError, codec: crate::Codec) -> Self;
#[must_use]
fn duplicate_field(name: &'static str, codec: crate::Codec) -> Self;
#[must_use]
fn unknown_field(index: usize, tag: Tag, codec: crate::Codec) -> Self;
}
impl Decode for () {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_null(tag)
}
}
impl<D: Decode> Decode for Option<D> {
fn decode<DE: Decoder>(decoder: &mut DE) -> Result<Self, DE::Error> {
decoder.decode_optional()
}
fn decode_with_tag<DE: Decoder>(decoder: &mut DE, tag: Tag) -> Result<Self, DE::Error> {
decoder.decode_optional_with_tag(tag)
}
fn decode_with_constraints<DE: Decoder>(
decoder: &mut DE,
constraints: Constraints,
) -> Result<Self, DE::Error> {
decoder.decode_optional_with_constraints(constraints)
}
fn decode_with_tag_and_constraints<DE: Decoder>(
decoder: &mut DE,
tag: Tag,
constraints: Constraints,
) -> Result<Self, DE::Error> {
decoder.decode_optional_with_tag_and_constraints(tag, constraints)
}
}
impl Decode for bool {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_bool(tag)
}
}
macro_rules! impl_integers {
($($int:ty),+ $(,)?) => {
$(
impl Decode for $int {
fn decode_with_tag_and_constraints<D: Decoder>(decoder: &mut D, tag: Tag, constraints: Constraints) -> Result<Self, D::Error> {
decoder.decode_integer::<$int>(tag, constraints)
}
}
)+
}
}
impl_integers! {
i8,
i16,
i32,
i64,
i128,
isize,
u8,
u16,
u32,
u64,
usize,
BigInt
}
impl<const START: i128, const END: i128> Decode for types::ConstrainedInteger<START, END> {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
decoder
.decode_integer::<types::Integer>(tag, constraints)
.map(Self)
}
}
impl Decode for types::Integer {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_integer::<types::Integer>(tag, constraints)
}
}
#[cfg(feature = "f32")]
impl Decode for f32 {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_real::<f32>(tag, Constraints::default())
}
}
#[cfg(feature = "f64")]
impl Decode for f64 {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_real::<f64>(tag, Constraints::default())
}
}
impl<T: Decode> Decode for Box<T> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, D::Error> {
T::decode(decoder).map(Box::new)
}
fn decode_with_tag<D: Decoder>(decoder: &mut D, tag: Tag) -> Result<Self, D::Error> {
T::decode_with_tag(decoder, tag).map(Box::new)
}
fn decode_with_constraints<DE: Decoder>(
decoder: &mut DE,
constraints: Constraints,
) -> Result<Self, DE::Error> {
T::decode_with_constraints(decoder, constraints).map(Box::new)
}
fn decode_with_tag_and_constraints<DE: Decoder>(
decoder: &mut DE,
tag: Tag,
constraints: Constraints,
) -> Result<Self, DE::Error> {
T::decode_with_tag_and_constraints(decoder, tag, constraints).map(Box::new)
}
}
impl<'a, T: 'a + ToOwned + Decode> Decode for Cow<'a, T> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, D::Error> {
T::decode(decoder).map(|x| Cow::Owned(x.to_owned()))
}
fn decode_with_tag<D: Decoder>(decoder: &mut D, tag: Tag) -> Result<Self, D::Error> {
T::decode_with_tag(decoder, tag).map(|x| Cow::Owned(x.to_owned()))
}
fn decode_with_constraints<DE: Decoder>(
decoder: &mut DE,
constraints: Constraints,
) -> Result<Self, DE::Error> {
T::decode_with_constraints(decoder, constraints).map(|x| Cow::Owned(x.to_owned()))
}
fn decode_with_tag_and_constraints<DE: Decoder>(
decoder: &mut DE,
tag: Tag,
constraints: Constraints,
) -> Result<Self, DE::Error> {
T::decode_with_tag_and_constraints(decoder, tag, constraints)
.map(|x| Cow::Owned(x.to_owned()))
}
}
impl Decode for types::OctetString {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
cfg_if::cfg_if! {
if #[cfg(feature = "arc-slice")] {
decoder.decode_octet_string(tag, constraints)
} else {
decoder.decode_octet_string::<Vec<u8>>(tag, constraints).map(From::from)
}
}
}
}
impl Decode for types::ObjectIdentifier {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_object_identifier(tag)
}
}
impl Decode for types::Utf8String {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_utf8_string(tag, constraints)
}
}
impl Decode for types::UtcTime {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_utc_time(tag)
}
}
impl Decode for types::GeneralizedTime {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_generalized_time(tag)
}
}
impl Decode for types::Any {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_any(tag)
}
}
impl<T: Decode> Decode for alloc::vec::Vec<T> {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_sequence_of(tag, constraints)
}
}
impl<T: Decode + Eq + core::hash::Hash> Decode for SetOf<T> {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
decoder.decode_set_of(tag, constraints)
}
}
impl<T: Decode, const N: usize> Decode for [T; N] {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
let sequence = decoder.decode_sequence_of(tag, constraints)?;
sequence.try_into().map_err(|seq: Vec<_>| {
D::Error::from(DecodeError::incorrect_item_number_in_sequence(
N,
seq.len(),
decoder.codec(),
))
})
}
}
impl<T: AsnType, V: Decode> Decode for types::Implicit<T, V> {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
constraints: Constraints,
) -> Result<Self, D::Error> {
Ok(Self::new(V::decode_with_tag_and_constraints(
decoder,
tag,
constraints,
)?))
}
}
impl<T: AsnType, V: Decode> Decode for types::Explicit<T, V> {
fn decode_with_tag_and_constraints<D: Decoder>(
decoder: &mut D,
tag: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
Ok(Self::new(decoder.decode_explicit_prefix(tag)?))
}
}
impl<T: AsnType> Decode for core::marker::PhantomData<T> {
fn decode_with_tag_and_constraints<D: Decoder>(
_: &mut D,
_: Tag,
_: Constraints,
) -> Result<Self, D::Error> {
Ok(core::marker::PhantomData)
}
}