From 6b4af73fc146c0cb52e0cfac17a3c993dd8d60ce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Oct 2024 12:46:58 -0600 Subject: [PATCH] der_derive: use `TryFrom` conversions for `asn1(type = ...)` Previously it was using `::new`. Using `TryFrom` is more flexible in terms of the possible conversions that it permits. Also fills out the missing `From`/`TryFrom` conversions needed for the existing crates in this repo (most notably `x509-cert` to compile with the changes). --- der/src/asn1/ia5_string.rs | 14 ++++++++++---- der/src/asn1/octet_string.rs | 8 ++++++++ der/src/asn1/printable_string.rs | 6 ++++++ der/src/asn1/teletex_string.rs | 6 ++++++ der/src/asn1/utf8_string.rs | 16 ++++++++++++++++ der_derive/src/asn1_type.rs | 2 +- der_derive/src/choice/variant.rs | 2 +- 7 files changed, 48 insertions(+), 6 deletions(-) diff --git a/der/src/asn1/ia5_string.rs b/der/src/asn1/ia5_string.rs index c4f46e91f..a9f5886f0 100644 --- a/der/src/asn1/ia5_string.rs +++ b/der/src/asn1/ia5_string.rs @@ -137,15 +137,21 @@ mod allocation { } impl<'a> From> for Ia5String { - fn from(international_string: Ia5StringRef<'a>) -> Ia5String { - let inner = international_string.inner.into(); + fn from(ia5_string: Ia5StringRef<'a>) -> Ia5String { + let inner = ia5_string.inner.into(); Self { inner } } } impl<'a> From<&'a Ia5String> for AnyRef<'a> { - fn from(international_string: &'a Ia5String) -> AnyRef<'a> { - AnyRef::from_tag_and_value(Tag::Ia5String, (&international_string.inner).into()) + fn from(ia5_string: &'a Ia5String) -> AnyRef<'a> { + AnyRef::from_tag_and_value(Tag::Ia5String, (&ia5_string.inner).into()) + } + } + + impl<'a> From<&'a Ia5String> for Ia5StringRef<'a> { + fn from(ia5_string: &'a Ia5String) -> Ia5StringRef<'a> { + ia5_string.owned_to_ref() } } diff --git a/der/src/asn1/octet_string.rs b/der/src/asn1/octet_string.rs index 790122d93..08025952c 100644 --- a/der/src/asn1/octet_string.rs +++ b/der/src/asn1/octet_string.rs @@ -96,6 +96,14 @@ impl<'a> From> for &'a [u8] { } } +impl<'a> TryFrom<&'a [u8]> for OctetStringRef<'a> { + type Error = Error; + + fn try_from(byte_slice: &'a [u8]) -> Result { + OctetStringRef::new(byte_slice) + } +} + #[cfg(feature = "alloc")] pub use self::allocating::OctetString; diff --git a/der/src/asn1/printable_string.rs b/der/src/asn1/printable_string.rs index 3d73d83e6..ca72646c6 100644 --- a/der/src/asn1/printable_string.rs +++ b/der/src/asn1/printable_string.rs @@ -204,6 +204,12 @@ mod allocation { } } + impl<'a> From<&'a PrintableString> for PrintableStringRef<'a> { + fn from(printable_string: &'a PrintableString) -> PrintableStringRef<'a> { + printable_string.owned_to_ref() + } + } + impl<'a> RefToOwned<'a> for PrintableStringRef<'a> { type Owned = PrintableString; fn ref_to_owned(&self) -> Self::Owned { diff --git a/der/src/asn1/teletex_string.rs b/der/src/asn1/teletex_string.rs index 7c6ea621d..668d8252d 100644 --- a/der/src/asn1/teletex_string.rs +++ b/der/src/asn1/teletex_string.rs @@ -166,6 +166,12 @@ mod allocation { } } + impl<'a> From<&'a TeletexString> for TeletexStringRef<'a> { + fn from(teletex_string: &'a TeletexString) -> TeletexStringRef<'a> { + teletex_string.owned_to_ref() + } + } + impl<'a> RefToOwned<'a> for TeletexStringRef<'a> { type Owned = TeletexString; fn ref_to_owned(&self) -> Self::Owned { diff --git a/der/src/asn1/utf8_string.rs b/der/src/asn1/utf8_string.rs index 9ffdc2044..f2718f36e 100644 --- a/der/src/asn1/utf8_string.rs +++ b/der/src/asn1/utf8_string.rs @@ -68,6 +68,22 @@ impl<'a> From> for AnyRef<'a> { } } +impl<'a> TryFrom<&'a str> for Utf8StringRef<'a> { + type Error = Error; + + fn try_from(s: &'a str) -> Result { + Self::new(s) + } +} + +impl<'a> TryFrom<&'a String> for Utf8StringRef<'a> { + type Error = Error; + + fn try_from(s: &'a String) -> Result { + Self::new(s.as_str()) + } +} + impl<'a> fmt::Debug for Utf8StringRef<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Utf8String({:?})", self.as_str()) diff --git a/der_derive/src/asn1_type.rs b/der_derive/src/asn1_type.rs index cd21614a1..69a3886ee 100644 --- a/der_derive/src/asn1_type.rs +++ b/der_derive/src/asn1_type.rs @@ -77,7 +77,7 @@ impl Asn1Type { | Asn1Type::PrintableString | Asn1Type::TeletexString | Asn1Type::VideotexString - | Asn1Type::Utf8String => quote!(#type_path::new(#binding)?), + | Asn1Type::Utf8String => quote!(#type_path::try_from(#binding)?), _ => quote!(#type_path::try_from(#binding)?), } } diff --git a/der_derive/src/choice/variant.rs b/der_derive/src/choice/variant.rs index c11ecbf36..2b2eadd34 100644 --- a/der_derive/src/choice/variant.rs +++ b/der_derive/src/choice/variant.rs @@ -225,7 +225,7 @@ mod tests { assert_eq!( variant.to_encode_value_tokens().to_string(), quote! { - Self::ExampleVariant(variant) => ::der::asn1::Utf8StringRef::new(variant)?.encode_value(encoder), + Self::ExampleVariant(variant) => ::der::asn1::Utf8StringRef::try_from(variant)?.encode_value(encoder), } .to_string() );