Skip to content
Snippets Groups Projects
Commit d271a464 authored by cheme's avatar cheme Committed by Bastian Köcher
Browse files

Decl_storage macro : force traits. (#1317)

* 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 84a29bc592023d1ee107519c58693ec19dbde2d2.

* Fix Vec usage (from rstd).
parent f5c4abd0
No related merge requests found
......@@ -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
......@@ -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 )
......@@ -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());
}
}});
}
......@@ -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)
}
......@@ -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)
}
......@@ -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 {
......@@ -576,14 +573,11 @@ 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(
......@@ -591,7 +585,7 @@ fn store_functions_to_metadata (
)
}
} 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!{
......@@ -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)
......@@ -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;
......@@ -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)
......@@ -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,
}
}
......@@ -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% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment