Skip to content

Commit

Permalink
Remove implementation of SimpleAsn1Writable for &T
Browse files Browse the repository at this point in the history
I don't know if this is a good idea.
  • Loading branch information
alex committed Nov 26, 2024
1 parent f8ca030 commit fa57915
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 48 deletions.
52 changes: 19 additions & 33 deletions asn1_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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<asn1::ObjectIdentifier>),
true,
);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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())
}
};
Expand Down Expand Up @@ -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())
}}
}
Expand All @@ -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))?;
}
}
}
Expand All @@ -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))?;
}
}
}
Expand All @@ -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)?;
Expand Down Expand Up @@ -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"),
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
24 changes: 10 additions & 14 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,6 @@ impl<T: SimpleAsn1Writable> Asn1Writable for T {
}
}

impl<T: SimpleAsn1Writable> SimpleAsn1Writable for &T {
const TAG: Tag = T::TAG;
fn write_data(&self, dest: &mut WriteBuf) -> WriteResult {
T::write_data(self, dest)
}
}

impl<T: SimpleAsn1Writable> SimpleAsn1Writable for Box<T> {
const TAG: Tag = T::TAG;
fn write_data(&self, dest: &mut WriteBuf) -> WriteResult {
Expand Down Expand Up @@ -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 = ();
Expand Down Expand Up @@ -1734,6 +1720,7 @@ impl<T: Asn1Writable, V: Borrow<[T]>> 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<T, const TAG: u32> {
inner: T,
}
Expand All @@ -1743,6 +1730,10 @@ impl<T, const TAG: u32> Implicit<T, { TAG }> {
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
}
Expand Down Expand Up @@ -1778,6 +1769,7 @@ impl<T: SimpleAsn1Writable, const TAG: u32> SimpleAsn1Writable for Implicit<T, {
/// `Explicit` is a type which wraps another ASN.1 type, indicating that the tag is an ASN.1
/// `EXPLICIT`. This will generally be used with `Option` or `Choice`.
#[derive(PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct Explicit<T, const TAG: u32> {
inner: T,
}
Expand All @@ -1787,6 +1779,10 @@ impl<T, const TAG: u32> Explicit<T, { TAG }> {
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
}
Expand Down

0 comments on commit fa57915

Please sign in to comment.