hipcheck_common/
types.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use 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}