elasticctl_api/value_lists/
evidence.rs1use super::ListPlan;
2use elasticctl_core::Error;
3use serde::Serialize;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
6#[serde(rename_all = "snake_case")]
7pub enum Outcome {
8 Applied,
9 Failed,
10 Unknown,
11 NotReached,
12}
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
15#[serde(rename_all = "snake_case")]
16pub enum Sent {
17 Accepted,
18 Refused,
19 Uncertain,
20 NotSent,
21}
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
24#[serde(rename_all = "snake_case")]
25pub enum Action {
26 CreateValueList,
27 UpdateValueList,
28 AddValues,
29 RemoveValues,
30 ReadBack,
31 NotReached,
32 DeleteValueList,
33 CheckValueList,
34}
35
36#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
37#[serde(rename_all = "snake_case")]
38pub enum ReadOf {
39 Values,
40 Container,
41}
42
43#[derive(Clone, Debug, Serialize)]
44pub struct Failure {
45 pub kind: String,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub status: Option<u16>,
48 pub message: String,
49}
50
51impl From<Error> for Failure {
52 fn from(error: Error) -> Self {
53 Self {
54 kind: error.kind.as_str().into(),
55 status: error.http_status,
56 message: error.message,
57 }
58 }
59}
60
61#[derive(Clone, Debug, Serialize)]
62pub struct Evidence {
63 pub action: Action,
64 pub rule_id: String,
65 pub name: String,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub values: Option<Vec<String>>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub sent: Option<Sent>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub status: Option<u16>,
72 pub phase_verified: bool,
73 pub outcome: Outcome,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub of: Option<ReadOf>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub observed: Option<bool>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub missing: Option<usize>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub extra: Option<usize>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub mismatched: Option<Vec<String>>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub read_error: Option<Failure>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub planned_adds: Option<usize>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub planned_removes: Option<usize>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub error: Option<Failure>,
92}
93
94impl Evidence {
95 pub(super) fn new(action: Action, id: &str, name: &str) -> Self {
96 Self {
97 action,
98 rule_id: id.into(),
99 name: name.into(),
100 values: Some(Vec::new()),
101 sent: Some(Sent::NotSent),
102 status: None,
103 phase_verified: false,
104 outcome: Outcome::NotReached,
105 of: None,
106 observed: None,
107 missing: None,
108 extra: None,
109 mismatched: None,
110 read_error: None,
111 planned_adds: None,
112 planned_removes: None,
113 error: None,
114 }
115 }
116}
117
118#[derive(Clone, Debug, Serialize)]
119pub struct ListOutcome {
120 pub id: String,
121 pub outcome: Outcome,
122 pub evidence: Vec<Evidence>,
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub error: Option<Failure>,
125}
126
127impl ListOutcome {
128 pub(super) fn finish(&mut self, outcome: Outcome, error: Option<Error>) {
129 self.outcome = outcome;
130 self.error = error.map(Into::into);
131 for entry in &mut self.evidence {
132 entry.outcome = outcome;
133 }
134 }
135
136 pub(super) fn not_reached(plan: &ListPlan) -> Self {
137 let c = &plan.local.container;
138 let mut entry = Evidence::new(Action::NotReached, &c.id, &c.name);
139 entry.values = None;
140 entry.planned_adds = Some(plan.adds.len());
141 entry.planned_removes = Some(plan.removes.len());
142 Self {
143 id: c.id.clone(),
144 outcome: Outcome::NotReached,
145 evidence: vec![entry],
146 error: None,
147 }
148 }
149}