Implement all storage after prefix (#4227)

* Implement all storage after prefix

* fix test, bump version and fix doc

* bump metadata version

* Update frame/support/procedural/src/storage/storage_struct.rs
This commit is contained in:
thiolliere
2019-11-27 19:23:20 +01:00
committed by Gavin Wood
parent dcaabbaacf
commit f4035cd5ac
15 changed files with 310 additions and 325 deletions
@@ -19,24 +19,12 @@
use proc_macro2::{TokenStream, Span};
use quote::quote;
use super::{DeclStorageDefExt, StorageLineTypeDef};
use super::DeclStorageDefExt;
const NUMBER_OF_INSTANCE: usize = 16;
const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable";
// prefix for consts in trait Instance
pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_";
pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_";
// Used to generate the const:
// `const $name: &'static str = $value_prefix ++ instance_prefix ++ $value_suffix`
struct InstanceConstDef {
name: syn::Ident,
value_prefix: String,
value_suffix: String,
}
// Used to generate an instance implementation.
struct InstanceDef {
prefix: String,
@@ -47,33 +35,7 @@ struct InstanceDef {
pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream {
let mut impls = TokenStream::new();
let mut const_defs = vec![];
for line in def.storage_lines.iter() {
let storage_prefix = format!("{} {}", def.crate_name, line.name);
let const_name = syn::Ident::new(
&format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
const_defs.push(InstanceConstDef {
name: const_name,
value_prefix: String::new(),
value_suffix: storage_prefix.clone(),
});
if let StorageLineTypeDef::LinkedMap(_) = line.storage_type {
let const_name = syn::Ident::new(
&format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
const_defs.push(InstanceConstDef {
name: const_name,
value_prefix: "head of ".into(),
value_suffix: storage_prefix,
});
}
}
impls.extend(create_instance_trait(&const_defs, def));
impls.extend(create_instance_trait(def));
// Implementation of instances.
if let Some(module_instance) = &def.module_instance {
@@ -95,7 +57,7 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
);
for instance_def in instance_defs {
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def));
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def));
}
}
@@ -116,27 +78,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
instance_struct: inherent_instance,
doc: quote!(#[doc(hidden)]),
};
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def));
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def));
}
impls
}
fn create_instance_trait(
const_defs: &[InstanceConstDef],
def: &DeclStorageDefExt,
) -> TokenStream {
let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone())
.unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()));
let mut const_impls = TokenStream::new();
for const_def in const_defs {
let const_name = &const_def.name;
const_impls.extend(quote! {
const #const_name: &'static str;
});
}
let optional_hide = if def.module_instance.is_some() {
quote!()
} else {
@@ -151,7 +104,6 @@ fn create_instance_trait(
pub trait #instance_trait: 'static {
/// The prefix used by any storage entry of an instance.
const PREFIX: &'static str;
#const_impls
}
}
}
@@ -159,22 +111,8 @@ fn create_instance_trait(
fn create_and_impl_instance_struct(
scrate: &TokenStream,
instance_def: &InstanceDef,
const_defs: &[InstanceConstDef],
def: &DeclStorageDefExt,
) -> TokenStream {
let mut const_impls = TokenStream::new();
for const_def in const_defs {
let const_value = format!(
"{}{}{}", const_def.value_prefix, instance_def.prefix, const_def.value_suffix
);
let const_name = &const_def.name;
const_impls.extend(quote! {
const #const_name: &'static str = #const_value;
});
}
let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone())
.unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()));
@@ -194,7 +132,6 @@ fn create_and_impl_instance_struct(
pub struct #instance_struct;
impl #instance_trait for #instance_struct {
const PREFIX: &'static str = #prefix;
#const_impls
}
}
}
@@ -16,11 +16,11 @@
//! Implementation of storage structures and implementation of storage traits on them.
use proc_macro2::TokenStream;
use proc_macro2::{TokenStream, Ident, Span};
use quote::quote;
use super::{
DeclStorageDefExt, StorageLineTypeDef,
instance_trait::{PREFIX_FOR, HEAD_KEY_FOR},
instance_trait::INHERENT_INSTANCE_NAME,
};
fn from_optional_value_to_query(is_option: bool, default: &Option<syn::Expr>) -> TokenStream {
@@ -78,17 +78,14 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
let from_optional_value_to_query =
from_optional_value_to_query(line.is_option, &line.default_value);
let final_prefix = if let Some(instance) = def.module_instance.as_ref() {
let instance = &instance.instance_generic;
let const_name = syn::Ident::new(
&format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
quote!( #instance::#const_name.as_bytes() )
// Contains accessor to instance, used to get prefixes
let instance_or_inherent = if let Some(instance) = def.module_instance.as_ref() {
instance.instance_generic.clone()
} else {
let prefix = format!("{} {}", def.crate_name, line.name);
quote!( #prefix.as_bytes() )
Ident::new(INHERENT_INSTANCE_NAME, Span::call_site())
};
let storage_name_str = syn::LitStr::new(&line.name.to_string(), line.name.span());
let storage_generator_trait = &line.storage_generator_trait;
let storage_struct = &line.storage_struct;
@@ -104,8 +101,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
{
type Query = #query_type;
fn unhashed_key() -> &'static [u8] {
#final_prefix
fn module_prefix() -> &'static [u8] {
#instance_or_inherent::PREFIX.as_bytes()
}
fn storage_prefix() -> &'static [u8] {
#storage_name_str.as_bytes()
}
fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
@@ -127,8 +128,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
type Query = #query_type;
type Hasher = #scrate::#hasher;
fn prefix() -> &'static [u8] {
#final_prefix
fn module_prefix() -> &'static [u8] {
#instance_or_inherent::PREFIX.as_bytes()
}
fn storage_prefix() -> &'static [u8] {
#storage_name_str.as_bytes()
}
fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
@@ -144,30 +149,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
StorageLineTypeDef::LinkedMap(map) => {
let hasher = map.hasher.to_storage_hasher_struct();
// make sure to use different prefix for head and elements.
let head_key = if let Some(instance) = def.module_instance.as_ref() {
let instance = &instance.instance_generic;
let const_name = syn::Ident::new(
&format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
quote!( #instance::#const_name.as_bytes() )
} else {
let prefix = format!("head of {} {}", def.crate_name, line.name);
quote!( #prefix.as_bytes() )
};
let head_prefix_str = syn::LitStr::new(
&format!("HeadOf{}", line.name.to_string()),
line.name.span(),
);
quote!(
impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct
#optional_storage_where_clause
{
type Query = #query_type;
type Hasher = #scrate::#hasher;
type KeyFormat = Self;
fn prefix() -> &'static [u8] {
#final_prefix
}
fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
#from_optional_value_to_query
}
@@ -180,8 +173,16 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
impl<#impl_trait> #scrate::storage::generator::LinkedMapKeyFormat for #storage_struct {
type Hasher = #scrate::#hasher;
fn head_key() -> &'static [u8] {
#head_key
fn module_prefix() -> &'static [u8] {
#instance_or_inherent::PREFIX.as_bytes()
}
fn storage_prefix() -> &'static [u8] {
#storage_name_str.as_bytes()
}
fn head_prefix() -> &'static [u8] {
#head_prefix_str.as_bytes()
}
}
)
@@ -199,8 +200,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
type Hasher2 = #scrate::#hasher2;
fn key1_prefix() -> &'static [u8] {
#final_prefix
fn module_prefix() -> &'static [u8] {
#instance_or_inherent::PREFIX.as_bytes()
}
fn storage_prefix() -> &'static [u8] {
#storage_name_str.as_bytes()
}
fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {