1use async_trait::async_trait;
3use ecat_errors::{Error, ErrorCode};
4
5#[async_trait]
6pub trait SearchClient: Send + Sync {
7 async fn index(&self, index: &str, id: &str, doc: &serde_json::Value) -> Result<(), Error>;
8 async fn search(
9 &self,
10 index: &str,
11 query: &serde_json::Value,
12 ) -> Result<serde_json::Value, Error>;
13 async fn delete(&self, index: &str, id: &str) -> Result<(), Error>;
14
15 async fn bulk_index(
18 &self,
19 _index: &str,
20 _docs: &[(String, serde_json::Value)],
21 ) -> Result<(), Error> {
22 Err(Error::new(
23 ErrorCode::Internal,
24 "search",
25 "bulk_index not supported by this backend",
26 ))
27 }
28
29 async fn update(&self, _index: &str, _id: &str, _doc: &serde_json::Value) -> Result<(), Error> {
31 Err(Error::new(
32 ErrorCode::Internal,
33 "search",
34 "update not supported by this backend",
35 ))
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 struct MinimalSearch;
45
46 #[async_trait]
47 impl SearchClient for MinimalSearch {
48 async fn index(
49 &self,
50 _index: &str,
51 _id: &str,
52 _doc: &serde_json::Value,
53 ) -> Result<(), Error> {
54 Ok(())
55 }
56 async fn search(
57 &self,
58 _index: &str,
59 _query: &serde_json::Value,
60 ) -> Result<serde_json::Value, Error> {
61 Ok(serde_json::Value::Null)
62 }
63 async fn delete(&self, _index: &str, _id: &str) -> Result<(), Error> {
64 Ok(())
65 }
66 }
67
68 #[tokio::test]
69 async fn optional_ops_default_to_not_supported_error() {
70 let client = MinimalSearch;
71 let err = client.bulk_index("idx", &[]).await.unwrap_err();
72 assert!(
73 err.to_string().contains("bulk_index not supported"),
74 "got: {err}"
75 );
76 let err = client
77 .update("idx", "1", &serde_json::Value::Null)
78 .await
79 .unwrap_err();
80 assert!(
81 err.to_string().contains("update not supported"),
82 "got: {err}"
83 );
84 }
85}