Skip to main content

elasticctl_api/state/
reports.rs

1use crate::diff::{Change, FieldChange};
2use crate::model::{ExceptionItem, ExceptionList, Rule};
3use serde::Serialize;
4use serde_json::Value;
5
6#[derive(Debug, Clone, PartialEq)]
7pub struct StackIdentity {
8    pub profile: String,
9    pub host: String,
10    pub space: String,
11}
12
13#[derive(Debug, Clone, PartialEq, Serialize)]
14pub struct PullReport {
15    pub pulled: usize,
16    pub exception_lists: usize,
17    pub exception_items: usize,
18    pub dir: String,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub selected: Option<usize>,
21    #[serde(skip_serializing_if = "is_zero")]
22    pub value_lists: usize,
23    #[serde(skip_serializing_if = "Vec::is_empty")]
24    pub value_list_warnings: Vec<crate::value_lists::Warning>,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize)]
28pub struct DiffReport {
29    pub clean: bool,
30    pub local: usize,
31    pub remote: usize,
32    pub changes: Vec<Change>,
33    pub exceptions: ExceptionDrift,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub value_lists: Option<super::values::ValueListDrift>,
36    #[serde(skip_serializing_if = "is_zero")]
37    pub out_of_scope: usize,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub selected: Option<usize>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub local_total: Option<usize>,
42}
43
44#[derive(Debug, Clone, PartialEq, Serialize)]
45pub struct PushReport {
46    pub applied: bool,
47    pub created: usize,
48    pub updated: usize,
49    pub skipped_remote_only: usize,
50    pub failed: usize,
51    pub pending: usize,
52    pub lists_created: usize,
53    pub lists_updated: usize,
54    pub items_created: usize,
55    pub items_updated: usize,
56    pub items_removed: usize,
57    #[serde(skip_serializing_if = "is_zero")]
58    pub value_lists_created: usize,
59    #[serde(skip_serializing_if = "is_zero")]
60    pub value_lists_updated: usize,
61    #[serde(skip_serializing_if = "is_zero")]
62    pub values_added: usize,
63    #[serde(skip_serializing_if = "is_zero")]
64    pub values_removed: usize,
65    #[serde(skip_serializing_if = "is_zero")]
66    pub value_lists_unknown: usize,
67    #[serde(skip_serializing_if = "is_zero")]
68    pub value_lists_not_reached: usize,
69    #[serde(skip_serializing_if = "is_zero")]
70    pub out_of_scope: usize,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub selected: Option<usize>,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub local_total: Option<usize>,
75}
76
77fn is_zero(n: &usize) -> bool {
78    *n == 0
79}
80
81#[derive(Debug)]
82pub struct Mirror {
83    pub rules: Vec<Rule>,
84    pub lists: Vec<ExceptionList>,
85    pub items: Vec<ExceptionItem>,
86    pub value_lists: Vec<crate::value_lists::LocalPair>,
87    pub has_value_lists: bool,
88}
89
90#[derive(Debug, Clone, PartialEq, Serialize)]
91pub struct ExceptionDrift {
92    pub local: usize,
93    pub remote: usize,
94    pub changes: Vec<ListChange>,
95    pub dangling: Vec<DanglingPointer>,
96}
97
98impl ExceptionDrift {
99    pub fn is_clean(&self) -> bool {
100        self.changes
101            .iter()
102            .all(|c| matches!(c, ListChange::Unchanged { .. }))
103            && self.dangling.is_empty()
104    }
105}
106
107#[derive(Debug, Clone, PartialEq, Serialize)]
108#[serde(tag = "change", rename_all = "snake_case")]
109pub enum ListChange {
110    Added {
111        list_id: String,
112        name: String,
113    },
114    Modified {
115        list_id: String,
116        name: String,
117        fields: Vec<FieldChange>,
118    },
119    Unchanged {
120        list_id: String,
121    },
122    RemoteOnly {
123        list_id: String,
124        name: String,
125    },
126    ItemAdded {
127        list_id: String,
128        item_id: String,
129    },
130    ItemModified {
131        list_id: String,
132        item_id: String,
133        fields: Vec<FieldChange>,
134    },
135    ItemRemoved {
136        list_id: String,
137        item_id: String,
138    },
139}
140
141#[derive(Debug, Clone, PartialEq, Serialize)]
142pub struct DanglingPointer {
143    pub rule_id: String,
144    pub list_id: String,
145    pub stored_id: Value,
146    pub live_id: Option<String>,
147}