gear_common/storage/complex/
mailbox.rs1use crate::storage::{
10 Callback, CountedByKey, DoubleMapStorage, GetCallback, Interval, IterableByKeyMap, IterableMap,
11 KeyFor,
12};
13use core::marker::PhantomData;
14
15pub type ValueWithInterval<T, B> = (T, Interval<B>);
16
17pub trait Mailbox {
19 type Key1;
21 type Key2;
23 type Value;
25 type BlockNumber;
29 type Error: MailboxError;
31 type OutputError: From<Self::Error>;
33
34 fn contains(key1: &Self::Key1, key2: &Self::Key2) -> bool;
36
37 fn insert(value: Self::Value, bn: Self::BlockNumber) -> Result<(), Self::OutputError>;
39
40 fn remove(
43 key1: Self::Key1,
44 key2: Self::Key2,
45 ) -> Result<ValueWithInterval<Self::Value, Self::BlockNumber>, Self::OutputError>;
46
47 fn peek(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value>;
50
51 fn clear();
53}
54
55pub trait MailboxCallbacks<OutputError> {
57 type Value;
62 type BlockNumber;
67
68 type GetBlockNumber: GetCallback<Self::BlockNumber>;
70 type OnInsert: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
72 type OnRemove: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
74}
75
76pub trait MailboxError {
80 fn duplicate_key() -> Self;
82
83 fn element_not_found() -> Self;
85}
86
87impl MailboxError for () {
88 fn duplicate_key() -> Self {}
89 fn element_not_found() -> Self {}
90}
91
92pub struct MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>(
99 PhantomData<(T, Error, OutputError, Callbacks, KeyGen)>,
100)
101where
102 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>,
103 Error: MailboxError,
104 OutputError: From<Error>,
105 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
106 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>;
107
108impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> Mailbox
110 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
111where
112 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>,
113 Error: MailboxError,
114 OutputError: From<Error>,
115 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
116 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
117{
118 type Key1 = T::Key1;
119 type Key2 = T::Key2;
120 type Value = Value;
121 type BlockNumber = BlockNumber;
122 type Error = Error;
123 type OutputError = OutputError;
124
125 fn contains(user_id: &Self::Key1, message_id: &Self::Key2) -> bool {
126 T::contains_keys(user_id, message_id)
127 }
128
129 fn insert(
130 message: Self::Value,
131 scheduled_at: Self::BlockNumber,
132 ) -> Result<(), Self::OutputError> {
133 let (key1, key2) = KeyGen::key_for(&message);
134
135 if Self::contains(&key1, &key2) {
136 return Err(Self::Error::duplicate_key().into());
137 }
138
139 let block_number = Callbacks::GetBlockNumber::call();
140 let message_with_bn = (
141 message,
142 Interval {
143 start: block_number,
144 finish: scheduled_at,
145 },
146 );
147
148 Callbacks::OnInsert::call(&message_with_bn);
149 T::insert(key1, key2, message_with_bn);
150 Ok(())
151 }
152
153 fn remove(
154 user_id: Self::Key1,
155 message_id: Self::Key2,
156 ) -> Result<ValueWithInterval<Self::Value, Self::BlockNumber>, Self::OutputError> {
157 if let Some(message_with_bn) = T::take(user_id, message_id) {
158 Callbacks::OnRemove::call(&message_with_bn);
159 Ok(message_with_bn)
160 } else {
161 Err(Self::Error::element_not_found().into())
162 }
163 }
164
165 fn peek(user_id: &Self::Key1, message_id: &Self::Key2) -> Option<Self::Value> {
166 T::get(user_id, message_id).map(|(stored, _)| stored)
167 }
168
169 fn clear() {
170 T::clear()
171 }
172}
173
174impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> CountedByKey
177 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
178where
179 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>
180 + CountedByKey<Key = T::Key1>,
181 Error: MailboxError,
182 OutputError: From<Error>,
183 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
184 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
185{
186 type Key = T::Key1;
187 type Length = T::Length;
188
189 fn len(key: &Self::Key) -> Self::Length {
190 T::len(key)
191 }
192}
193
194impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableByKeyMap<T::Value>
197 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
198where
199 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>>
200 + IterableByKeyMap<T::Value, Key = T::Key1>,
201 Error: MailboxError,
202 OutputError: From<Error>,
203 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
204 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
205{
206 type Key = T::Key1;
207 type DrainIter = T::DrainIter;
208 type Iter = T::Iter;
209
210 fn drain_key(key: Self::Key) -> Self::DrainIter {
211 T::drain_key(key)
212 }
213
214 fn iter_key(key: Self::Key) -> Self::Iter {
215 T::iter_key(key)
216 }
217}
218
219impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableMap<T::Value>
222 for MailboxImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
223where
224 T: DoubleMapStorage<Value = ValueWithInterval<Value, BlockNumber>> + IterableMap<T::Value>,
225 Error: MailboxError,
226 OutputError: From<Error>,
227 Callbacks: MailboxCallbacks<OutputError, Value = Value, BlockNumber = BlockNumber>,
228 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
229{
230 type DrainIter = T::DrainIter;
231 type Iter = T::Iter;
232
233 fn drain() -> Self::DrainIter {
234 T::drain()
235 }
236
237 fn iter() -> Self::Iter {
238 T::iter()
239 }
240}