//! ASN.1 DER headers. use crate::{Decode, DerOrd, Encode, ErrorKind, Length, Reader, Result, Tag, Writer}; use core::cmp::Ordering; /// ASN.1 DER headers: tag + length component of TLV-encoded values #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Header { /// Tag representing the type of the encoded value pub tag: Tag, /// Length of the encoded value pub length: Length, } impl Header { /// Create a new [`Header`] from a [`Tag`] and a specified length. /// /// Returns an error if the length exceeds the limits of [`Length`]. pub fn new(tag: Tag, length: impl TryInto) -> Result { let length = length.try_into().map_err(|_| ErrorKind::Overflow)?; Ok(Self { tag, length }) } } impl<'a> Decode<'a> for Header { fn decode>(reader: &mut R) -> Result
{ let tag = Tag::decode(reader)?; let length = Length::decode(reader).map_err(|e| { if e.kind() == ErrorKind::Overlength { ErrorKind::Length { tag }.into() } else { e } })?; Ok(Self { tag, length }) } } impl Encode for Header { fn encoded_len(&self) -> Result { self.tag.encoded_len()? + self.length.encoded_len()? } fn encode(&self, writer: &mut impl Writer) -> Result<()> { self.tag.encode(writer)?; self.length.encode(writer) } } impl DerOrd for Header { fn der_cmp(&self, other: &Self) -> Result { match self.tag.der_cmp(&other.tag)? { Ordering::Equal => self.length.der_cmp(&other.length), ordering => Ok(ordering), } } }