use super::iter;
#[cfg(any(feature = "alloc", test))]
use super::{Cert, CertChain};
macro_rules! def_borrowed_wrapper {
($(#[$m:meta])* $name:ident, $owned:ident $(,$(#[$pos_m:meta])* position)?) => {
#[derive(Clone, Eq, Debug)]
$(#[$m])*
pub struct $name<'a> {
pub(super) inner: &'a [u8],
$($(#[$pos_m])*)?
pub(super) position: ::der::Length,
pub(super) length: ::der::Length,
}
impl<'a> $name<'a> {
pub fn as_bytes(&self) -> &'a [u8] {
self.inner
}
pub fn len(&self) -> ::der::Length {
self.length
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
impl ::core::cmp::PartialEq for $name<'_> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl ::der::FixedTag for $name<'_> {
const TAG: ::der::Tag = ::der::Tag::Sequence;
}
impl<'a> ::der::DecodeValue<'a> for $name<'a> {
fn decode_value<R: ::der::Reader<'a>>(
reader: &mut R,
header: ::der::Header
) -> ::der::Result<Self> {
debug_assert_eq!(header.tag, der::Tag::Sequence);
$($(#[$pos_m])*)?
let position = reader.position();
let length = header.length;
::core::result::Result::Ok(Self {
inner: reader.read_slice(length)?,
$($(#[$pos_m])*)?
position,
length,
})
}
}
impl ::der::EncodeValue for $name<'_> {
fn value_len(&self) -> ::der::Result<::der::Length> {
::core::result::Result::Ok(self.length)
}
fn encode_value(&self, encoder: &mut impl ::der::Writer) -> ::der::Result<()> {
encoder.write(self.inner)
}
}
#[cfg(any(feature = "alloc", test))]
impl<'a> ::core::convert::From<&'a $owned> for $name<'a> {
fn from(value: &'a $owned) -> Self {
Self {
inner: &value.inner,
position: value.position,
length: value.length,
}
}
}
#[cfg(any(feature = "alloc", test))]
impl<'a> ::der::referenced::RefToOwned<'a> for $name<'a> {
type Owned = $owned;
fn ref_to_owned(&self) -> Self::Owned {
self.into()
}
}
};
}
#[cfg(feature = "x509-cert")]
macro_rules! impl_borrowed_decode_body {
($name:ident, $decoded:ty, $decodes_as:literal) => {
impl $name<'_> {
#[doc = concat!("Decodes the body as ", $decodes_as, ".")]
#[cfg(feature = "x509-cert")]
pub fn decode_body(&self) -> ::der::Result<$decoded> {
let mut reader = ::der::SliceReader::new(self.inner)?;
match <$decoded as ::der::DecodeValue>::decode_value(
&mut reader,
::der::Header {
tag: <Self as ::der::FixedTag>::TAG,
length: self.length,
},
) {
Ok(v) => Ok(v),
Err(e) => Err($crate::util::shift_error_position(e, self.position)),
}
}
}
};
}
def_borrowed_wrapper!(
CertRef,
Cert,
#[cfg(any(feature = "alloc", test))]
position
);
#[cfg(feature = "x509-cert")]
impl_borrowed_decode_body!(
CertRef,
x509_cert::Certificate,
"a [`Certificate`](x509_cert::Certificate)"
);
def_borrowed_wrapper!(
CertChainRef,
CertChain
);
#[cfg(feature = "x509-cert")]
impl_borrowed_decode_body!(
CertChainRef,
alloc::vec::Vec<x509_cert::Certificate>,
"a vector of [`Certificate`](x509_cert::Certificate)s"
);
impl CertChainRef<'_> {
pub fn iter(&self) -> iter::CertIter<'_> {
iter::CertIter {
inner: self.inner,
position: self.position,
}
}
}