Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Decl_storage macro : force traits. (#1317)
Browse files Browse the repository at this point in the history
* Missing trait def on two calls.

Slight mcla refact on transfo.

* Allways provide GenesisConfig even when useless (for runtime module
export).

* Revert "Allways provide GenesisConfig even when useless (for runtime module"

This reverts commit 84a29bc.

* Fix Vec usage (from rstd).
  • Loading branch information
cheme authored and bkchr committed Jan 7, 2019
1 parent 91b6c79 commit 6cef98d
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 46 deletions.
112 changes: 66 additions & 46 deletions srml/support/procedural/src/storage/transformation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn decl_store_extra_genesis(
..
} = sline;

let is_simple = if let DeclStorageType::Simple(..) = storage_type { true } else { false };
let type_infos = get_type_infos(storage_type);

let mut opt_build;
// need build line
Expand All @@ -180,20 +180,16 @@ fn decl_store_extra_genesis(
let ident = &getter.getfn.content;
quote!( #ident )
};
let option_extracteed = if let DeclStorageType::Simple(ref st) = storage_type {
if ext::has_parametric_type(st, traitinstance) {
is_trait_needed = true;
has_trait_field = true;
}
ext::extract_type_option(st)
} else { None };
let is_option = option_extracteed.is_some();
let storage_type = option_extracteed.unwrap_or_else(|| quote!( #storage_type ));
if type_infos.is_simple && ext::has_parametric_type(type_infos.full_type, traitinstance) {
is_trait_needed = true;
has_trait_field = true;
}
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 ))
.unwrap_or_else(|| quote!( (|config: &GenesisConfig<#traitinstance>| config.#ident.clone()) )));
let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d|
if is_option {
if type_infos.is_option {
quote!( #d.unwrap_or_default() )
} else {
quote!( #d )
Expand All @@ -204,20 +200,25 @@ fn decl_store_extra_genesis(
opt_build = build.as_ref().map(|b| &b.expr.content).map(|b| quote!( #b ));
}

let typ = type_infos.typ;
if let Some(builder) = opt_build {
is_trait_needed = true;
if is_simple {
if type_infos.is_simple {
builders.extend(quote!{{
use #scrate::codec::Encode;
let v = (#builder)(&self);
r.insert(Self::hash(<#name<#traitinstance>>::key()).to_vec(), v.encode());
r.insert(Self::hash(
<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key()
).to_vec(), v.encode());
}});
} else {
let kty = type_infos.map_key.clone().expect("is not simple; qed");
builders.extend(quote!{{
use #scrate::codec::Encode;
let data = (#builder)(&self);
for (k, v) in data.into_iter() {
r.insert(Self::hash(&<#name<#traitinstance>>::key_for(k)).to_vec(), v.encode());
let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(&k);
r.insert(Self::hash(&key[..]).to_vec(), v.encode());
}
}});
}
Expand Down Expand Up @@ -361,25 +362,22 @@ fn decl_storage_items(
..
} = sline;

let (is_simple, extracted_opt, stk, gettype) = match storage_type {
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
};
let is_option = extracted_opt.is_some();
let type_infos = get_type_infos(storage_type);
let gettype = type_infos.full_type;
let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d| quote!( #d ))
.unwrap_or_else(|| quote!{ Default::default() });

let typ = extracted_opt.unwrap_or(quote!( #gettype ));
let typ = type_infos.typ;

let option_simple_1 = if !is_option {
let option_simple_1 = if !type_infos.is_option {
// raw type case
quote!( unwrap_or_else )
} else {
// Option<> type case
quote!( or_else )
};
let implementation = if is_simple {
let mutate_impl = if !is_option {
let implementation = if type_infos.is_simple {
let mutate_impl = if !type_infos.is_option {
quote!{
<Self as #scrate::storage::generator::StorageValue<#typ>>::put(&val, storage)
}
Expand Down Expand Up @@ -430,8 +428,8 @@ fn decl_storage_items(

}
} else {
let kty = stk.expect("is not simple; qed");
let mutate_impl = if !is_option {
let kty = type_infos.map_key.expect("is not simple; qed");
let mutate_impl = if !type_infos.is_option {
quote!{
<Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::insert(key, &val, storage)
}
Expand Down Expand Up @@ -531,20 +529,19 @@ fn impl_store_fns(

if let Some(getter) = getter {
let get_fn = &getter.getfn.content;
let (is_simple, extracted_opt, stk, gettype) = match storage_type {
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
};

let typ = extracted_opt.unwrap_or(quote!(#gettype));
let item = if is_simple {
let type_infos = get_type_infos(storage_type);
let gettype = type_infos.full_type;

let typ = type_infos.typ;
let item = if type_infos.is_simple {
quote!{
pub fn #get_fn() -> #gettype {
<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage)
}
}
} else {
let kty = stk.expect("is not simple; qed");
let kty = type_infos.map_key.expect("is not simple; qed");
// map
quote!{
pub fn #get_fn<K: #scrate::storage::generator::Borrow<#kty>>(key: K) -> #gettype {
Expand Down Expand Up @@ -576,22 +573,19 @@ fn store_functions_to_metadata (
..
} = sline;

let (is_simple, extracted_opt, stk, gettype) = match storage_type {
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
};
let type_infos = get_type_infos(storage_type);
let gettype = type_infos.full_type;

let is_option = extracted_opt.is_some();
let typ = extracted_opt.unwrap_or(quote!( #gettype ));
let stype = if is_simple {
let typ = type_infos.typ;
let stype = if type_infos.is_simple {
let styp = clean_type_string(&typ.to_string());
quote!{
#scrate::storage::generator::StorageFunctionType::Plain(
#scrate::storage::generator::DecodeDifferent::Encode(#styp),
)
}
} else {
let kty = stk.expect("is not simple; qed");
let kty = type_infos.map_key.expect("is not simple; qed");
let kty = clean_type_string(&quote!(#kty).to_string());
let styp = clean_type_string(&typ.to_string());
quote!{
Expand All @@ -601,13 +595,13 @@ fn store_functions_to_metadata (
}
}
};
let modifier = if !is_option {
let modifier = if type_infos.is_option {
quote!{
#scrate::storage::generator::StorageFunctionModifier::Default
#scrate::storage::generator::StorageFunctionModifier::Optional
}
} else {
quote!{
#scrate::storage::generator::StorageFunctionModifier::Optional
#scrate::storage::generator::StorageFunctionModifier::Default
}
};
let default = default_value.inner.get(0).as_ref().map(|d| &d.expr)
Expand Down Expand Up @@ -647,10 +641,10 @@ fn store_functions_to_metadata (
let def_get = quote! {
pub struct #struct_name<#traitinstance>(pub #scrate::rstd::marker::PhantomData<#traitinstance>);
#[cfg(feature = "std")]
static #cache_name: #scrate::once_cell::sync::OnceCell<Vec<u8>> = #scrate::once_cell::sync::OnceCell::INIT;
static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec<u8>> = #scrate::once_cell::sync::OnceCell::INIT;
#[cfg(feature = "std")]
impl<#traitinstance: #traittype> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance> {
fn default_byte(&self) -> Vec<u8> {
fn default_byte(&self) -> #scrate::rstd::vec::Vec<u8> {
use #scrate::codec::Encode;
#cache_name.get_or_init(|| {
let def_val: #gettype = #default;
Expand All @@ -660,7 +654,7 @@ fn store_functions_to_metadata (
}
#[cfg(not(feature = "std"))]
impl<#traitinstance: #traittype> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance> {
fn default_byte(&self) -> Vec<u8> {
fn default_byte(&self) -> #scrate::rstd::vec::Vec<u8> {
use #scrate::codec::Encode;
let def_val: #gettype = #default;
<#gettype as Encode>::encode(&def_val)
Expand All @@ -677,3 +671,29 @@ fn store_functions_to_metadata (
}
})
}


struct DeclStorageTypeInfos<'a> {
pub is_simple: bool,
pub full_type: &'a syn::Type,
pub is_option: bool,
pub typ: TokenStream2,
pub map_key: Option<&'a syn::Type>,
}

fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos {
let (is_simple, extracted_type, map_key, full_type) = match storage_type {
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
};
let is_option = extracted_type.is_some();
let typ = extracted_type.unwrap_or(quote!( #full_type ));
DeclStorageTypeInfos {
is_simple,
full_type,
is_option,
typ,
map_key,
}
}

26 changes: 26 additions & 0 deletions srml/support/src/storage/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,3 +946,29 @@ mod test2 {
type BlockNumber = u32;
}
}

#[cfg(test)]
#[allow(dead_code)]
mod test3 {
pub trait Trait {
type Origin;
type BlockNumber;
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
decl_storage! {
trait Store for Module<T: Trait> as Test {
Foo get(foo) config(initial_foo): u32;
}
}

type PairOf<T> = (T, T);

struct TraitImpl {}

impl Trait for TraitImpl {
type Origin = u32;
type BlockNumber = u32;
}
}

0 comments on commit 6cef98d

Please sign in to comment.