1use crate::api::value::RuleResultValue;
4use crate::evaluation::explanations::Explanation;
5use crate::evaluation::response::{Response as DomainResponse, RuleResult as DomainRuleResult};
6use crate::parsing::ast::DateTimeValue;
7use crate::result_value::RowResult;
8use indexmap::IndexMap;
9use serde::Serialize;
10
11#[derive(Debug, Clone, Serialize)]
12pub struct Response {
13 #[serde(rename = "spec")]
14 pub spec_name: String,
15 pub effective: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub spec_effective_from: Option<DateTimeValue>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub spec_effective_to: Option<DateTimeValue>,
20 pub results: IndexMap<String, RuleResult>,
21 #[serde(skip_serializing_if = "Vec::is_empty")]
22 pub rows: Vec<RowResult>,
23}
24
25impl From<&DomainResponse> for Response {
26 fn from(response: &DomainResponse) -> Self {
27 Self {
28 spec_name: response.spec_name.clone(),
29 effective: response.effective.clone(),
30 spec_effective_from: response.spec_effective_from.clone(),
31 spec_effective_to: response.spec_effective_to.clone(),
32 results: response
33 .results
34 .iter()
35 .map(|(name, result)| (name.clone(), RuleResult::from(result)))
36 .collect(),
37 rows: response.rows.clone(),
38 }
39 }
40}
41
42#[derive(Debug, Clone, Serialize)]
44pub struct RuleResult {
45 pub vetoed: bool,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub veto_reason: Option<String>,
48 pub rule_type: String,
49 #[serde(flatten)]
50 pub result: Option<RuleResultValue>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub explanation: Option<Explanation>,
53 #[serde(skip_serializing_if = "Vec::is_empty")]
54 pub missing_data: Vec<String>,
55}
56
57impl From<&DomainRuleResult> for RuleResult {
58 fn from(result: &DomainRuleResult) -> Self {
59 Self {
60 vetoed: result.vetoed,
61 veto_reason: result.veto_reason.clone(),
62 rule_type: result.rule_type.clone(),
63 result: result.result.as_ref().map(RuleResultValue::from),
64 explanation: result.explanation.clone(),
65 missing_data: result.missing_data().to_vec(),
66 }
67 }
68}