luct_core/store/async.rs
1use crate::store::StoreBase;
2use std::future::Future;
3
4pub trait AsyncStoreRead: StoreBase {
5 /// Returns the value associated with `key` from the [`Store`](crate::store::Store)
6 ///
7 /// # Arguments:
8 /// - `key`: the key indexing the object
9 ///
10 /// # Returns:
11 /// - `Some(value)`, if the value exists
12 /// - `None` otherwise
13 fn get(&self, key: Self::Key) -> impl Future<Output = Option<Self::Value>>;
14
15 /// Returns the number of elements in the [`Store`](crate::store::Store)
16 fn len(&self) -> impl Future<Output = usize>;
17
18 /// Returns `true`, if the store is empty
19 fn is_empty(&self) -> impl Future<Output = bool> {
20 async { self.len().await == 0 }
21 }
22}
23
24pub trait AsyncStoreWrite: StoreBase {
25 /// Insert a value into the store
26 ///
27 /// # Arguments:
28 /// - `key`: the key associated with the value
29 /// - `value`: the value itself
30 fn insert(&self, key: Self::Key, value: Self::Value) -> impl Future<Output = ()>;
31
32 /// Remove a value from the store
33 ///
34 /// # Arguments
35 /// - `key`: the key to be removed
36 ///
37 /// # Returns
38 /// - `true` if the key existed and has been removed
39 /// - `false` otherwise
40 fn delete(&self, key: Self::Key) -> impl Future<Output = bool>;
41}
42
43/// The [`AsyncStore`] trait is a version of the [`Store`](crate::store::Store) that is asynchrounous
44///
45/// This allows the underlying store engine to make asynchronous requests,
46/// such as a distributed storage or rebuilding the store dynamically using tiles
47pub trait AsyncStore: AsyncStoreRead + AsyncStoreWrite {}
48
49impl<T> AsyncStore for T where T: AsyncStoreRead + AsyncStoreWrite {}
50
51/// Async version of [`OrderedStore`](crate::store::OrderedStore)
52pub trait AsyncOrderedStoreRead: AsyncStoreRead<Key: Ord> {
53 /// Returns the last element in the store
54 ///
55 /// The last element is the largest element with respect to the keys [`Ord`] implementation.
56 ///
57 /// # Returns
58 /// - `Some(key, value)` if the store is non-empty
59 /// - `None` otherwise
60 fn last(&self) -> impl Future<Output = Option<(Self::Key, Self::Value)>>;
61}
62
63pub trait AsyncOrderedStore: AsyncOrderedStoreRead + AsyncStoreWrite {}
64impl<T> AsyncOrderedStore for T where T: AsyncOrderedStoreRead + AsyncStoreWrite {}
65
66/// Async version of [`AppendableStore`](crate::store::AppendableStore)
67pub trait AsyncAppendableStore: AsyncOrderedStoreRead {
68 /// Insert a value into the store and return the index
69 ///
70 /// # Arguments:
71 /// - `value`: the value itself
72 ///
73 /// # Returns:
74 /// - the index of the new value. This is the key under which the value can later be retreived
75 fn append(&self, value: Self::Value) -> impl Future<Output = Self::Key>;
76}
77
78/// Async version of [`SearchableStore`](crate::store::SearchableStore)
79pub trait AsyncSearchableStoreRead: AsyncOrderedStoreRead {
80 /// Search for all entries in the store, that fulfill a certain predicate
81 ///
82 /// Note that the elements are being searched through in the order specified by [`Ord`] of key
83 ///
84 /// # Arguments
85 /// - `pred`: A predicate that has access to the key and value
86 ///
87 /// # Returns
88 /// - An array of key-value pairs, for which `pred` holds true
89 fn filter(
90 &self,
91 pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
92 ) -> impl Future<Output = Vec<(Self::Key, Self::Value)>>;
93
94 fn find(
95 &self,
96 mut pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
97 ) -> impl Future<Output = Option<(Self::Key, Self::Value)>> {
98 async move {
99 let mut found = false;
100
101 let vals = self
102 .filter(|key, value| {
103 if !found && pred(key, value) {
104 found = true;
105 true
106 } else {
107 false
108 }
109 })
110 .await;
111
112 if found {
113 assert_eq!(vals.len(), 1);
114 Some(vals.into_iter().next().unwrap())
115 } else {
116 None
117 }
118 }
119 }
120}
121
122pub trait AsyncSearchableStore: AsyncSearchableStoreRead + AsyncStoreWrite {}
123impl<T> AsyncSearchableStore for T where T: AsyncSearchableStoreRead + AsyncStoreWrite {}