From fa57915a8683f3a2153c89de79f12710838bc19c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 23 Nov 2024 19:04:40 -0500 Subject: [PATCH] Remove implementation of SimpleAsn1Writable for &T I don't know if this is a good idea. --- asn1_derive/src/lib.rs | 52 +++++++++++++++--------------------------- src/lib.rs | 1 - src/types.rs | 24 ++++++++----------- 3 files changed, 29 insertions(+), 48 deletions(-) diff --git a/asn1_derive/src/lib.rs b/asn1_derive/src/lib.rs index a50c4a1..77967b6 100644 --- a/asn1_derive/src/lib.rs +++ b/asn1_derive/src/lib.rs @@ -17,7 +17,6 @@ pub fn derive_asn1_read(input: proc_macro::TokenStream) -> proc_macro::TokenStre all_field_types(&input.data, &input.generics), syn::parse_quote!(asn1::Asn1Readable<#lifetime_name>), syn::parse_quote!(asn1::Asn1DefinedByReadable<#lifetime_name, asn1::ObjectIdentifier>), - false, ); let (impl_generics, _, where_clause) = generics.split_for_impl(); @@ -67,7 +66,6 @@ pub fn derive_asn1_write(input: proc_macro::TokenStream) -> proc_macro::TokenStr fields, syn::parse_quote!(asn1::Asn1Writable), syn::parse_quote!(asn1::Asn1DefinedByWritable), - true, ); let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); @@ -402,7 +400,6 @@ fn add_bounds( field_types: Vec<(syn::Type, OpType, bool)>, bound: syn::TypeParamBound, defined_by_bound: syn::TypeParamBound, - add_ref: bool, ) { let where_clause = if field_types.is_empty() { return; @@ -416,11 +413,11 @@ fn add_bounds( }; for (f, op_type, has_default) in field_types { - let (bounded_ty, required_bound) = match (op_type, add_ref) { - (OpType::Regular, _) => (f, bound.clone()), - (OpType::DefinedBy(_), _) => (f, defined_by_bound.clone()), + let (bounded_ty, required_bound) = match op_type { + OpType::Regular => (f, bound.clone()), + OpType::DefinedBy(_) => (f, defined_by_bound.clone()), - (OpType::Implicit(OpTypeArgs { value, required }), false) => { + OpType::Implicit(OpTypeArgs { value, required }) => { let ty = if required || has_default { syn::parse_quote!(asn1::Implicit::<#f, #value>) } else { @@ -429,32 +426,14 @@ fn add_bounds( (ty, bound.clone()) } - (OpType::Implicit(OpTypeArgs { value, required }), true) => { - let ty = if required || has_default { - syn::parse_quote!(for<'asn1_internal> asn1::Implicit::<&'asn1_internal #f, #value>) - } else { - syn::parse_quote!(for<'asn1_internal> asn1::Implicit::<&'asn1_internal <#f as asn1::OptionExt>::T, #value>) - }; - - (ty, bound.clone()) - } - (OpType::Explicit(OpTypeArgs { value, required }), false) => { + OpType::Explicit(OpTypeArgs { value, required }) => { let ty = if required || has_default { syn::parse_quote!(asn1::Explicit::<#f, #value>) } else { syn::parse_quote!(asn1::Explicit::<<#f as asn1::OptionExt>::T, #value>) }; - (ty, bound.clone()) - } - (OpType::Explicit(OpTypeArgs { value, required }), true) => { - let ty = if required || has_default { - syn::parse_quote!(for<'asn1_internal> asn1::Explicit::<&'asn1_internal #f, #value>) - } else { - syn::parse_quote!(for<'asn1_internal> asn1::Explicit::<&'asn1_internal <#f as asn1::OptionExt>::T, #value>) - }; - (ty, bound.clone()) } }; @@ -750,8 +729,9 @@ fn generate_write_element( ) -> proc_macro2::TokenStream { let (write_type, default) = extract_field_properties(&f.attrs); + let has_default = default.is_some(); if let Some(default) = default { - field_read = quote::quote! {&{ + field_read = quote::quote! {{ asn1::to_optional_default(#field_read, &(#default).into()) }} } @@ -761,12 +741,12 @@ fn generate_write_element( let value = arg.value; if arg.required { quote::quote_spanned! {f.span() => - w.write_element(&asn1::Explicit::<_, #value>::new(#field_read))?; + w.write_element(asn1::Explicit::<_, #value>::from_ref(#field_read))?; } } else { quote::quote_spanned! {f.span() => if let Some(v) = #field_read { - w.write_element(&asn1::Explicit::<_, #value>::new(v))?; + w.write_element(asn1::Explicit::<_, #value>::from_ref(v))?; } } } @@ -775,12 +755,12 @@ fn generate_write_element( let value = arg.value; if arg.required { quote::quote_spanned! {f.span() => - w.write_element(&asn1::Implicit::<_, #value>::new(#field_read))?; + w.write_element(asn1::Implicit::<_, #value>::from_ref(#field_read))?; } } else { quote::quote_spanned! {f.span() => if let Some(v) = #field_read { - w.write_element(&asn1::Implicit::<_, #value>::new(v))?; + w.write_element(asn1::Implicit::<_, #value>::from_ref(v))?; } } } @@ -790,6 +770,12 @@ fn generate_write_element( quote::quote! { w.write_element(asn1::writable_defined_by_item(#defined_by_marker_read))?; } + } else if has_default { + quote::quote! { + if let Some(v) = #field_read { + w.write_element(v)?; + } + } } else { quote::quote! { w.write_element(#field_read)?; @@ -870,13 +856,13 @@ fn generate_enum_write_block(name: &syn::Ident, data: &syn::DataEnum) -> proc_ma OpType::Explicit(arg) => { let tag = arg.value; quote::quote! { - #name::#ident(value) => w.write_element(&asn1::Explicit::<_, #tag>::new(value)), + #name::#ident(value) => w.write_element(asn1::Explicit::<_, #tag>::from_ref(value)), } } OpType::Implicit(arg) => { let tag = arg.value; quote::quote! { - #name::#ident(value) => w.write_element(&asn1::Implicit::<_, #tag>::new(value)), + #name::#ident(value) => w.write_element(asn1::Implicit::<_, #tag>::from_ref(value)), } } OpType::DefinedBy(_) => panic!("Can't use #[defined_by] in an Asn1Write on an enum"), diff --git a/src/lib.rs b/src/lib.rs index 271f393..9736c62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![forbid(unsafe_code)] #![deny(rust_2018_idioms)] //! This crate provides you with the ability to generate and parse ASN.1 diff --git a/src/types.rs b/src/types.rs index 5c5c0ad..d5d795e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -82,13 +82,6 @@ impl Asn1Writable for T { } } -impl SimpleAsn1Writable for &T { - const TAG: Tag = T::TAG; - fn write_data(&self, dest: &mut WriteBuf) -> WriteResult { - T::write_data(self, dest) - } -} - impl SimpleAsn1Writable for Box { const TAG: Tag = T::TAG; fn write_data(&self, dest: &mut WriteBuf) -> WriteResult { @@ -145,13 +138,6 @@ impl Asn1Writable for Tlv<'_> { } } -impl Asn1Writable for &Tlv<'_> { - #[inline] - fn write(&self, w: &mut Writer<'_>) -> WriteResult { - Tlv::write(self, w) - } -} - /// The ASN.1 NULL type, for use with `Parser.read_element` and /// `Writer.write_element`. pub type Null = (); @@ -1734,6 +1720,7 @@ impl> SimpleAsn1Writable for SetOfWriter<'_, T, /// `Implicit` is a type which wraps another ASN.1 type, indicating that the tag is an ASN.1 /// `IMPLICIT`. This will generally be used with `Option` or `Choice`. #[derive(PartialEq, Eq, Debug)] +#[repr(transparent)] pub struct Implicit { inner: T, } @@ -1743,6 +1730,10 @@ impl Implicit { Implicit { inner: v } } + pub fn from_ref(v: &T) -> &Self { + unsafe { &*(v as *const T as *const Self) } + } + pub fn as_inner(&self) -> &T { &self.inner } @@ -1778,6 +1769,7 @@ impl SimpleAsn1Writable for Implicit { inner: T, } @@ -1787,6 +1779,10 @@ impl Explicit { Explicit { inner: v } } + pub fn from_ref(v: &T) -> &Self { + unsafe { &*(v as *const T as *const Self) } + } + pub fn as_inner(&self) -> &T { &self.inner }