gear_common/storage/complex/
waitlist.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 Waitlist {
19 type Key1;
21 type Key2;
23 type Value;
25 type BlockNumber;
29 type Error: WaitlistError;
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 clear();
49}
50
51pub trait WaitlistCallbacks {
53 type Value;
58 type BlockNumber;
63
64 type GetBlockNumber: GetCallback<Self::BlockNumber>;
66 type OnInsert: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
68 type OnRemove: Callback<ValueWithInterval<Self::Value, Self::BlockNumber>>;
70}
71
72pub trait WaitlistError {
76 fn duplicate_key() -> Self;
78
79 fn element_not_found() -> Self;
81}
82
83pub struct WaitlistImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>(
90 PhantomData<(T, Error, OutputError, Callbacks, KeyGen)>,
91)
92where
93 T: DoubleMapStorage<Value = (Value, Interval<BlockNumber>)>,
94 Error: WaitlistError,
95 OutputError: From<Error>,
96 Callbacks: WaitlistCallbacks<Value = Value, BlockNumber = BlockNumber>,
97 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>;
98
99impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> Waitlist
101 for WaitlistImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
102where
103 T: DoubleMapStorage<Value = (Value, Interval<BlockNumber>)>,
104 Error: WaitlistError,
105 OutputError: From<Error>,
106 Callbacks: WaitlistCallbacks<Value = Value, BlockNumber = BlockNumber>,
107 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
108{
109 type Key1 = T::Key1;
110 type Key2 = T::Key2;
111 type Value = Value;
112 type BlockNumber = BlockNumber;
113 type Error = Error;
114 type OutputError = OutputError;
115
116 fn contains(program_id: &Self::Key1, message_id: &Self::Key2) -> bool {
117 T::contains_keys(program_id, message_id)
118 }
119
120 fn insert(
121 message: Self::Value,
122 scheduled_at: Self::BlockNumber,
123 ) -> Result<(), Self::OutputError> {
124 let (key1, key2) = KeyGen::key_for(&message);
125
126 if Self::contains(&key1, &key2) {
127 return Err(Self::Error::duplicate_key().into());
128 }
129
130 let block_number = Callbacks::GetBlockNumber::call();
131 let message_with_bn = (
132 message,
133 Interval {
134 start: block_number,
135 finish: scheduled_at,
136 },
137 );
138
139 Callbacks::OnInsert::call(&message_with_bn);
140 T::insert(key1, key2, message_with_bn);
141 Ok(())
142 }
143
144 fn remove(
145 program_id: Self::Key1,
146 message_id: Self::Key2,
147 ) -> Result<ValueWithInterval<Self::Value, Self::BlockNumber>, Self::OutputError> {
148 if let Some(message_with_bn) = T::take(program_id, message_id) {
149 Callbacks::OnRemove::call(&message_with_bn);
150 Ok(message_with_bn)
151 } else {
152 Err(Self::Error::element_not_found().into())
153 }
154 }
155
156 fn clear() {
157 T::clear()
158 }
159}
160
161impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> CountedByKey
164 for WaitlistImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
165where
166 T: DoubleMapStorage<Value = (Value, Interval<BlockNumber>)> + CountedByKey<Key = T::Key1>,
167 Error: WaitlistError,
168 OutputError: From<Error>,
169 Callbacks: WaitlistCallbacks<Value = Value, BlockNumber = BlockNumber>,
170 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
171{
172 type Key = T::Key1;
173 type Length = T::Length;
174
175 fn len(key: &Self::Key) -> Self::Length {
176 T::len(key)
177 }
178}
179
180impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableByKeyMap<T::Value>
183 for WaitlistImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
184where
185 T: DoubleMapStorage<Value = (Value, Interval<BlockNumber>)>
186 + IterableByKeyMap<T::Value, Key = T::Key1>,
187 Error: WaitlistError,
188 OutputError: From<Error>,
189 Callbacks: WaitlistCallbacks<Value = Value, BlockNumber = BlockNumber>,
190 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
191{
192 type Key = T::Key1;
193 type DrainIter = T::DrainIter;
194 type Iter = T::Iter;
195
196 fn drain_key(key: Self::Key) -> Self::DrainIter {
197 T::drain_key(key)
198 }
199
200 fn iter_key(key: Self::Key) -> Self::Iter {
201 T::iter_key(key)
202 }
203}
204
205impl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen> IterableMap<T::Value>
208 for WaitlistImpl<T, Value, BlockNumber, Error, OutputError, Callbacks, KeyGen>
209where
210 T: DoubleMapStorage<Value = (Value, Interval<BlockNumber>)> + IterableMap<T::Value>,
211 Error: WaitlistError,
212 OutputError: From<Error>,
213 Callbacks: WaitlistCallbacks<Value = Value, BlockNumber = BlockNumber>,
214 KeyGen: KeyFor<Key = (T::Key1, T::Key2), Value = Value>,
215{
216 type DrainIter = T::DrainIter;
217 type Iter = T::Iter;
218
219 fn drain() -> Self::DrainIter {
220 T::drain()
221 }
222
223 fn iter() -> Self::Iter {
224 T::iter()
225 }
226}