1use crate::{
4 error::Error,
5 proto::{Query as PluginQuery, QueryState},
6};
7use serde_json::Value;
8
9#[derive(Debug)]
10pub struct Query {
11 pub id: usize,
12 pub direction: QueryDirection,
13 pub publisher: String,
14 pub plugin: String,
15 pub query: String,
16 pub key: Vec<serde_json::Value>,
17 pub output: Vec<serde_json::Value>,
18 pub concerns: Vec<String>,
19}
20
21#[derive(Debug, PartialEq, Eq)]
22pub enum QueryDirection {
23 Request,
24 Response,
25}
26
27impl TryFrom<QueryState> for QueryDirection {
28 type Error = Error;
29
30 fn try_from(value: QueryState) -> Result<Self, Self::Error> {
31 match value {
32 QueryState::Unspecified => Err(Error::UnspecifiedQueryState),
33 QueryState::SubmitInProgress => Err(Error::UnexpectedRequestInProgress),
34 QueryState::SubmitComplete => Ok(QueryDirection::Request),
35 QueryState::ReplyInProgress => Err(Error::UnexpectedReplyInProgress),
36 QueryState::ReplyComplete => Ok(QueryDirection::Response),
37 }
38 }
39}
40
41impl From<QueryDirection> for QueryState {
42 fn from(value: QueryDirection) -> Self {
43 match value {
44 QueryDirection::Request => QueryState::SubmitComplete,
45 QueryDirection::Response => QueryState::ReplyComplete,
46 }
47 }
48}
49
50impl TryFrom<PluginQuery> for Query {
51 type Error = Error;
52
53 fn try_from(value: PluginQuery) -> Result<Query, Self::Error> {
54 let direction = QueryDirection::try_from(value.state())?;
55
56 fn get_fields_rfd9(v: &PluginQuery) -> Result<(Vec<Value>, Vec<Value>), Error> {
57 let mut keys = Vec::with_capacity(v.key.len());
58 for x in v.key.iter() {
59 let value =
60 serde_json::from_str(x.as_str()).map_err(Error::InvalidJsonInQueryKey)?;
61 keys.push(value);
62 }
63
64 let mut outputs = Vec::with_capacity(v.output.len());
65 for x in v.output.iter() {
66 let value =
67 serde_json::from_str(x.as_str()).map_err(Error::InvalidJsonInQueryOutput)?;
68 outputs.push(value);
69 }
70
71 Ok((keys, outputs))
72 }
73
74 fn get_fields_compat(v: &PluginQuery) -> Result<(Vec<Value>, Vec<Value>), Error> {
75 let key = v.key.join("");
76 let output = v.output.join("");
77 let json_key = serde_json::from_str(&key).map_err(Error::InvalidJsonInQueryKey)?;
78 let json_out =
79 serde_json::from_str(&output).map_err(Error::InvalidJsonInQueryOutput)?;
80 Ok((vec![json_key], vec![json_out]))
81 }
82
83 let rfd9_res = get_fields_rfd9(&value);
84
85 let (keys, outputs) = if rfd9_res.is_err() && cfg!(feature = "rfd9-compat") {
86 get_fields_compat(&value)?
87 } else {
88 rfd9_res?
89 };
90
91 Ok(Query {
92 id: value.id as usize,
93 direction,
94 publisher: value.publisher_name,
95 plugin: value.plugin_name,
96 query: value.query_name,
97 key: keys,
98 output: outputs,
99 concerns: value.concern,
100 })
101 }
102}
103
104impl TryFrom<Query> for PluginQuery {
105 type Error = Error;
106
107 fn try_from(value: Query) -> Result<PluginQuery, Self::Error> {
108 let state: QueryState = value.direction.into();
109
110 let mut keys = vec![];
111 for key in value.key {
112 let json_formatted_key =
113 serde_json::to_string(&key).map_err(Error::InvalidJsonInQueryKey)?;
114 keys.push(json_formatted_key);
115 }
116
117 let mut outputs = vec![];
118 for output in value.output {
119 let json_formatted_output =
120 serde_json::to_string(&output).map_err(Error::InvalidJsonInQueryKey)?;
121 outputs.push(json_formatted_output);
122 }
123
124 Ok(PluginQuery {
125 id: value.id as i32,
126 state: state as i32,
127 publisher_name: value.publisher,
128 plugin_name: value.plugin,
129 query_name: value.query,
130 key: keys,
131 output: outputs,
132 concern: value.concerns,
133 split: false,
134 })
135 }
136}