1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::time::Duration;
use crate::{dev::OwnedValue, error::Result, mutation::Mutation, value::Value};
/// It is usefull for when store and expiry are implemented for the same struct,
/// and should be implemented in those cases even if there can't be any optimization,
/// as it will prevent some runtime checks for expiry validity.
#[async_trait::async_trait]
pub trait Provider: Send + Sync {
/// Set a key-value pair, if the key already exist, value should be overwritten
async fn keys(&self, scope: &str) -> Result<Box<dyn Iterator<Item = Vec<u8>>>>;
/// Set a key-value pair, if the key already exist, value should be overwritten
async fn set(&self, scope: &str, key: &[u8], value: Value<'_>) -> Result<()>;
/// Get a single value for specified key, it should return None if the value does not exist
async fn get(&self, scope: &str, key: &[u8]) -> Result<Option<OwnedValue>>;
/// Get a list of values for specified key, it should return an empty vector if the value does not exist
async fn get_range(
&self,
scope: &str,
key: &[u8],
start: i64,
end: i64,
) -> Result<Vec<OwnedValue>>;
/// Push a value into the list associated with this key, if the key has a value of
/// another type, it should return error
async fn push(&self, scope: &str, key: &[u8], value: Value<'_>) -> Result<()>;
/// Push multiple values into the list associated with this key, if the key has a value of
/// another type, it should return error
async fn push_multiple(&self, scope: &str, key: &[u8], value: Vec<Value<'_>>) -> Result<()>;
/// Pop a value from the list associated with this key, if the key has a value of
/// another type, it should return error
async fn pop(&self, scope: &str, key: &[u8]) -> Result<Option<OwnedValue>>;
/// Mutate and get a value for specified key, it should set the value to 0 if it doesn't exist
async fn mutate(&self, scope: &str, key: &[u8], mutations: Mutation) -> Result<i64>;
/// Delete the key from storage, if the key doesn't exist, it shouldn't return an error
async fn remove(&self, scope: &str, key: &[u8]) -> Result<Option<OwnedValue>>;
/// Check if key exist in storage
async fn contains_key(&self, scope: &str, key: &[u8]) -> Result<bool>;
/// Remove all expiry requests from a key and make it persistent,
/// the persistenty can be overwriten by calling expire on the key.
async fn persist(&self, scope: &str, key: &[u8]) -> Result<()>;
/// Sets an expiry for a key, the key may or may not be removed based on
/// implementation, but it should be guaranteed that it won't appear in
/// get based methods or contains checks after the period specified.
async fn expire(&self, scope: &str, key: &[u8], expire_in: Duration) -> Result<()>;
/// Gets expiry for a key, returning None means it doesn't have an expiry,
/// if the provider can't return an expiry, it should return an error instead.
/// The result of this function can have some error, but it should be documented.
async fn expiry(&self, scope: &str, key: &[u8]) -> Result<Option<Duration>>;
/// Extend expiry for a key for another duration of time.
/// If the key doesn't have an expiry, it should be equivalent of calling expire.
async fn extend(&self, scope: &str, key: &[u8], expire_in: Duration) -> Result<()> {
let expiry = self.expiry(scope.clone(), key.clone()).await?;
self.expire(scope, key, expiry.unwrap_or_default() + expire_in)
.await
}
/// Set a key-value for a duration of time, if the key already exists, it should overwrite
/// both the value and the expiry for that key.
async fn set_expiring(
&self,
scope: &str,
key: &[u8],
value: Value<'_>,
expire_in: Duration,
) -> Result<()> {
self.set(scope.clone(), key.clone(), value).await?;
self.expire(scope, key, expire_in).await
}
/// Get the value and expiry for a key, it is possible to return None if the key doesn't exist,
/// or return None for the expiry if the key is persistent.
async fn get_expiring(
&self,
scope: &str,
key: &[u8],
) -> Result<Option<(OwnedValue, Option<Duration>)>> {
let val = self.get(scope.clone(), key.clone()).await?;
match val {
Some(val) => {
let expiry = self.expiry(scope, key).await?;
Ok(Some((val, expiry)))
}
None => Ok(None),
}
}
}