From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- vendor/der/src/asn1/sequence.rs | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 vendor/der/src/asn1/sequence.rs (limited to 'vendor/der/src/asn1/sequence.rs') diff --git a/vendor/der/src/asn1/sequence.rs b/vendor/der/src/asn1/sequence.rs new file mode 100644 index 000000000..d2f6bc5d1 --- /dev/null +++ b/vendor/der/src/asn1/sequence.rs @@ -0,0 +1,84 @@ +//! The [`Sequence`] trait simplifies writing decoders/encoders which map ASN.1 +//! `SEQUENCE`s to Rust structs. + +use crate::{ + ByteSlice, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Result, + Tag, Writer, +}; + +/// ASN.1 `SEQUENCE` trait. +/// +/// Types which impl this trait receive blanket impls for the [`Decode`], +/// [`Encode`], and [`FixedTag`] traits. +pub trait Sequence<'a>: Decode<'a> { + /// Call the provided function with a slice of [`Encode`] trait objects + /// representing the fields of this `SEQUENCE`. + /// + /// This method uses a callback because structs with fields which aren't + /// directly [`Encode`] may need to construct temporary values from + /// their fields prior to encoding. + fn fields(&self, f: F) -> Result + where + F: FnOnce(&[&dyn Encode]) -> Result; +} + +impl<'a, M> EncodeValue for M +where + M: Sequence<'a>, +{ + fn value_len(&self) -> Result { + self.fields(|fields| { + fields + .iter() + .try_fold(Length::ZERO, |acc, field| acc + field.encoded_len()?) + }) + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + self.fields(|fields| { + for &field in fields { + field.encode(writer)?; + } + + Ok(()) + }) + } +} + +impl<'a, M> FixedTag for M +where + M: Sequence<'a>, +{ + const TAG: Tag = Tag::Sequence; +} + +/// The [`SequenceRef`] type provides raw access to the octets which comprise a +/// DER-encoded `SEQUENCE`. +/// +/// This is a zero-copy reference type which borrows from the input data. +pub struct SequenceRef<'a> { + /// Body of the `SEQUENCE`. + body: ByteSlice<'a>, +} + +impl<'a> DecodeValue<'a> for SequenceRef<'a> { + fn decode_value>(reader: &mut R, header: Header) -> Result { + Ok(Self { + body: ByteSlice::decode_value(reader, header)?, + }) + } +} + +impl EncodeValue for SequenceRef<'_> { + fn value_len(&self) -> Result { + Ok(self.body.len()) + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + self.body.encode_value(writer) + } +} + +impl<'a> FixedTag for SequenceRef<'a> { + const TAG: Tag = Tag::Sequence; +} -- cgit v1.2.3