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 }
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}