From 2bdc827d87665833acae7425181ae5d833f75ab0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jan 2024 16:37:26 -0700 Subject: [PATCH] const-oid: make `ObjectIdentifier`'s size const generic (#1300) Previously the v0.10-pre release series has attempted to make `ObjectIdentifier` generic around a backing buffer containing the BER encoding and bounded on `AsRef<[u8]>`. This approach has a drawback though: we can't use derived `PartialEq`/`Eq`, which means it isn't possible to use in `match` expressions anymore, an ergonomics drawback noted in #1293, with the implementation reverted in #1299. An alternative way to go for what it was trying to implement: an `ObjectIdentifierRef` backed by a `&[u8]` is to use a separate struct. With that approach, there could be overlapping `PartialEq`/`Eq` impls that would allow the two to be compared. As a start towards going that route, this gets rid of the generic backing buffer and opts instead to make the struct const generic around its size with a default. --- const-oid/src/lib.rs | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/const-oid/src/lib.rs b/const-oid/src/lib.rs index 34b3d2a20..794daaa13 100644 --- a/const-oid/src/lib.rs +++ b/const-oid/src/lib.rs @@ -46,7 +46,7 @@ use core::{fmt, str::FromStr}; /// Default maximum size. /// /// Makes `ObjectIdentifier` 40-bytes total w\ 1-byte length. -const MAX_SIZE: usize = 39; +const DEFAULT_MAX_SIZE: usize = 39; /// A trait which associates an OID with a type. pub trait AssociatedOid { @@ -85,15 +85,15 @@ impl DynAssociatedOid for T { /// - The second arc MUST be within the range 0-39 /// - The BER/DER encoding of the OID MUST be shorter than /// [`ObjectIdentifier::MAX_SIZE`] -#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct ObjectIdentifier = Buffer> { +#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct ObjectIdentifier { /// Buffer containing BER/DER-serialized bytes (sans ASN.1 tag/length) - buffer: B, + buffer: Buffer, } impl ObjectIdentifier { /// Maximum size of a BER/DER-encoded OID in bytes. - pub const MAX_SIZE: usize = MAX_SIZE; + pub const MAX_SIZE: usize = DEFAULT_MAX_SIZE; /// Parse an [`ObjectIdentifier`] from the dot-delimited string form, /// panicking on parse errors. @@ -203,20 +203,7 @@ impl ObjectIdentifier { } } -impl<'a> ObjectIdentifier<&'a [u8]> { - /// Initialize OID from a byte slice without validating that it contains - /// a well-formed BER-encoded OID. - /// - /// Use with care, e.g. to define compact constants. - pub const fn from_bytes_unchecked(buffer: &'a [u8]) -> Self { - Self { buffer } - } -} - -impl ObjectIdentifier -where - B: AsRef<[u8]>, -{ +impl ObjectIdentifier { /// Get the BER/DER serialization of this OID as bytes. /// /// Note that this encoding omits the tag/length, and only contains the @@ -243,10 +230,7 @@ where } } -impl AsRef<[u8]> for ObjectIdentifier -where - B: AsRef<[u8]>, -{ +impl AsRef<[u8]> for ObjectIdentifier { fn as_ref(&self) -> &[u8] { self.as_bytes() } @@ -268,13 +252,13 @@ impl TryFrom<&[u8]> for ObjectIdentifier { } } -impl fmt::Debug for ObjectIdentifier { +impl fmt::Debug for ObjectIdentifier { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ObjectIdentifier({})", self) } } -impl fmt::Display for ObjectIdentifier { +impl fmt::Display for ObjectIdentifier { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let len = self.arcs().count();