diff --git a/substrate/srml/example/src/lib.rs b/substrate/srml/example/src/lib.rs index 587c4af258..5f81e4336a 100644 --- a/substrate/srml/example/src/lib.rs +++ b/substrate/srml/example/src/lib.rs @@ -251,8 +251,13 @@ impl Module { fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> Result { let _sender = ensure_signed(origin)?; + let prev = >::get(); // Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an Option<> type. - >::mutate(|foo| *foo = *foo + increase_by); + let result = >::mutate(|foo| { + *foo = *foo + increase_by; + *foo + }); + assert!(prev + increase_by == result); Ok(()) } diff --git a/substrate/srml/support/src/storage/generator.rs b/substrate/srml/support/src/storage/generator.rs index f3e2f0e8c0..586ec5eb2b 100644 --- a/substrate/srml/support/src/storage/generator.rs +++ b/substrate/srml/support/src/storage/generator.rs @@ -119,7 +119,7 @@ pub trait StorageValue { } /// Mutate this value - fn mutate(f: F, storage: &S); + fn mutate R, S: Storage>(f: F, storage: &S) -> R; /// Clear the storage value. fn kill(storage: &S) { @@ -190,7 +190,7 @@ pub trait StorageMap { } /// Mutate the value under a key. - fn mutate(key: &K, f: F, storage: &S); + fn mutate R, S: Storage>(key: &K, f: F, storage: &S) -> R; } // TODO: Remove this in favour of `decl_storage` macro. @@ -342,10 +342,10 @@ macro_rules! __storage_items_internal { } /// Mutate this value. - fn mutate(f: F, storage: &S) { + fn mutate R, S: $crate::GenericStorage>(f: F, storage: &S) -> R { let mut val = >::get(storage); - f(&mut val); + let ret = f(&mut val); __handle_wrap_internal!($wraptype { // raw type case @@ -353,10 +353,12 @@ macro_rules! __storage_items_internal { } { // Option<> type case match val { - Some(val) => >::put(&val, storage), + Some(ref val) => >::put(&val, storage), None => >::kill(storage), } }); + + ret } } }; @@ -398,10 +400,10 @@ macro_rules! __storage_items_internal { } /// Mutate the value under a key. - fn mutate(key: &$kty, f: F, storage: &S) { + fn mutate R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R { let mut val = >::take(key, storage); - f(&mut val); + let ret = f(&mut val); __handle_wrap_internal!($wraptype { // raw type case @@ -409,10 +411,12 @@ macro_rules! __storage_items_internal { } { // Option<> type case match val { - Some(val) => >::insert(key, &val, storage), + Some(ref val) => >::insert(key, &val, storage), None => >::remove(key, storage), } }); + + ret } } }; @@ -1900,10 +1904,10 @@ macro_rules! __decl_storage_item { } /// Mutate the value under a key - fn mutate(key: &$kty, f: F, storage: &S) { + fn mutate R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R { let mut val = >::take(key, storage); - f(&mut val); + let ret = f(&mut val); __handle_wrap_internal!($wraptype { // raw type case @@ -1911,10 +1915,12 @@ macro_rules! __decl_storage_item { } { // Option<> type case match val { - Some(val) => >::insert(key, &val, storage), + Some(ref val) => >::insert(key, &val, storage), None => >::remove(key, storage), } }); + + ret } } }; @@ -1959,10 +1965,10 @@ macro_rules! __decl_storage_item { } /// Mutate the value under a key. - fn mutate(f: F, storage: &S) { + fn mutate R, S: $crate::GenericStorage>(f: F, storage: &S) -> R { let mut val = >::get(storage); - f(&mut val); + let ret = f(&mut val); __handle_wrap_internal!($wraptype { // raw type case @@ -1970,10 +1976,12 @@ macro_rules! __decl_storage_item { } { // Option<> type case match val { - Some(val) => >::put(&val, storage), + Some(ref val) => >::put(&val, storage), None => >::kill(storage), } }); + + ret } } }; diff --git a/substrate/srml/support/src/storage/mod.rs b/substrate/srml/support/src/storage/mod.rs index 637ecc688a..6e1302718a 100644 --- a/substrate/srml/support/src/storage/mod.rs +++ b/substrate/srml/support/src/storage/mod.rs @@ -169,7 +169,7 @@ pub trait StorageValue { fn put>(val: Arg); /// Mutate the value - fn mutate(f: F); + fn mutate R>(f: F) -> R; /// Clear the storage value. fn kill(); @@ -193,7 +193,7 @@ impl StorageValue for U where U: generator::StorageValue { fn put>(val: Arg) { U::put(val.borrow(), &RuntimeStorage) } - fn mutate(f: F) { + fn mutate R>(f: F) -> R { U::mutate(f, &RuntimeStorage) } fn kill() { @@ -296,7 +296,7 @@ pub trait StorageMap { fn remove>(key: KeyArg); /// Mutate the value under a key. - fn mutate, F: FnOnce(&mut Self::Query)>(key: KeyArg, f: F); + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; /// Take the value under a key. fn take>(key: KeyArg) -> Self::Query; @@ -329,7 +329,7 @@ impl StorageMap for U where U: generator::StorageMa U::remove(key.borrow(), &RuntimeStorage) } - fn mutate, F: FnOnce(&mut Self::Query)>(key: KeyArg, f: F) { + fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R { U::mutate(key.borrow(), f, &RuntimeStorage) }