1use std::{
7 collections::{HashMap, HashSet},
8 fmt::Debug,
9};
10
11use allocative::Allocative;
12
13use crate::{
14 self as linera_views,
15 bucket_queue_view::BucketQueueView,
16 collection_view::CollectionView,
17 context::MemoryContext,
18 log_view::LogView,
19 map_view::MapView,
20 queue_view::QueueView,
21 register_view::RegisterView,
22 set_view::SetView,
23 views::{ClonableView, RootView},
24 ViewError,
25};
26
27pub trait TestView: RootView<Context = MemoryContext<()>> + ClonableView {
29 type State: Debug + Eq + Send;
31
32 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError>;
35
36 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError>;
41
42 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError>;
47
48 async fn read(&self) -> Result<Self::State, ViewError>;
50}
51
52#[derive(RootView, ClonableView)]
54pub struct TestRegisterView<C> {
55 byte: RegisterView<C, u8>,
56}
57
58impl TestView for TestRegisterView<MemoryContext<()>> {
59 type State = u8;
60
61 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
62 let dummy_value = 82;
63 self.byte.set(dummy_value);
64 Ok(dummy_value)
65 }
66
67 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
68 let dummy_value = 209;
69 self.byte.set(dummy_value);
70 Ok(dummy_value)
71 }
72
73 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
74 let dummy_value = 15;
75 self.byte.set(dummy_value);
76 Ok(dummy_value)
77 }
78
79 async fn read(&self) -> Result<Self::State, ViewError> {
80 Ok(*self.byte.get())
81 }
82}
83
84const INITIAL_LOG_QUEUE_VIEW_CHANGES: &[u16] = &[1, 2, 3, 4, 5];
85
86#[derive(RootView, ClonableView)]
88pub struct TestLogView<C> {
89 log: LogView<C, u16>,
90}
91
92impl TestView for TestLogView<MemoryContext<()>> {
93 type State = Vec<u16>;
94
95 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
96 for value in INITIAL_LOG_QUEUE_VIEW_CHANGES {
97 self.log.push(*value);
98 }
99
100 Ok(INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec())
101 }
102
103 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
104 let new_values = [10_000, 20_000, 30_000];
105
106 for value in new_values {
107 self.log.push(value);
108 }
109
110 Ok(INITIAL_LOG_QUEUE_VIEW_CHANGES
111 .iter()
112 .copied()
113 .chain(new_values)
114 .collect())
115 }
116
117 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
118 let new_values = [201, 1, 50_050];
119
120 for value in new_values {
121 self.log.push(value);
122 }
123
124 Ok(INITIAL_LOG_QUEUE_VIEW_CHANGES
125 .iter()
126 .copied()
127 .chain(new_values)
128 .collect())
129 }
130
131 async fn read(&self) -> Result<Self::State, ViewError> {
132 self.log.read(..).await
133 }
134}
135
136const INITIAL_MAP_COLLECTION_VIEW_CHANGES: &[(i32, &str)] = &[
137 (0, "zero"),
138 (-1, "minus one"),
139 (2, "two"),
140 (-3, "minus three"),
141 (4, "four"),
142 (-5, "minus five"),
143];
144
145#[derive(RootView, ClonableView)]
147pub struct TestMapView<C> {
148 map: MapView<C, i32, String>,
149}
150
151impl TestView for TestMapView<MemoryContext<()>> {
152 type State = HashMap<i32, String>;
153
154 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
155 for (key, value) in INITIAL_MAP_COLLECTION_VIEW_CHANGES {
156 self.map.insert(key, value.to_string())?;
157 }
158
159 Ok(INITIAL_MAP_COLLECTION_VIEW_CHANGES
160 .iter()
161 .map(|(key, value)| (*key, value.to_string()))
162 .collect::<HashMap<_, _>>())
163 }
164
165 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
166 let new_entries = [(-1_000_000, "foo"), (2_000_000, "bar")]
167 .into_iter()
168 .map(|(key, value)| (key, value.to_owned()));
169
170 let entries_to_remove = [0, -3];
171
172 for (key, value) in new_entries.clone() {
173 self.map.insert(&key, value)?;
174 }
175
176 for key in entries_to_remove {
177 self.map.remove(&key)?;
178 }
179
180 let new_state = INITIAL_MAP_COLLECTION_VIEW_CHANGES
181 .iter()
182 .filter(|(key, _)| !entries_to_remove.contains(key))
183 .map(|(key, value)| (*key, value.to_string()))
184 .chain(new_entries)
185 .collect();
186
187 Ok(new_state)
188 }
189
190 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
191 let new_entries = [(1_234, "first new entry"), (-2_101_010, "second_new_entry")]
192 .into_iter()
193 .map(|(key, value)| (key, value.to_owned()));
194
195 let entries_to_remove = [-1, 2, 4];
196
197 for (key, value) in new_entries.clone() {
198 self.map.insert(&key, value)?;
199 }
200
201 for key in entries_to_remove {
202 self.map.remove(&key)?;
203 }
204
205 let new_state = INITIAL_MAP_COLLECTION_VIEW_CHANGES
206 .iter()
207 .filter(|(key, _)| !entries_to_remove.contains(key))
208 .map(|(key, value)| (*key, value.to_string()))
209 .chain(new_entries)
210 .collect();
211
212 Ok(new_state)
213 }
214
215 async fn read(&self) -> Result<Self::State, ViewError> {
216 let mut state = HashMap::new();
217 self.map
218 .for_each_index_value(|key, value| {
219 let value = value.into_owned();
220 state.insert(key, value);
221 Ok(())
222 })
223 .await?;
224 Ok(state)
225 }
226}
227
228#[derive(RootView, ClonableView)]
230pub struct TestSetView<C> {
231 set: SetView<C, i32>,
232}
233
234const INITIAL_SET_VIEW_CHANGES: &[i32] = &[0, -1, 2, -3, 4, -5];
235
236impl TestView for TestSetView<MemoryContext<()>> {
237 type State = HashSet<i32>;
238
239 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
240 for key in INITIAL_SET_VIEW_CHANGES {
241 self.set.insert(key)?;
242 }
243
244 Ok(INITIAL_SET_VIEW_CHANGES.iter().copied().collect())
245 }
246
247 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
248 let mut state = INITIAL_SET_VIEW_CHANGES
249 .iter()
250 .copied()
251 .collect::<HashSet<_>>();
252 let new_entries = [-1_000_000, 2_000_000];
253
254 let entries_to_remove = [0, -3];
255
256 for key in new_entries {
257 self.set.insert(&key)?;
258 state.insert(key);
259 }
260
261 for key in entries_to_remove {
262 self.set.remove(&key)?;
263 state.remove(&key);
264 }
265
266 Ok(state)
267 }
268
269 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
270 let mut state = INITIAL_SET_VIEW_CHANGES
271 .iter()
272 .copied()
273 .collect::<HashSet<_>>();
274 let new_entries = [1_234, -2_101_010];
275
276 let entries_to_remove = [-1, 2, 4];
277
278 for key in new_entries {
279 self.set.insert(&key)?;
280 state.insert(key);
281 }
282
283 for key in entries_to_remove {
284 self.set.remove(&key)?;
285 state.remove(&key);
286 }
287
288 Ok(state)
289 }
290
291 async fn read(&self) -> Result<Self::State, ViewError> {
292 let indices = self.set.indices().await?;
293 Ok(indices.into_iter().collect())
294 }
295}
296
297#[derive(RootView, ClonableView)]
299pub struct TestCollectionView<C> {
300 collection: CollectionView<C, i32, RegisterView<C, String>>,
301}
302
303impl TestView for TestCollectionView<MemoryContext<()>> {
304 type State = HashMap<i32, String>;
305
306 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
307 for (key, value) in INITIAL_MAP_COLLECTION_VIEW_CHANGES {
308 self.collection
309 .load_entry_mut(key)
310 .await?
311 .set(value.to_string());
312 }
313
314 Ok(INITIAL_MAP_COLLECTION_VIEW_CHANGES
315 .iter()
316 .map(|(key, value)| (*key, value.to_string()))
317 .collect::<HashMap<_, _>>())
318 }
319
320 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
321 let new_entries = [(-1_000_000, "foo"), (2_000_000, "bar")]
322 .into_iter()
323 .map(|(key, value)| (key, value.to_owned()));
324
325 let entries_to_remove = [0, -3];
326
327 for (key, value) in new_entries.clone() {
328 self.collection.load_entry_mut(&key).await?.set(value);
329 }
330
331 for key in entries_to_remove {
332 self.collection.remove_entry(&key)?;
333 }
334
335 let new_state = INITIAL_MAP_COLLECTION_VIEW_CHANGES
336 .iter()
337 .filter(|(key, _)| !entries_to_remove.contains(key))
338 .map(|(key, value)| (*key, value.to_string()))
339 .chain(new_entries)
340 .collect();
341
342 Ok(new_state)
343 }
344
345 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
346 let new_entries = [(1_234, "first new entry"), (-2_101_010, "second_new_entry")]
347 .into_iter()
348 .map(|(key, value)| (key, value.to_owned()));
349
350 let entries_to_remove = [-1, 2, 4];
351
352 for (key, value) in new_entries.clone() {
353 self.collection.load_entry_mut(&key).await?.set(value);
354 }
355
356 for key in entries_to_remove {
357 self.collection.remove_entry(&key)?;
358 }
359
360 let new_state = INITIAL_MAP_COLLECTION_VIEW_CHANGES
361 .iter()
362 .filter(|(key, _)| !entries_to_remove.contains(key))
363 .map(|(key, value)| (*key, value.to_string()))
364 .chain(new_entries)
365 .collect();
366
367 Ok(new_state)
368 }
369
370 async fn read(&self) -> Result<Self::State, ViewError> {
371 let indices = self.collection.indices().await?;
372 let mut state = HashMap::with_capacity(indices.len());
373
374 for index in indices {
375 if let Some(value) = self.collection.try_load_entry(&index).await? {
376 state.insert(index, value.get().clone());
377 }
378 }
379
380 Ok(state)
381 }
382}
383
384#[derive(RootView, ClonableView)]
386pub struct TestQueueView<C> {
387 queue: QueueView<C, u16>,
388}
389
390impl TestView for TestQueueView<MemoryContext<()>> {
391 type State = Vec<u16>;
392
393 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
394 for value in INITIAL_LOG_QUEUE_VIEW_CHANGES {
395 self.queue.push_back(*value);
396 }
397
398 Ok(INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec())
399 }
400
401 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
402 let mut initial_state = INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec();
403 let new_values = [10_000, 20_000, 30_000];
404
405 for value in new_values {
406 self.queue.push_back(value);
407 initial_state.push(value);
408 }
409 self.queue.delete_front();
410 initial_state.remove(0);
411 self.queue.delete_front();
412 initial_state.remove(0);
413
414 Ok(initial_state)
415 }
416
417 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
418 let mut initial_state = INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec();
419 let new_values = [201, 1, 50_050, 203];
420
421 for value in new_values {
422 self.queue.push_back(value);
423 initial_state.push(value);
424 }
425 self.queue.delete_front();
426 initial_state.remove(0);
427
428 Ok(initial_state)
429 }
430
431 async fn read(&self) -> Result<Self::State, ViewError> {
432 self.queue.elements().await
433 }
434}
435
436#[derive(RootView, ClonableView, Allocative)]
438pub struct TestBucketQueueView<C> {
439 queue: BucketQueueView<C, u16, 2>,
440}
441
442impl TestView for TestBucketQueueView<MemoryContext<()>> {
443 type State = Vec<u16>;
444
445 async fn stage_initial_changes(&mut self) -> Result<Self::State, ViewError> {
446 for value in INITIAL_LOG_QUEUE_VIEW_CHANGES {
447 self.queue.push_back(*value);
448 }
449
450 Ok(INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec())
451 }
452
453 async fn stage_changes_to_be_discarded(&mut self) -> Result<Self::State, ViewError> {
454 let mut initial_state = INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec();
455 let new_values = [10_000, 20_000, 30_000];
456
457 for value in new_values {
458 self.queue.push_back(value);
459 initial_state.push(value);
460 }
461 self.queue.delete_front().await?;
462 initial_state.remove(0);
463 self.queue.delete_front().await?;
464 initial_state.remove(0);
465
466 Ok(initial_state)
467 }
468
469 async fn stage_changes_to_be_persisted(&mut self) -> Result<Self::State, ViewError> {
470 let mut initial_state = INITIAL_LOG_QUEUE_VIEW_CHANGES.to_vec();
471 let new_values = [201, 1, 50_050, 203];
472
473 for value in new_values {
474 self.queue.push_back(value);
475 initial_state.push(value);
476 }
477 self.queue.delete_front().await?;
478 initial_state.remove(0);
479
480 Ok(initial_state)
481 }
482
483 async fn read(&self) -> Result<Self::State, ViewError> {
484 self.queue.elements().await
485 }
486}