gear_common/storage/complex/
mailbox.rs1use crate::storage::{
25 Callback, CountedByKey, DoubleMapStorage, GetCallback, Interval, IterableByKeyMap, IterableMap,
26 KeyFor,
27};
28use core::marker::PhantomData;
29
30pub type ValueWithInterval<T, B> = (T, Interval<B>);
31
32pub trait Mailbox {
34 type Key1;
36 type Key2;
38 type Value;
40 type BlockNumber;
44 type Error: MailboxError;
46 type OutputError: From<Self::Error>;
48
49 fn contains(key1: &Self::Key1, key2: &Self::Key2) -> bool;
51
52 fn insert(value: Self::Value, bn: Self::BlockNumber) -> Result<(), Self::OutputError>;
54
55 fn remove(
58 key1: Self::Key1,
59 key2: Self::Key2,
60 ) -> Result<ValueWithInterval<Self::Value, Self::BlockNumber>, Self::OutputError>;
61
62 fn peek(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value>;
65
66 fn clear();
68}
69
70pub trait MailboxCallbacks<OutputError> {
72 type Value;
77 type BlockNumber;
82
83 type GetBlockNumber: GetCallback<Self::BlockNumber>;
85 type OnInsert: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
87 type OnRemove: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
89}
90
91pub trait MailboxError {
95 fn duplicate_key() -> Self;
97
98 fn element_not_found() -> Self;
100}
101
102impl MailboxError for () {
103 fn duplicate_key() -> Self {}
104 fn element_not_found() -> Self {}
105}
106
107pub struct MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>(
114 PhantomData<(T, Error, OutputError, Callbacks, KeyGen)>,
115)
116where
117 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>,
118 Error: MailboxError,
119 OutputError: From<Error>,
120 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
121 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>;
122
123impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> Mailbox
125 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
126where
127 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>,
128 Error: MailboxError,
129 OutputError: From<Error>,
130 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
131 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
132{
133 type Key1 = T::Key1;
134 type Key2 = T::Key2;
135 type Value = Value;
136 type BlockNumber = BlockNumber;
137 type Error = Error;
138 type OutputError = OutputError;
139
140 fn contains(user_id: &Self::Key1, message_id: &Self::Key2) -> bool {
141 T::contains_keys(user_id, message_id)
142 }
143
144 fn insert(
145 message: Self::Value,
146 scheduled_at: Self::BlockNumber,
147 ) -> Result<(), Self::OutputError> {
148 let (key1, key2) = KeyGen::key_for(&message);
149
150 if Self::contains(&key1, &key2) {
151 return Err(Self::Error::duplicate_key().into());
152 }
153
154 let block_number = Callbacks::GetBlockNumber::call();
155 let message_with_bn = (
156 message,
157 Interval {
158 start: block_number,
159 finish: scheduled_at,
160 },
161 );
162
163 Callbacks::OnInsert::call(&message_with_bn);
164 T::insert(key1, key2, message_with_bn);
165 Ok(())
166 }
167
168 fn remove(
169 user_id: Self::Key1,
170 message_id: Self::Key2,
171 ) -> Result<ValueWithInterval<Self::Value, Self::BlockNumber>, Self::OutputError> {
172 if let Some(message_with_bn) = T::take(user_id, message_id) {
173 Callbacks::OnRemove::call(&message_with_bn);
174 Ok(message_with_bn)
175 } else {
176 Err(Self::Error::element_not_found().into())
177 }
178 }
179
180 fn peek(user_id: &Self::Key1, message_id: &Self::Key2) -> Option<Self::Value> {
181 T::get(user_id, message_id).map(|(stored, _)| stored)
182 }
183
184 fn clear() {
185 T::clear()
186 }
187}
188
189impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> CountedByKey
192 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
193where
194 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>
195 + CountedByKey<Key = T::Key1>,
196 Error: MailboxError,
197 OutputError: From<Error>,
198 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
199 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
200{
201 type Key = T::Key1;
202 type Length = T::Length;
203
204 fn len(key: &Self::Key) -> Self::Length {
205 T::len(key)
206 }
207}
208
209impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableByKeyMap<T::Value>
212 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
213where
214 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>
215 + IterableByKeyMap<T::Value, Key = T::Key1>,
216 Error: MailboxError,
217 OutputError: From<Error>,
218 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
219 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
220{
221 type Key = T::Key1;
222 type DrainIter = T::DrainIter;
223 type Iter = T::Iter;
224
225 fn drain_key(key: Self::Key) -> Self::DrainIter {
226 T::drain_key(key)
227 }
228
229 fn iter_key(key: Self::Key) -> Self::Iter {
230 T::iter_key(key)
231 }
232}
233
234impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableMap<T::Value>
237 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
238where
239 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>> + IterableMap<T::Value>,
240 Error: MailboxError,
241 OutputError: From<Error>,
242 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
243 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
244{
245 type DrainIter = T::DrainIter;
246 type Iter = T::Iter;
247
248 fn drain() -> Self::DrainIter {
249 T::drain()
250 }
251
252 fn iter() -> Self::Iter {
253 T::iter()
254 }
255}