1use async_trait::async_trait;
3use ecat_errors::Error;
4
5#[async_trait]
10pub trait WideColumnClient: Send + Sync {
11 async fn put(
13 &self,
14 table: &str,
15 row: &str,
16 cells: &std::collections::BTreeMap<String, serde_json::Value>,
17 ) -> Result<(), Error>;
18
19 async fn get(
21 &self,
22 table: &str,
23 row: &str,
24 ) -> Result<Option<std::collections::BTreeMap<String, serde_json::Value>>, Error>;
25
26 async fn scan(
29 &self,
30 table: &str,
31 prefix: &str,
32 limit: usize,
33 ) -> Result<
34 Vec<(
35 String,
36 std::collections::BTreeMap<String, serde_json::Value>,
37 )>,
38 Error,
39 >;
40
41 async fn delete(&self, table: &str, row: &str) -> Result<(), Error>;
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use std::collections::BTreeMap;
49
50 struct Noop;
51
52 #[async_trait]
53 impl WideColumnClient for Noop {
54 async fn put(
55 &self,
56 _table: &str,
57 _row: &str,
58 _cells: &BTreeMap<String, serde_json::Value>,
59 ) -> Result<(), Error> {
60 Ok(())
61 }
62
63 async fn get(
64 &self,
65 _table: &str,
66 _row: &str,
67 ) -> Result<Option<BTreeMap<String, serde_json::Value>>, Error> {
68 Ok(None)
69 }
70
71 async fn scan(
72 &self,
73 _table: &str,
74 _prefix: &str,
75 _limit: usize,
76 ) -> Result<Vec<(String, BTreeMap<String, serde_json::Value>)>, Error> {
77 Ok(Vec::new())
78 }
79
80 async fn delete(&self, _table: &str, _row: &str) -> Result<(), Error> {
81 Ok(())
82 }
83 }
84
85 #[tokio::test]
88 async fn trait_is_object_safe() {
89 let client: Box<dyn WideColumnClient> = Box::new(Noop);
90 let mut cells = BTreeMap::new();
91 cells.insert("cf:a".to_string(), serde_json::json!(1));
92 client.put("t", "r", &cells).await.unwrap();
93 assert!(client.get("t", "r").await.unwrap().is_none());
94 assert!(client.scan("t", "", 10).await.unwrap().is_empty());
95 client.delete("t", "r").await.unwrap();
96 }
97}