Refactored Slicable (#324)

* Refactored Slicable

* Docs

* Wasm build

* Wasm build

* Renamed traits

* Review nits

* Renamed Slicable as well
This commit is contained in:
Arkadiy Paronyan
2018-07-15 22:51:21 +02:00
committed by Gav Wood
parent b45020175a
commit 1aeb2825af
84 changed files with 901 additions and 818 deletions
@@ -22,7 +22,7 @@ pub use std::fmt;
pub use rstd::result;
#[cfg(feature = "std")]
use serde;
pub use codec::{Slicable, Input};
pub use codec::{Codec, Decode, Encode, Input, Output};
pub type Result = result::Result<(), &'static str>;
@@ -39,11 +39,11 @@ pub trait AuxDispatchable {
#[cfg(feature = "std")]
pub trait AuxCallable {
type Call: AuxDispatchable + Slicable + ::serde::Serialize + Clone + PartialEq + Eq;
type Call: AuxDispatchable + Codec + ::serde::Serialize + Clone + PartialEq + Eq;
}
#[cfg(not(feature = "std"))]
pub trait AuxCallable {
type Call: AuxDispatchable + Slicable + Clone + PartialEq + Eq;
type Call: AuxDispatchable + Codec + Clone + PartialEq + Eq;
}
// dirty hack to work around serde_derive issue
@@ -52,11 +52,11 @@ pub type AuxCallableCallFor<A> = <A as AuxCallable>::Call;
#[cfg(feature = "std")]
pub trait Callable {
type Call: Dispatchable + Slicable + ::serde::Serialize + Clone + PartialEq + Eq;
type Call: Dispatchable + Codec + ::serde::Serialize + Clone + PartialEq + Eq;
}
#[cfg(not(feature = "std"))]
pub trait Callable {
type Call: Dispatchable + Slicable + Clone + PartialEq + Eq;
type Call: Dispatchable + Codec + Clone + PartialEq + Eq;
}
// dirty hack to work around serde_derive issue.
@@ -64,16 +64,16 @@ pub trait Callable {
pub type CallableCallFor<C> = <C as Callable>::Call;
#[cfg(feature = "std")]
pub trait Parameter: Slicable + serde::Serialize + Clone + Eq + fmt::Debug {}
pub trait Parameter: Codec + serde::Serialize + Clone + Eq + fmt::Debug {}
#[cfg(feature = "std")]
impl<T> Parameter for T where T: Slicable + serde::Serialize + Clone + Eq + fmt::Debug {}
impl<T> Parameter for T where T: Codec + serde::Serialize + Clone + Eq + fmt::Debug {}
#[cfg(not(feature = "std"))]
pub trait Parameter: Slicable + Clone + Eq {}
pub trait Parameter: Codec + Clone + Eq {}
#[cfg(not(feature = "std"))]
impl<T> Parameter for T where T: Slicable + Clone + Eq {}
impl<T> Parameter for T where T: Codec + Clone + Eq {}
/// Declare a struct for this module, then implement dispatch logic to create a pairing of several
/// dispatch traits and enums.
@@ -395,13 +395,13 @@ macro_rules! __decl_dispatch_module_common {
}
}
impl<$trait_instance: $trait_name> $crate::dispatch::Slicable for $call_type<$trait_instance> {
impl<$trait_instance: $trait_name> $crate::dispatch::Decode for $call_type<$trait_instance> {
fn decode<I: $crate::dispatch::Input>(input: &mut I) -> Option<Self> {
match input.read_byte()? {
$(
$id => {
$(
let $param_name = $crate::dispatch::Slicable::decode(input)?;
let $param_name = $crate::dispatch::Decode::decode(input)?;
)*
Some($call_type:: $fn_name( $( $param_name ),* ))
}
@@ -409,9 +409,10 @@ macro_rules! __decl_dispatch_module_common {
_ => None,
}
}
}
fn encode(&self) -> $crate::dispatch::Vec<u8> {
let mut v = $crate::dispatch::Vec::new();
impl<$trait_instance: $trait_name> $crate::dispatch::Encode for $call_type<$trait_instance> {
fn encode_to<W: $crate::dispatch::Output>(&self, dest: &mut W) {
match *self {
$(
$call_type::$fn_name(
@@ -419,19 +420,14 @@ macro_rules! __decl_dispatch_module_common {
ref $param_name
),*
) => {
v.push($id as u8);
dest.push_byte($id as u8);
$(
$param_name.using_encoded(|s| v.extend(s));
$param_name.encode_to(dest);
)*
}
)*
$call_type::__PhantomItem(_) => unreachable!(),
}
v
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.encode().as_slice())
}
}
@@ -536,32 +532,28 @@ macro_rules! impl_outer_dispatch_common {
(
$call_type:ident, $( $camelcase:ident = $id:expr, )*
) => {
impl $crate::dispatch::Slicable for $call_type {
impl $crate::dispatch::Decode for $call_type {
fn decode<I: $crate::dispatch::Input>(input: &mut I) -> Option<Self> {
match input.read_byte()? {
$(
$id =>
Some($call_type::$camelcase( $crate::dispatch::Slicable::decode(input)? )),
Some($call_type::$camelcase( $crate::dispatch::Decode::decode(input)? )),
)*
_ => None,
}
}
}
fn encode(&self) -> $crate::dispatch::Vec<u8> {
let mut v = $crate::dispatch::Vec::new();
impl $crate::dispatch::Encode for $call_type {
fn encode_to<W: $crate::dispatch::Output>(&self, dest: &mut W) {
match *self {
$(
$call_type::$camelcase( ref sub ) => {
v.push($id as u8);
sub.using_encoded(|s| v.extend(s));
dest.push_byte($id as u8);
sub.encode_to(dest);
}
)*
}
v
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.encode().as_slice())
}
}
@@ -16,7 +16,7 @@
//! Hashable trait.
use codec::Slicable;
use codec::Codec;
use runtime_io::{blake2_256, twox_128, twox_256};
pub trait Hashable: Sized {
@@ -25,7 +25,7 @@ pub trait Hashable: Sized {
fn twox_256(&self) -> [u8; 32];
}
impl<T: Slicable> Hashable for T {
impl<T: Codec> Hashable for T {
fn blake2_256(&self) -> [u8; 32] {
blake2_256(&self.encode())
}
@@ -59,38 +59,38 @@ pub trait Storage {
fn exists(&self, key: &[u8]) -> bool;
/// Load the bytes of a key from storage. Can panic if the type is incorrect.
fn get<T: codec::Slicable>(&self, key: &[u8]) -> Option<T>;
fn get<T: codec::Codec>(&self, key: &[u8]) -> Option<T>;
/// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if
/// it's not there.
fn require<T: codec::Slicable>(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") }
fn require<T: codec::Codec>(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") }
/// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's
/// default is returned if it's not there.
fn get_or_default<T: codec::Slicable + Default>(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() }
fn get_or_default<T: codec::Codec + Default>(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() }
/// Put a value in under a key.
fn put<T: codec::Slicable>(&self, key: &[u8], val: &T);
fn put<T: codec::Codec>(&self, key: &[u8], val: &T);
/// Remove the bytes of a key from storage.
fn kill(&self, key: &[u8]);
/// Take a value from storage, deleting it after reading.
fn take<T: codec::Slicable>(&self, key: &[u8]) -> Option<T> {
fn take<T: codec::Codec>(&self, key: &[u8]) -> Option<T> {
let value = self.get(key);
self.kill(key);
value
}
/// Take a value from storage, deleting it after reading.
fn take_or_panic<T: codec::Slicable>(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") }
fn take_or_panic<T: codec::Codec>(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") }
/// Take a value from storage, deleting it after reading.
fn take_or_default<T: codec::Slicable + Default>(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() }
fn take_or_default<T: codec::Codec + Default>(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() }
}
/// A strongly-typed value kept in storage.
pub trait StorageValue<T: codec::Slicable> {
pub trait StorageValue<T: codec::Codec> {
/// The type that get/take returns.
type Query;
@@ -120,7 +120,7 @@ pub trait StorageValue<T: codec::Slicable> {
}
/// A strongly-typed list in storage.
pub trait StorageList<T: codec::Slicable> {
pub trait StorageList<T: codec::Codec> {
/// Get the prefix key in storage.
fn prefix() -> &'static [u8];
@@ -150,7 +150,7 @@ pub trait StorageList<T: codec::Slicable> {
}
/// A strongly-typed map in storage.
pub trait StorageMap<K: codec::Slicable, V: codec::Slicable> {
pub trait StorageMap<K: codec::Codec, V: codec::Codec> {
/// The type that get/take returns.
type Query;
@@ -233,7 +233,7 @@ macro_rules! __storage_items_internal {
/// Get the storage key used to fetch a value corresponding to a specific key.
fn key_for(x: &$kty) -> Vec<u8> {
let mut key = $prefix.to_vec();
key.extend($crate::codec::Slicable::encode(x));
$crate::codec::Encode::encode_to(x, &mut key);
key
}
@@ -284,7 +284,7 @@ macro_rules! __storage_items_internal {
/// Get the storage key used to fetch a value at a given index.
fn key_for(index: u32) -> Vec<u8> {
let mut key = $prefix.to_vec();
key.extend($crate::codec::Slicable::encode(&index));
$crate::codec::Encode::encode_to(&index, &mut key);
key
}
@@ -496,7 +496,7 @@ macro_rules! __decl_storage_item {
/// Get the storage key used to fetch a value corresponding to a specific key.
fn key_for(x: &$kty) -> Vec<u8> {
let mut key = $prefix.to_vec();
key.extend($crate::codec::Slicable::encode(x));
$crate::codec::Encode::encode_to(x, &mut key);
key
}
@@ -991,7 +991,7 @@ macro_rules! __decl_storage_items {
mod tests {
use std::collections::HashMap;
use std::cell::RefCell;
use codec::Slicable;
use codec::Codec;
use super::*;
impl Storage for RefCell<HashMap<Vec<u8>, Vec<u8>>> {
@@ -999,11 +999,11 @@ mod tests {
self.borrow_mut().get(key).is_some()
}
fn get<T: Slicable>(&self, key: &[u8]) -> Option<T> {
fn get<T: Codec>(&self, key: &[u8]) -> Option<T> {
self.borrow_mut().get(key).map(|v| T::decode(&mut &v[..]).unwrap())
}
fn put<T: Slicable>(&self, key: &[u8], val: &T) {
fn put<T: Codec>(&self, key: &[u8], val: &T) {
self.borrow_mut().insert(key.to_owned(), val.encode());
}
@@ -19,7 +19,7 @@
use rstd::prelude::*;
use rstd::borrow::Borrow;
use runtime_io::{self, twox_128};
use codec::{Slicable, KeyedVec, Input};
use codec::{Codec, Decode, KeyedVec, Input};
pub mod generator;
@@ -40,42 +40,42 @@ impl<'a> Input for IncrementalInput<'a> {
}
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
pub fn get<T: Codec + Sized>(key: &[u8]) -> Option<T> {
let key = twox_128(key);
runtime_io::read_storage(&key[..], &mut [0; 0][..], 0).map(|_| {
let mut input = IncrementalInput {
key: &key[..],
pos: 0,
};
Slicable::decode(&mut input).expect("storage is not null, therefore must be a valid type")
Decode::decode(&mut input).expect("storage is not null, therefore must be a valid type")
})
}
/// Return the value of the item in storage under `key`, or the type's default if there is no
/// explicit entry.
pub fn get_or_default<T: Slicable + Sized + Default>(key: &[u8]) -> T {
pub fn get_or_default<T: Codec + Sized + Default>(key: &[u8]) -> T {
get(key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry.
pub fn get_or<T: Slicable + Sized>(key: &[u8], default_value: T) -> T {
pub fn get_or<T: Codec + Sized>(key: &[u8], default_value: T) -> T {
get(key).unwrap_or(default_value)
}
/// Return the value of the item in storage under `key`, or `default_value()` if there is no
/// explicit entry.
pub fn get_or_else<T: Slicable + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
pub fn get_or_else<T: Codec + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
get(key).unwrap_or_else(default_value)
}
/// Put `value` in storage under `key`.
pub fn put<T: Slicable>(key: &[u8], value: &T) {
pub fn put<T: Codec>(key: &[u8], value: &T) {
value.using_encoded(|slice| runtime_io::set_storage(&twox_128(key)[..], slice));
}
/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
pub fn take<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
pub fn take<T: Codec + Sized>(key: &[u8]) -> Option<T> {
let r = get(key);
if r.is_some() {
kill(key);
@@ -85,19 +85,19 @@ pub fn take<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
/// the default for its type.
pub fn take_or_default<T: Slicable + Sized + Default>(key: &[u8]) -> T {
pub fn take_or_default<T: Codec + Sized + Default>(key: &[u8]) -> T {
take(key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry. Ensure there is no explicit entry on return.
pub fn take_or<T: Slicable + Sized>(key: &[u8], default_value: T) -> T {
pub fn take_or<T: Codec + Sized>(key: &[u8], default_value: T) -> T {
take(key).unwrap_or(default_value)
}
/// Return the value of the item in storage under `key`, or `default_value()` if there is no
/// explicit entry. Ensure there is no explicit entry on return.
pub fn take_or_else<T: Slicable + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
pub fn take_or_else<T: Codec + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
take(key).unwrap_or_else(default_value)
}
@@ -131,12 +131,12 @@ impl ::GenericStorage for RuntimeStorage {
}
/// Load the bytes of a key from storage. Can panic if the type is incorrect.
fn get<T: Slicable>(&self, key: &[u8]) -> Option<T> {
fn get<T: Codec>(&self, key: &[u8]) -> Option<T> {
super::storage::get(key)
}
/// Put a value in under a key.
fn put<T: Slicable>(&self, key: &[u8], val: &T) {
fn put<T: Codec>(&self, key: &[u8], val: &T) {
super::storage::put(key, val)
}
@@ -146,13 +146,13 @@ impl ::GenericStorage for RuntimeStorage {
}
/// Take a value from storage, deleting it after reading.
fn take<T: Slicable>(&self, key: &[u8]) -> Option<T> {
fn take<T: Codec>(&self, key: &[u8]) -> Option<T> {
super::storage::take(key)
}
}
/// A trait for working with macro-generated storage values under the substrate storage API.
pub trait StorageValue<T: Slicable> {
pub trait StorageValue<T: Codec> {
/// The type that get/take return.
type Query;
@@ -175,7 +175,7 @@ pub trait StorageValue<T: Slicable> {
fn take() -> Self::Query;
}
impl<T: Slicable, U> StorageValue<T> for U where U: generator::StorageValue<T> {
impl<T: Codec, U> StorageValue<T> for U where U: generator::StorageValue<T> {
type Query = U::Query;
fn key() -> &'static [u8] {
@@ -199,7 +199,7 @@ impl<T: Slicable, U> StorageValue<T> for U where U: generator::StorageValue<T> {
}
/// A strongly-typed list in storage.
pub trait StorageList<T: Slicable> {
pub trait StorageList<T: Codec> {
/// Get the prefix key in storage.
fn prefix() -> &'static [u8];
@@ -228,7 +228,7 @@ pub trait StorageList<T: Slicable> {
fn clear();
}
impl<T: Slicable, U> StorageList<T> for U where U: generator::StorageList<T> {
impl<T: Codec, U> StorageList<T> for U where U: generator::StorageList<T> {
fn prefix() -> &'static [u8] {
<U as generator::StorageList<T>>::prefix()
}
@@ -267,7 +267,7 @@ impl<T: Slicable, U> StorageList<T> for U where U: generator::StorageList<T> {
}
/// A strongly-typed map in storage.
pub trait StorageMap<K: Slicable, V: Slicable> {
pub trait StorageMap<K: Codec, V: Codec> {
/// The type that get/take return.
type Query;
@@ -293,7 +293,7 @@ pub trait StorageMap<K: Slicable, V: Slicable> {
fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
}
impl<K: Slicable, V: Slicable, U> StorageMap<K, V> for U where U: generator::StorageMap<K, V> {
impl<K: Codec, V: Codec, U> StorageMap<K, V> for U where U: generator::StorageMap<K, V> {
type Query = U::Query;
fn prefix() -> &'static [u8] {
@@ -327,7 +327,7 @@ impl<K: Slicable, V: Slicable, U> StorageMap<K, V> for U where U: generator::Sto
/// A trait to conveniently store a vector of storable data.
pub trait StorageVec {
type Item: Default + Sized + Slicable;
type Item: Default + Sized + Codec;
const PREFIX: &'static [u8];
/// Get the current set of items.
@@ -386,44 +386,44 @@ pub trait StorageVec {
pub mod unhashed {
use rstd::borrow::Borrow;
use super::{runtime_io, Slicable, KeyedVec, Vec, IncrementalInput};
use super::{runtime_io, Codec, Decode, KeyedVec, Vec, IncrementalInput};
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
pub fn get<T: Codec + Sized>(key: &[u8]) -> Option<T> {
runtime_io::read_storage(key, &mut [0; 0][..], 0).map(|_| {
let mut input = IncrementalInput {
key,
pos: 0,
};
Slicable::decode(&mut input).expect("stroage is not null, therefore must be a valid type")
Decode::decode(&mut input).expect("storage is not null, therefore must be a valid type")
})
}
/// Return the value of the item in storage under `key`, or the type's default if there is no
/// explicit entry.
pub fn get_or_default<T: Slicable + Sized + Default>(key: &[u8]) -> T {
pub fn get_or_default<T: Codec + Sized + Default>(key: &[u8]) -> T {
get(key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry.
pub fn get_or<T: Slicable + Sized>(key: &[u8], default_value: T) -> T {
pub fn get_or<T: Codec + Sized>(key: &[u8], default_value: T) -> T {
get(key).unwrap_or(default_value)
}
/// Return the value of the item in storage under `key`, or `default_value()` if there is no
/// explicit entry.
pub fn get_or_else<T: Slicable + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
pub fn get_or_else<T: Codec + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
get(key).unwrap_or_else(default_value)
}
/// Put `value` in storage under `key`.
pub fn put<T: Slicable>(key: &[u8], value: &T) {
pub fn put<T: Codec>(key: &[u8], value: &T) {
value.using_encoded(|slice| runtime_io::set_storage(key, slice));
}
/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
pub fn take<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
pub fn take<T: Codec + Sized>(key: &[u8]) -> Option<T> {
let r = get(key);
if r.is_some() {
kill(key);
@@ -433,19 +433,19 @@ pub mod unhashed {
/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
/// the default for its type.
pub fn take_or_default<T: Slicable + Sized + Default>(key: &[u8]) -> T {
pub fn take_or_default<T: Codec + Sized + Default>(key: &[u8]) -> T {
take(key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry. Ensure there is no explicit entry on return.
pub fn take_or<T: Slicable + Sized>(key: &[u8], default_value: T) -> T {
pub fn take_or<T: Codec + Sized>(key: &[u8], default_value: T) -> T {
take(key).unwrap_or(default_value)
}
/// Return the value of the item in storage under `key`, or `default_value()` if there is no
/// explicit entry. Ensure there is no explicit entry on return.
pub fn take_or_else<T: Slicable + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
pub fn take_or_else<T: Codec + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
take(key).unwrap_or_else(default_value)
}
@@ -476,7 +476,7 @@ pub mod unhashed {
/// A trait to conveniently store a vector of storable data.
pub trait StorageVec {
type Item: Default + Sized + Slicable;
type Item: Default + Sized + Codec;
const PREFIX: &'static [u8];
/// Get the current set of items.