gear_common/storage/primitives/value.rs
1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! Module for single-value storing primitive.
5//!
6//! This primitive defines interface of interaction
7//! with globally stored single-value.
8
9/// Represents logic of managing globally stored
10/// value for more complicated logic.
11///
12/// In fact, represents custom implementation/wrapper
13/// around of Substrate's `ValueStorage` with `OptionQuery`.
14pub trait ValueStorage {
15 /// Stored value type.
16 type Value;
17
18 /// Returns bool, defining does value present.
19 fn exists() -> bool;
20
21 /// Gets stored value, if present.
22 fn get() -> Option<Self::Value>;
23
24 /// Removes stored value.
25 fn kill();
26
27 /// Mutates stored value by `Option` reference, which stored
28 /// (or not in `None` case) with given function.
29 ///
30 /// May return generic type value.
31 fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(f: F) -> R;
32
33 /// Works the same as `Self::mutate`, but triggers if value present.
34 fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(f: F) -> Option<R> {
35 Self::mutate(|opt_val| opt_val.as_mut().map(f))
36 }
37
38 /// Stores given value.
39 fn put(value: Self::Value);
40
41 /// Stores given value and returns previous one, if present.
42 fn set(value: Self::Value) -> Option<Self::Value>;
43
44 /// Gets stored value, if present, and removes it from storage.
45 fn take() -> Option<Self::Value>;
46}
47
48/// Creates new type with specified name and value type and implements
49/// `ValueStorage` for it based on specified storage,
50/// which is a `Substrate`'s `StorageValue`.
51///
52/// This macro main purpose is to follow newtype pattern
53/// and avoid `Substrate` dependencies in `gear_common`.
54///
55/// Requires `PhantomData` be in scope: from `std`, `core` or `sp_std`.
56///
57/// Requires `Config` be in scope of the crate root where it called.
58#[allow(clippy::crate_in_macro_def)]
59#[macro_export]
60macro_rules! wrap_storage_value {
61 (storage: $storage: ident, name: $name: ident, value: $val: ty) => {
62 #[derive(Debug, PartialEq, Eq)]
63 pub struct $name<T>(PhantomData<T>);
64
65 impl<T: crate::Config> ValueStorage for $name<T> {
66 type Value = $val;
67
68 fn exists() -> bool {
69 $storage::<T>::exists()
70 }
71
72 fn get() -> Option<Self::Value> {
73 $storage::<T>::get()
74 }
75
76 fn kill() {
77 $storage::<T>::kill()
78 }
79
80 fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(f: F) -> R {
81 $storage::<T>::mutate(f)
82 }
83
84 fn put(value: Self::Value) {
85 $storage::<T>::put(value)
86 }
87
88 fn set(value: Self::Value) -> Option<Self::Value> {
89 $storage::<T>::mutate(|opt| {
90 let prev = opt.take();
91 *opt = Some(value);
92 prev
93 })
94 }
95
96 fn take() -> Option<Self::Value> {
97 $storage::<T>::take()
98 }
99 }
100 };
101}