der/
header.rs

1//! ASN.1 DER headers.
2
3use crate::{Decode, DerOrd, Encode, ErrorKind, Length, Reader, Result, Tag, Writer};
4use core::cmp::Ordering;
5
6/// ASN.1 DER headers: tag + length component of TLV-encoded values
7#[derive(Copy, Clone, Debug, Eq, PartialEq)]
8pub struct Header {
9    /// Tag representing the type of the encoded value
10    pub tag: Tag,
11
12    /// Length of the encoded value
13    pub length: Length,
14}
15
16impl Header {
17    /// Create a new [`Header`] from a [`Tag`] and a specified length.
18    ///
19    /// Returns an error if the length exceeds the limits of [`Length`].
20    pub fn new(tag: Tag, length: impl TryInto<Length>) -> Result<Self> {
21        let length = length.try_into().map_err(|_| ErrorKind::Overflow)?;
22        Ok(Self { tag, length })
23    }
24}
25
26impl<'a> Decode<'a> for Header {
27    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Header> {
28        let tag = Tag::decode(reader)?;
29
30        let length = Length::decode(reader).map_err(|e| {
31            if e.kind() == ErrorKind::Overlength {
32                ErrorKind::Length { tag }.into()
33            } else {
34                e
35            }
36        })?;
37
38        Ok(Self { tag, length })
39    }
40}
41
42impl Encode for Header {
43    fn encoded_len(&self) -> Result<Length> {
44        self.tag.encoded_len()? + self.length.encoded_len()?
45    }
46
47    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
48        self.tag.encode(writer)?;
49        self.length.encode(writer)
50    }
51}
52
53impl DerOrd for Header {
54    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
55        match self.tag.der_cmp(&other.tag)? {
56            Ordering::Equal => self.length.der_cmp(&other.length),
57            ordering => Ok(ordering),
58        }
59    }
60}