From f3b8c9caf37c32662929948e3aa6d4a083e4c717 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Fri, 3 Oct 2025 13:26:29 +0200 Subject: [PATCH] der: improve docs for `Encode` and `Decode` --- der/src/decode.rs | 16 +++++++++++----- der/src/encode.rs | 26 +++++++++++++++++--------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/der/src/decode.rs b/der/src/decode.rs index d82bfa9af..452a624c5 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -16,10 +16,13 @@ use alloc::boxed::Box; #[cfg(feature = "ber")] use crate::EncodingRules; -/// Decoding trait. +/// Decode trait parses a complete TLV (Tag-Length-Value) structure. /// /// This trait provides the core abstraction upon which all decoding operations /// are based. +/// +/// When decoding fails, a [`Decode::Error`] type is thrown. +/// Most ASN.1 DER objects return a builtin der [`Error`] type as [`Decode::Error`], which can be made from [`ErrorKind`]. #[diagnostic::on_unimplemented( note = "Consider adding impls of `DecodeValue` and `FixedTag` to `{Self}`" )] @@ -27,7 +30,7 @@ pub trait Decode<'a>: Sized + 'a { /// Type returned in the event of a decoding error. type Error: From + 'static; - /// Attempt to decode this message using the provided decoder. + /// Attempt to decode this TLV message using the provided decoder. fn decode>(decoder: &mut R) -> Result; /// Parse `Self` from the provided BER-encoded byte slice. @@ -127,13 +130,16 @@ impl + PemLabel> DecodePem for T { } } -/// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`] -/// and [`Length`]. +/// DecodeValue trait parses the value part of a Tag-Length-Value object, +/// sans the [`Tag`] and [`Length`]. +/// +/// As opposed to [`Decode`], implementer is expected to read the inner content only, +/// without the [`Header`], which was decoded beforehand. pub trait DecodeValue<'a>: Sized { /// Type returned in the event of a decoding error. type Error: From + 'static; - /// Attempt to decode this message using the provided [`Reader`]. + /// Attempt to decode this value using the provided [`Reader`]. fn decode_value>(reader: &mut R, header: Header) -> Result; } diff --git a/der/src/encode.rs b/der/src/encode.rs index f29213cc8..822a435db 100644 --- a/der/src/encode.rs +++ b/der/src/encode.rs @@ -17,20 +17,22 @@ use { use crate::ErrorKind; #[cfg(doc)] -use crate::Tag; +use crate::{FixedTag, Tag}; -/// Encoding trait. +/// Encode trait produces a complete TLV (Tag-Length-Value) structure. +/// +/// As opposed to [`EncodeValue`], implementer is expected to write ASN.1 DER tag and length header before value. #[diagnostic::on_unimplemented( note = "Consider adding impls of `EncodeValue` and `FixedTag` to `{Self}`" )] pub trait Encode { - /// Compute the length of this value in bytes when encoded as ASN.1 DER. + /// Compute the length of this TLV object in bytes when encoded as ASN.1 DER. fn encoded_len(&self) -> Result; - /// Encode this value as ASN.1 DER using the provided [`Writer`]. + /// Encode this TLV object as ASN.1 DER using the provided [`Writer`]. fn encode(&self, encoder: &mut impl Writer) -> Result<()>; - /// Encode this value to the provided byte slice, returning a sub-slice + /// Encode this TLV object to the provided byte slice, returning a sub-slice /// containing the encoded message. fn encode_to_slice<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { let mut writer = SliceWriter::new(buf); @@ -38,7 +40,7 @@ pub trait Encode { writer.finish() } - /// Encode this message as ASN.1 DER, appending it to the provided + /// Encode this TLV object as ASN.1 DER, appending it to the provided /// byte vector. #[cfg(feature = "alloc")] fn encode_to_vec(&self, buf: &mut Vec) -> Result { @@ -60,7 +62,7 @@ pub trait Encode { actual_len.try_into() } - /// Encode this type as DER, returning a byte vector. + /// Encode this TLV object as ASN.1 DER, returning a byte vector. #[cfg(feature = "alloc")] fn to_der(&self) -> Result> { let mut buf = Vec::new(); @@ -73,12 +75,12 @@ impl Encode for T where T: EncodeValue + Tagged + ?Sized, { - /// Compute the length of this value in bytes when encoded as ASN.1 DER. + /// Compute the length of this TLV object in bytes when encoded as ASN.1 DER. fn encoded_len(&self) -> Result { self.value_len().and_then(|len| len.for_tlv(self.tag())) } - /// Encode this value as ASN.1 DER using the provided [`Writer`]. + /// Encode this TLV object as ASN.1 DER using the provided [`Writer`]. fn encode(&self, writer: &mut impl Writer) -> Result<()> { self.header()?.encode(writer)?; self.encode_value(writer) @@ -134,6 +136,12 @@ where /// Encode the value part of a Tag-Length-Value encoded field, sans the [`Tag`] /// and [`Length`]. +/// +/// As opposed to [`Encode`], implementer is expected to write the inner content only, +/// without the [`Header`]. +/// +/// When [`EncodeValue`] is paired with [`FixedTag`], +/// it produces a complete TLV ASN.1 DER encoding as [`Encode`] trait. pub trait EncodeValue { /// Get the [`Header`] used to encode this value. fn header(&self) -> Result