summaryrefslogtreecommitdiffstats
path: root/vendor/der/src/asn1/sequence.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/der/src/asn1/sequence.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-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.rs84
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;
+}