Skip to content

Commit

Permalink
Minor codegen hygiene improvements and modernizations (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbepop authored Sep 13, 2021
1 parent 205bb1a commit 4fa5ddf
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 65 deletions.
18 changes: 11 additions & 7 deletions derive/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub fn quote(
type_name: &Ident,
type_generics: &TokenStream,
input: &TokenStream,
crate_ident: &TokenStream,
) -> TokenStream {
match *data {
Data::Struct(ref data) => match data.fields {
Expand All @@ -39,6 +40,7 @@ pub fn quote(
&type_name.to_string(),
input,
&data.fields,
crate_ident,
),
Fields::Unit => {
quote_spanned! { data.fields.span() =>
Expand All @@ -65,6 +67,7 @@ pub fn quote(
&format!("{}::{}", type_name, name),
input,
&v.fields,
crate_ident,
);

quote_spanned! { v.span() =>
Expand Down Expand Up @@ -96,7 +99,7 @@ pub fn quote(
}
}

fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenStream {
fn create_decode_expr(field: &Field, name: &str, input: &TokenStream, crate_ident: &TokenStream) -> TokenStream {
let encoded_as = utils::get_encoded_as_type(field);
let compact = utils::is_compact(field);
let skip = utils::should_skip(&field.attrs);
Expand All @@ -117,7 +120,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt
quote_spanned! { field.span() =>
{
let #res = <
<#field_type as _parity_scale_codec::HasCompact>::Type as _parity_scale_codec::Decode
<#field_type as #crate_ident::HasCompact>::Type as #crate_ident::Decode
>::decode(#input);
match #res {
::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)),
Expand All @@ -128,7 +131,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt
} else if let Some(encoded_as) = encoded_as {
quote_spanned! { field.span() =>
{
let #res = <#encoded_as as _parity_scale_codec::Decode>::decode(#input);
let #res = <#encoded_as as #crate_ident::Decode>::decode(#input);
match #res {
::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)),
::core::result::Result::Ok(#res) => #res.into(),
Expand All @@ -141,7 +144,7 @@ fn create_decode_expr(field: &Field, name: &str, input: &TokenStream) -> TokenSt
let field_type = &field.ty;
quote_spanned! { field.span() =>
{
let #res = <#field_type as _parity_scale_codec::Decode>::decode(#input);
let #res = <#field_type as #crate_ident::Decode>::decode(#input);
match #res {
::core::result::Result::Err(e) => return ::core::result::Result::Err(e.chain(#err_msg)),
::core::result::Result::Ok(#res) => #res,
Expand All @@ -155,7 +158,8 @@ fn create_instance(
name: TokenStream,
name_str: &str,
input: &TokenStream,
fields: &Fields
fields: &Fields,
crate_ident: &TokenStream,
) -> TokenStream {
match *fields {
Fields::Named(ref fields) => {
Expand All @@ -165,7 +169,7 @@ fn create_instance(
Some(a) => format!("{}::{}", name_str, a),
None => format!("{}", name_str), // Should never happen, fields are named.
};
let decode = create_decode_expr(f, &field_name, input);
let decode = create_decode_expr(f, &field_name, input, crate_ident);

quote_spanned! { f.span() =>
#name_ident: #decode
Expand All @@ -182,7 +186,7 @@ fn create_instance(
let recurse = fields.unnamed.iter().enumerate().map(|(i, f) | {
let field_name = format!("{}.{}", name_str, i);

create_decode_expr(f, &field_name, input)
create_decode_expr(f, &field_name, input, crate_ident)
});

quote_spanned! { fields.span() =>
Expand Down
53 changes: 30 additions & 23 deletions derive/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type FieldsList = Punctuated<Field, Comma>;
fn encode_single_field(
field: &Field,
field_name: TokenStream,
crate_ident: &TokenStream,
) -> TokenStream {
let encoded_as = utils::get_encoded_as_type(field);
let compact = utils::is_compact(field);
Expand All @@ -52,16 +53,16 @@ fn encode_single_field(
let field_type = &field.ty;
quote_spanned! {
field.span() => {
<<#field_type as _parity_scale_codec::HasCompact>::Type as
_parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name)
<<#field_type as #crate_ident::HasCompact>::Type as
#crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name)
}
}
} else if let Some(encoded_as) = encoded_as {
let field_type = &field.ty;
quote_spanned! {
field.span() => {
<#encoded_as as
_parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name)
#crate_ident::EncodeAsRef<'_, #field_type>>::RefType::from(#field_name)
}
}
} else {
Expand All @@ -74,19 +75,19 @@ fn encode_single_field(
let i_self = quote! { self };

quote_spanned! { field.span() =>
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>(
fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>(
&#i_self,
__codec_dest_edqy: &mut __CodecOutputEdqy
) {
_parity_scale_codec::Encode::encode_to(&#final_field_variable, __codec_dest_edqy)
#crate_ident::Encode::encode_to(&#final_field_variable, __codec_dest_edqy)
}

fn encode(&#i_self) -> _parity_scale_codec::alloc::vec::Vec<u8> {
_parity_scale_codec::Encode::encode(&#final_field_variable)
fn encode(&#i_self) -> #crate_ident::alloc::vec::Vec<::core::primitive::u8> {
#crate_ident::Encode::encode(&#final_field_variable)
}

fn using_encoded<R, F: ::core::ops::FnOnce(&[::core::primitive::u8]) -> R>(&#i_self, f: F) -> R {
_parity_scale_codec::Encode::using_encoded(&#final_field_variable, f)
#crate_ident::Encode::using_encoded(&#final_field_variable, f)
}
}
}
Expand All @@ -95,6 +96,7 @@ fn encode_fields<F>(
dest: &TokenStream,
fields: &FieldsList,
field_name: F,
crate_ident: &TokenStream,
) -> TokenStream where
F: Fn(usize, &Option<Ident>) -> TokenStream,
{
Expand All @@ -117,10 +119,10 @@ fn encode_fields<F>(
let field_type = &f.ty;
quote_spanned! {
f.span() => {
_parity_scale_codec::Encode::encode_to(
#crate_ident::Encode::encode_to(
&<
<#field_type as _parity_scale_codec::HasCompact>::Type as
_parity_scale_codec::EncodeAsRef<'_, #field_type>
<#field_type as #crate_ident::HasCompact>::Type as
#crate_ident::EncodeAsRef<'_, #field_type>
>::RefType::from(#field),
#dest,
);
Expand All @@ -130,10 +132,10 @@ fn encode_fields<F>(
let field_type = &f.ty;
quote_spanned! {
f.span() => {
_parity_scale_codec::Encode::encode_to(
#crate_ident::Encode::encode_to(
&<
#encoded_as as
_parity_scale_codec::EncodeAsRef<'_, #field_type>
#crate_ident::EncodeAsRef<'_, #field_type>
>::RefType::from(#field),
#dest,
);
Expand All @@ -145,7 +147,7 @@ fn encode_fields<F>(
}
} else {
quote_spanned! { f.span() =>
_parity_scale_codec::Encode::encode_to(#field, #dest);
#crate_ident::Encode::encode_to(#field, #dest);
}
}
});
Expand All @@ -155,7 +157,7 @@ fn encode_fields<F>(
}
}

fn try_impl_encode_single_field_optimisation(data: &Data) -> Option<TokenStream> {
fn try_impl_encode_single_field_optimisation(data: &Data, crate_ident: &TokenStream) -> Option<TokenStream> {
match *data {
Data::Struct(ref data) => {
match data.fields {
Expand All @@ -164,7 +166,8 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option<TokenStream>
let name = &field.ident;
Some(encode_single_field(
field,
quote!(&self.#name)
quote!(&self.#name),
crate_ident,
))
},
Fields::Unnamed(ref fields) if utils::filter_skip_unnamed(fields).count() == 1 => {
Expand All @@ -173,7 +176,8 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option<TokenStream>

Some(encode_single_field(
field,
quote!(&self.#id)
quote!(&self.#id),
crate_ident,
))
},
_ => None,
Expand All @@ -183,7 +187,7 @@ fn try_impl_encode_single_field_optimisation(data: &Data) -> Option<TokenStream>
}
}

fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
fn impl_encode(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream {
let self_ = quote!(self);
let dest = &quote!(__codec_dest_edqy);
let encoding = match *data {
Expand All @@ -193,6 +197,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
dest,
&fields.named,
|_, name| quote!(&#self_.#name),
crate_ident,
),
Fields::Unnamed(ref fields) => encode_fields(
dest,
Expand All @@ -201,6 +206,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
let i = syn::Index::from(i);
quote!(&#self_.#i)
},
crate_ident,
),
Fields::Unit => quote!(),
}
Expand Down Expand Up @@ -236,6 +242,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
dest,
&fields.named,
|a, b| field_name(a, b),
crate_ident,
);

quote_spanned! { f.span() =>
Expand All @@ -261,6 +268,7 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
dest,
&fields.unnamed,
|a, b| field_name(a, b),
crate_ident,
);

quote_spanned! { f.span() =>
Expand Down Expand Up @@ -292,9 +300,8 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
"Union types are not supported."
).to_compile_error(),
};

quote! {
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>(
fn encode_to<__CodecOutputEdqy: #crate_ident::Output + ?::core::marker::Sized>(
&#self_,
#dest: &mut __CodecOutputEdqy
) {
Expand All @@ -303,11 +310,11 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
}
}

pub fn quote(data: &Data, type_name: &Ident) -> TokenStream {
if let Some(implementation) = try_impl_encode_single_field_optimisation(data) {
pub fn quote(data: &Data, type_name: &Ident, crate_ident: &TokenStream) -> TokenStream {
if let Some(implementation) = try_impl_encode_single_field_optimisation(data, crate_ident) {
implementation
} else {
impl_encode(data, type_name)
impl_encode(data, type_name, crate_ident)
}
}

Expand Down
Loading

0 comments on commit 4fa5ddf

Please sign in to comment.