frame_support/storage/generator/
value.rs1use crate::{
19 storage::{self, unhashed, StorageAppend},
20 Never,
21};
22use codec::{Decode, Encode, EncodeLike, FullCodec};
23
24pub trait StorageValue<T: FullCodec> {
31 type Query;
33
34 fn pallet_prefix() -> &'static [u8];
36
37 fn storage_prefix() -> &'static [u8];
39
40 fn from_optional_value_to_query(v: Option<T>) -> Self::Query;
42
43 fn from_query_to_optional_value(v: Self::Query) -> Option<T>;
45
46 fn storage_value_final_key() -> [u8; 32];
48}
49
50impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
51 type Query = G::Query;
52
53 fn hashed_key() -> [u8; 32] {
54 Self::storage_value_final_key()
55 }
56
57 fn exists() -> bool {
58 unhashed::exists(&Self::storage_value_final_key())
59 }
60
61 fn get() -> Self::Query {
62 let value = unhashed::get(&Self::storage_value_final_key());
63 G::from_optional_value_to_query(value)
64 }
65
66 fn try_get() -> Result<T, ()> {
67 unhashed::get(&Self::storage_value_final_key()).ok_or(())
68 }
69
70 fn translate<O: Decode, F: FnOnce(Option<O>) -> Option<T>>(f: F) -> Result<Option<T>, ()> {
71 let key = Self::storage_value_final_key();
72
73 let maybe_old = unhashed::get_raw(&key)
75 .map(|old_data| O::decode(&mut &old_data[..]).map_err(|_| ()))
76 .transpose()?;
77 let maybe_new = f(maybe_old);
78 if let Some(new) = maybe_new.as_ref() {
79 new.using_encoded(|d| unhashed::put_raw(&key, d));
80 } else {
81 unhashed::kill(&key);
82 }
83 Ok(maybe_new)
84 }
85
86 fn put<Arg: EncodeLike<T>>(val: Arg) {
87 unhashed::put(&Self::storage_value_final_key(), &val)
88 }
89
90 fn set(maybe_val: Self::Query) {
91 if let Some(val) = G::from_query_to_optional_value(maybe_val) {
92 unhashed::put(&Self::storage_value_final_key(), &val)
93 } else {
94 unhashed::kill(&Self::storage_value_final_key())
95 }
96 }
97
98 fn mutate<R, F: FnOnce(&mut G::Query) -> R>(f: F) -> R {
99 Self::try_mutate(|v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
100 }
101
102 fn try_mutate<R, E, F: FnOnce(&mut G::Query) -> Result<R, E>>(f: F) -> Result<R, E> {
103 let mut val = G::get();
104
105 let ret = f(&mut val);
106 if ret.is_ok() {
107 match G::from_query_to_optional_value(val) {
108 Some(ref val) => G::put(val),
109 None => G::kill(),
110 }
111 }
112 ret
113 }
114
115 fn mutate_exists<R, F>(f: F) -> R
116 where
117 F: FnOnce(&mut Option<T>) -> R,
118 {
119 Self::try_mutate_exists(|v| Ok::<R, Never>(f(v)))
120 .expect("`Never` can not be constructed; qed")
121 }
122
123 fn try_mutate_exists<R, E, F>(f: F) -> Result<R, E>
124 where
125 F: FnOnce(&mut Option<T>) -> Result<R, E>,
126 {
127 let mut val = G::from_query_to_optional_value(Self::get());
128
129 let ret = f(&mut val);
130 if ret.is_ok() {
131 match val {
132 Some(ref val) => Self::put(val),
133 None => Self::kill(),
134 }
135 }
136 ret
137 }
138
139 fn kill() {
140 unhashed::kill(&Self::storage_value_final_key())
141 }
142
143 fn take() -> G::Query {
144 let key = Self::storage_value_final_key();
145 let value = unhashed::get(&key);
146 if value.is_some() {
147 unhashed::kill(&key)
148 }
149 G::from_optional_value_to_query(value)
150 }
151
152 fn append<Item, EncodeLikeItem>(item: EncodeLikeItem)
153 where
154 Item: Encode,
155 EncodeLikeItem: EncodeLike<Item>,
156 T: StorageAppend<Item>,
157 {
158 let key = Self::storage_value_final_key();
159 sp_io::storage::append(&key, item.encode());
160 }
161}