myko_rs/
query.rs

1use serde::{ser::Error, Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::{client::MykoClient, item::WrappedItem};
5
6pub trait MykoQuery {
7    type Item;
8
9    fn watch(&self, client: &MykoClient) -> impl tokio_stream::Stream<Item = Vec<Self::Item>>;
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase")]
14pub struct QueryResponse {
15    pub deletes: Vec<String>,
16
17    pub upserts: Vec<WrappedItem<Value>>,
18
19    pub sequence: u64,
20
21    pub tx: String,
22}
23
24pub struct QueryResult<T> {
25    pub deletes: Vec<String>,
26    pub upserts: Vec<T>,
27    pub sequence: u64,
28    pub tx: String,
29}
30
31impl<T> QueryResult<T> {
32    pub fn new(tx: String, upserts: Vec<T>) -> QueryResult<T> {
33        QueryResult {
34            deletes: vec![],
35            upserts,
36            sequence: 0,
37            tx,
38        }
39    }
40}
41
42impl QueryResponse {
43    pub fn new(tx: String, _result: Vec<Value>) -> QueryResponse {
44        QueryResponse {
45            sequence: 0,
46            upserts: vec![],
47            deletes: vec![],
48            tx,
49        }
50    }
51
52    pub fn to_string(&self) -> Result<String, serde_json::Error> {
53        serde_json::to_string(self)
54    }
55}
56
57impl QueryResponse {
58    pub fn get_tx(&self) -> String {
59        self.tx.clone()
60    }
61
62    // #[wasm_bindgen(getter, js_name = "result")]
63    // pub fn get_item(&self) -> String {
64    //     json!(self.result.clone()).to_string()
65    // }
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct WrappedQuery {
71    pub query: Value,
72    pub query_id: String,
73    pub query_item_type: String,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct QueryError {
79    pub tx: String,
80    pub message: String,
81}
82
83pub trait QueryId {
84    fn query_id(&self) -> String;
85}
86
87pub trait QueryItemType {
88    fn query_item_type(&self) -> String;
89}
90
91pub fn wrap_query<Q: QueryId + QueryItemType + Serialize + Clone>(
92    tx: String,
93    query: Q,
94) -> Result<WrappedQuery, serde_json::Error> {
95    let mut json = serde_json::to_value(query.clone())?;
96
97    let obj_mut = json.as_object_mut();
98
99    if obj_mut.is_none() {
100        return Err(serde_json::Error::custom("Could not convert to object"));
101    }
102
103    let obj = obj_mut.unwrap();
104
105    obj.insert("tx".to_string(), tx.into());
106
107    Ok(WrappedQuery {
108        query: json,
109        query_id: query.query_id(),
110        query_item_type: query.query_item_type(),
111    })
112}
113
114pub trait QueryHandler<Q: MykoQuery> {
115    fn handle_query(
116        &self,
117        query: Q,
118        tx: String,
119    ) -> impl tokio_stream::Stream<Item = QueryResult<Q::Item>>;
120}