Temporary fix for serde issue (#1511)

* Generate serde bound instead of relying on serde_derive.

* remove comment
This commit is contained in:
cheme
2019-01-21 19:23:22 +01:00
committed by Gav Wood
parent 7ccd294de4
commit 8ec759d32e
3 changed files with 89 additions and 1 deletions
@@ -154,6 +154,7 @@ fn decl_store_extra_genesis(
let mut is_trait_needed = false;
let mut has_trait_field = false;
let mut serde_complete_bound = std::collections::HashSet::new();
let mut config_field = TokenStream2::new();
let mut config_field_default = TokenStream2::new();
let mut builders = TokenStream2::new();
@@ -184,6 +185,14 @@ fn decl_store_extra_genesis(
is_trait_needed = true;
has_trait_field = true;
}
for t in ext::get_non_bound_serde_derive_types(type_infos.full_type, &traitinstance).into_iter() {
serde_complete_bound.insert(t);
}
if let Some(kt) = type_infos.map_key {
for t in ext::get_non_bound_serde_derive_types(kt, &traitinstance).into_iter() {
serde_complete_bound.insert(t);
}
}
let storage_type = type_infos.typ.clone();
config_field.extend(quote!( pub #ident: #storage_type, ));
opt_build = Some(build.as_ref().map(|b| &b.expr.content).map(|b|quote!( #b ))
@@ -246,6 +255,11 @@ fn decl_store_extra_genesis(
is_trait_needed = true;
has_trait_field = true;
}
for t in ext::get_non_bound_serde_derive_types(extra_type, &traitinstance).into_iter() {
serde_complete_bound.insert(t);
}
let extrafield = &extra_field.content;
genesis_extrafields.extend(quote!{
#attrs pub #extrafield: #extra_type,
@@ -268,6 +282,25 @@ fn decl_store_extra_genesis(
}
}
let serde_bug_bound = if serde_complete_bound.len() > 0 {
let mut b_ser = String::new();
let mut b_dser = String::new();
for bound in serde_complete_bound {
let stype = quote!(#bound);
b_ser += &(stype.to_string() + " : " + &scrate.to_string() + "::serde::Serialize, ");
b_dser += &(stype.to_string() + " : " + &scrate.to_string() + "::serde::de::DeserializeOwned, ");
}
quote! {
#[serde(bound(serialize = #b_ser))]
#[serde(bound(deserialize = #b_dser))]
}
} else {
quote!()
};
let is_extra_genesis_needed = has_scall
|| !config_field.is_empty()
|| !genesis_extrafields.is_empty()
@@ -307,6 +340,7 @@ fn decl_store_extra_genesis(
#[cfg(feature = "std")]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
#serde_bug_bound
pub struct GenesisConfig#fparam {
#ph_field
#config_field
@@ -334,3 +334,57 @@ pub fn has_parametric_type_def(typ: &syn::Type, ident: &Ident, default: bool) ->
pub fn has_parametric_type(typ: &syn::Type, ident: &Ident) -> bool {
has_parametric_type_def(typ, ident, true)
}
/// Get case where serde does not include bound with serde_derive macros:
/// see https://github.com/serde-rs/serde/issues/1454
pub fn get_non_bound_serde_derive_types(typ: &syn::Type, t: &syn::Ident) -> Vec<syn::Type> {
let mut result = Vec::new();
get_non_bound_serde_derive_types_inner(typ, t, &mut result);
result
}
fn get_non_bound_serde_derive_types_inner(typ: &syn::Type, t: &syn::Ident, result: &mut Vec<syn::Type>) {
match *typ {
syn::Type::Path(ref path) => {
if heuristic_is_associated_path(&path.path,t) {
result.push(typ.clone());
}
for p in path.path.segments.iter() {
if let syn::PathArguments::AngleBracketed(ref args) = p.arguments {
for a in args.args.iter() {
if let syn::GenericArgument::Type(ref ty) = a {
get_non_bound_serde_derive_types_inner(ty, t, result)
}
}
}
}
},
syn::Type::Slice(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::Array(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::Ptr(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::Reference(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::BareFn(..) => (),
syn::Type::Never(..) => (),
syn::Type::Tuple(ref inner) => for e in inner.elems.iter() {
get_non_bound_serde_derive_types_inner(e, t, result)
},
syn::Type::TraitObject(..) => (),
syn::Type::ImplTrait(..) => (),
syn::Type::Paren(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::Group(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result),
syn::Type::Infer(..) => (),
syn::Type::Macro(..) => (),
syn::Type::Verbatim(..) => (),
}
}
fn heuristic_is_associated_path(path: &syn::Path,t: &syn::Ident) -> bool {
if let Some(syn::punctuated::Pair::Punctuated(s,_)) = path.segments.first() {
&s.ident == t
} else {
false
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
#![cfg_attr(not(feature = "std"), feature(alloc))]
#[cfg(feature = "std")]
extern crate serde;
pub extern crate serde;
#[doc(hidden)]
pub extern crate sr_std as rstd;