Skip to main content

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 {}