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
#[cfg(feature = "json")]
mod json;
#[cfg(feature = "proto")]
mod proto;

pub use async_trait::async_trait;
use bytes::Bytes;
use futures_util::future::join_all;
use smol_str::SmolStr;
use std::collections::HashMap;

#[cfg(feature = "json")]
pub use json::KvdbJsonExt;
#[cfg(feature = "proto")]
pub use proto::KvdbProtoExt;

pub type Key = SmolStr;
pub type Value = Bytes;
pub type KeyValue = (Key, Value);

pub enum DBOp {
    Insert { key: Key, value: Value },
    InsertMany { data: HashMap<Key, Value> },
    Delete { key: Key },
    DeleteAll,
    DeletePrefix { prefix: Key },
}

#[async_trait]
pub trait Kvdb {
    async fn get(&self, key: Key) -> Option<Value> {
        self.get_with_prefix(key.clone()).await.remove(&key)
    }
    async fn get_keys(&self) -> Vec<Key>;
    async fn get_values(&self) -> Vec<Value>;
    async fn get_all(&self) -> HashMap<Key, Value>;
    async fn get_with_prefix(&self, prefix: Key) -> HashMap<Key, Value> {
        let mut data = self.get_all().await;
        data.retain(|k, _| k.starts_with(&*prefix));
        data
    }
    async fn set(&self, key: Key, value: Value) {
        let data = HashMap::from([(key, value)]);
        self.set_many(data).await
    }
    async fn set_many(&self, data: HashMap<Key, Value>);
    async fn delete(&self, key: Key);
    async fn delete_all(&self);
    async fn delete_with_prefix(&self, prefix: Key) {
        let data = self.get_with_prefix(prefix).await;
        let futs = data.into_keys().map(|k| self.delete(k));
        join_all(futs).await;
    }
}