diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/der/src/asn1/sequence.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/src/asn1/sequence.rs')
-rw-r--r-- | vendor/der/src/asn1/sequence.rs | 84 |
1 files changed, 84 insertions, 0 deletions
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<F, T>(&self, f: F) -> Result<T> + where + F: FnOnce(&[&dyn Encode]) -> Result<T>; +} + +impl<'a, M> EncodeValue for M +where + M: Sequence<'a>, +{ + fn value_len(&self) -> Result<Length> { + 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<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> { + Ok(Self { + body: ByteSlice::decode_value(reader, header)?, + }) + } +} + +impl EncodeValue for SequenceRef<'_> { + fn value_len(&self) -> Result<Length> { + 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; +} |