1use crate::common::translate_column;
2use crate::common::{ColumnId, UTC_TIMESTAMP_WIDTH};
3use std::collections::HashMap;
4
5pub fn init(i18n: &mut HashMap<String, String>) {
6 for col in [
7 AlarmColumn::Name,
8 AlarmColumn::State,
9 AlarmColumn::LastStateUpdate,
10 AlarmColumn::Description,
11 AlarmColumn::Conditions,
12 AlarmColumn::Actions,
13 AlarmColumn::StateDetails,
14 AlarmColumn::MetricName,
15 AlarmColumn::Namespace,
16 AlarmColumn::Statistic,
17 AlarmColumn::Period,
18 AlarmColumn::Resource,
19 AlarmColumn::Dimensions,
20 AlarmColumn::Expression,
21 AlarmColumn::Type,
22 AlarmColumn::CrossAccount,
23 ] {
24 i18n.entry(col.id().to_string())
25 .or_insert_with(|| col.default_name().to_string());
26 }
27}
28
29#[derive(Debug, Clone)]
30pub struct Alarm {
31 pub name: String,
32 pub state: String,
33 pub state_updated_timestamp: String,
34 pub description: String,
35 pub metric_name: String,
36 pub namespace: String,
37 pub statistic: String,
38 pub period: u32,
39 pub comparison_operator: String,
40 pub threshold: f64,
41 pub actions_enabled: bool,
42 pub state_reason: String,
43 pub resource: String,
44 pub dimensions: String,
45 pub expression: String,
46 pub alarm_type: String,
47 pub cross_account: String,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq)]
51pub enum AlarmColumn {
52 Name,
53 State,
54 LastStateUpdate,
55 Description,
56 Conditions,
57 Actions,
58 StateDetails,
59 MetricName,
60 Namespace,
61 Statistic,
62 Period,
63 Resource,
64 Dimensions,
65 Expression,
66 Type,
67 CrossAccount,
68}
69
70impl AlarmColumn {
71 const ID_NAME: &'static str = "column.cw.alarm.name";
72 const ID_STATE: &'static str = "column.cw.alarm.state";
73 const ID_LAST_STATE_UPDATE: &'static str = "column.cw.alarm.last_state_update";
74 const ID_DESCRIPTION: &'static str = "column.cw.alarm.description";
75 const ID_CONDITIONS: &'static str = "column.cw.alarm.conditions";
76 const ID_ACTIONS: &'static str = "column.cw.alarm.actions";
77 const ID_STATE_DETAILS: &'static str = "column.cw.alarm.state_details";
78 const ID_METRIC_NAME: &'static str = "column.cw.alarm.metric_name";
79 const ID_NAMESPACE: &'static str = "column.cw.alarm.namespace";
80 const ID_STATISTIC: &'static str = "column.cw.alarm.statistic";
81 const ID_PERIOD: &'static str = "column.cw.alarm.period";
82 const ID_RESOURCE: &'static str = "column.cw.alarm.resource";
83 const ID_DIMENSIONS: &'static str = "column.cw.alarm.dimensions";
84 const ID_EXPRESSION: &'static str = "column.cw.alarm.expression";
85 const ID_TYPE: &'static str = "column.cw.alarm.type";
86 const ID_CROSS_ACCOUNT: &'static str = "column.cw.alarm.cross_account";
87
88 pub const fn id(&self) -> &'static str {
89 match self {
90 AlarmColumn::Name => Self::ID_NAME,
91 AlarmColumn::State => Self::ID_STATE,
92 AlarmColumn::LastStateUpdate => Self::ID_LAST_STATE_UPDATE,
93 AlarmColumn::Description => Self::ID_DESCRIPTION,
94 AlarmColumn::Conditions => Self::ID_CONDITIONS,
95 AlarmColumn::Actions => Self::ID_ACTIONS,
96 AlarmColumn::StateDetails => Self::ID_STATE_DETAILS,
97 AlarmColumn::MetricName => Self::ID_METRIC_NAME,
98 AlarmColumn::Namespace => Self::ID_NAMESPACE,
99 AlarmColumn::Statistic => Self::ID_STATISTIC,
100 AlarmColumn::Period => Self::ID_PERIOD,
101 AlarmColumn::Resource => Self::ID_RESOURCE,
102 AlarmColumn::Dimensions => Self::ID_DIMENSIONS,
103 AlarmColumn::Expression => Self::ID_EXPRESSION,
104 AlarmColumn::Type => Self::ID_TYPE,
105 AlarmColumn::CrossAccount => Self::ID_CROSS_ACCOUNT,
106 }
107 }
108
109 pub const fn default_name(&self) -> &'static str {
110 match self {
111 AlarmColumn::Name => "Name",
112 AlarmColumn::State => "State",
113 AlarmColumn::LastStateUpdate => "Last state update",
114 AlarmColumn::Description => "Description",
115 AlarmColumn::Conditions => "Conditions",
116 AlarmColumn::Actions => "Actions",
117 AlarmColumn::StateDetails => "State details",
118 AlarmColumn::MetricName => "Metric name",
119 AlarmColumn::Namespace => "Namespace",
120 AlarmColumn::Statistic => "Statistic",
121 AlarmColumn::Period => "Period",
122 AlarmColumn::Resource => "Resource",
123 AlarmColumn::Dimensions => "Dimensions",
124 AlarmColumn::Expression => "Expression",
125 AlarmColumn::Type => "Type",
126 AlarmColumn::CrossAccount => "Cross-account",
127 }
128 }
129
130 pub fn name(&self) -> String {
131 translate_column(self.id(), self.default_name())
132 }
133
134 pub fn width(&self) -> u16 {
135 match self {
136 AlarmColumn::Name => 30,
137 AlarmColumn::State => 15,
138 AlarmColumn::LastStateUpdate => UTC_TIMESTAMP_WIDTH,
139 AlarmColumn::Description => 40,
140 AlarmColumn::Conditions => 30,
141 AlarmColumn::Actions => 20,
142 AlarmColumn::StateDetails => 30,
143 AlarmColumn::MetricName => 25,
144 AlarmColumn::Namespace => 20,
145 AlarmColumn::Statistic => 15,
146 AlarmColumn::Period => 10,
147 AlarmColumn::Resource => 25,
148 AlarmColumn::Dimensions => 25,
149 AlarmColumn::Expression => 30,
150 AlarmColumn::Type => 15,
151 AlarmColumn::CrossAccount => 15,
152 }
153 }
154
155 pub fn from_id(id: &str) -> Option<Self> {
156 match id {
157 Self::ID_NAME => Some(AlarmColumn::Name),
158 Self::ID_STATE => Some(AlarmColumn::State),
159 Self::ID_LAST_STATE_UPDATE => Some(AlarmColumn::LastStateUpdate),
160 Self::ID_DESCRIPTION => Some(AlarmColumn::Description),
161 Self::ID_CONDITIONS => Some(AlarmColumn::Conditions),
162 Self::ID_ACTIONS => Some(AlarmColumn::Actions),
163 Self::ID_STATE_DETAILS => Some(AlarmColumn::StateDetails),
164 Self::ID_METRIC_NAME => Some(AlarmColumn::MetricName),
165 Self::ID_NAMESPACE => Some(AlarmColumn::Namespace),
166 Self::ID_STATISTIC => Some(AlarmColumn::Statistic),
167 Self::ID_PERIOD => Some(AlarmColumn::Period),
168 Self::ID_RESOURCE => Some(AlarmColumn::Resource),
169 Self::ID_DIMENSIONS => Some(AlarmColumn::Dimensions),
170 Self::ID_EXPRESSION => Some(AlarmColumn::Expression),
171 Self::ID_TYPE => Some(AlarmColumn::Type),
172 Self::ID_CROSS_ACCOUNT => Some(AlarmColumn::CrossAccount),
173 _ => None,
174 }
175 }
176
177 pub fn all() -> [AlarmColumn; 16] {
178 [
179 AlarmColumn::Name,
180 AlarmColumn::State,
181 AlarmColumn::LastStateUpdate,
182 AlarmColumn::Description,
183 AlarmColumn::Conditions,
184 AlarmColumn::Actions,
185 AlarmColumn::StateDetails,
186 AlarmColumn::MetricName,
187 AlarmColumn::Namespace,
188 AlarmColumn::Statistic,
189 AlarmColumn::Period,
190 AlarmColumn::Resource,
191 AlarmColumn::Dimensions,
192 AlarmColumn::Expression,
193 AlarmColumn::Type,
194 AlarmColumn::CrossAccount,
195 ]
196 }
197
198 pub fn ids() -> Vec<ColumnId> {
199 Self::all().iter().map(|c| c.id()).collect()
200 }
201}
202
203pub fn console_url(
204 region: &str,
205 view_mode: &str,
206 page_size: usize,
207 sort_col: &str,
208 sort_dir: &str,
209) -> String {
210 format!(
211 "https://{}.console.aws.amazon.com/cloudwatch/home?region={}#alarmsV2:alarms/{}/{}?~(sortingColumn~'{}~sortingDirection~'{})",
212 region, region, view_mode, page_size, sort_col, sort_dir
213 )
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn test_column_ids_have_correct_prefix() {
222 for col in AlarmColumn::all() {
223 assert!(
224 col.id().starts_with("column.cw.alarm."),
225 "AlarmColumn ID '{}' should start with 'column.cw.alarm.'",
226 col.id()
227 );
228 }
229 }
230}