1 //! ASN.1 DER headers.
2 
3 use crate::{Decode, DerOrd, Encode, ErrorKind, Length, Reader, Result, Tag, Writer};
4 use core::cmp::Ordering;
5 
6 /// ASN.1 DER headers: tag + length component of TLV-encoded values
7 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
8 pub 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 
16 impl 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`].
new(tag: Tag, length: impl TryInto<Length>) -> Result<Self>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 
26 impl<'a> Decode<'a> for Header {
decode<R: Reader<'a>>(reader: &mut R) -> Result<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 
42 impl Encode for Header {
encoded_len(&self) -> Result<Length>43     fn encoded_len(&self) -> Result<Length> {
44         self.tag.encoded_len()? + self.length.encoded_len()?
45     }
46 
encode(&self, writer: &mut impl Writer) -> Result<()>47     fn encode(&self, writer: &mut impl Writer) -> Result<()> {
48         self.tag.encode(writer)?;
49         self.length.encode(writer)
50     }
51 }
52 
53 impl DerOrd for Header {
der_cmp(&self, other: &Self) -> Result<Ordering>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 }
61