Skip to main content

rusticity_term/cloudtrail/
resources.rs

1use crate::common::ColumnId;
2use crate::ui::table::Column as TableColumn;
3use ratatui::style::Style;
4
5#[derive(Debug, Clone)]
6pub struct EventResource {
7    pub resource_type: String,
8    pub resource_name: String,
9    pub timeline: String,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq)]
13pub enum EventResourceColumn {
14    ResourceType,
15    ResourceName,
16    Timeline,
17}
18
19impl EventResourceColumn {
20    const ID_RESOURCE_TYPE: &'static str = "column.cloudtrail.resource.resource_type";
21    const ID_RESOURCE_NAME: &'static str = "column.cloudtrail.resource.resource_name";
22    const ID_TIMELINE: &'static str = "column.cloudtrail.resource.timeline";
23
24    pub fn id(&self) -> ColumnId {
25        match self {
26            Self::ResourceType => Self::ID_RESOURCE_TYPE,
27            Self::ResourceName => Self::ID_RESOURCE_NAME,
28            Self::Timeline => Self::ID_TIMELINE,
29        }
30    }
31
32    pub fn from_id(id: &ColumnId) -> Option<Self> {
33        match *id {
34            Self::ID_RESOURCE_TYPE => Some(Self::ResourceType),
35            Self::ID_RESOURCE_NAME => Some(Self::ResourceName),
36            Self::ID_TIMELINE => Some(Self::Timeline),
37            _ => None,
38        }
39    }
40
41    pub fn ids() -> Vec<ColumnId> {
42        vec![
43            Self::ID_RESOURCE_TYPE,
44            Self::ID_RESOURCE_NAME,
45            Self::ID_TIMELINE,
46        ]
47    }
48
49    pub fn name(&self) -> &'static str {
50        match self {
51            Self::ResourceType => "Resource type",
52            Self::ResourceName => "Resource name",
53            Self::Timeline => "AWS Config resource timeline",
54        }
55    }
56
57    pub fn width(&self) -> u16 {
58        match self {
59            Self::ResourceType => 30,
60            Self::ResourceName => 50,
61            Self::Timeline => 30,
62        }
63    }
64}
65
66impl TableColumn<EventResource> for EventResourceColumn {
67    fn name(&self) -> &str {
68        self.name()
69    }
70
71    fn width(&self) -> u16 {
72        self.width()
73    }
74
75    fn render(&self, resource: &EventResource) -> (String, Style) {
76        let value = match self {
77            Self::ResourceType => resource.resource_type.clone(),
78            Self::ResourceName => resource.resource_name.clone(),
79            Self::Timeline => resource.timeline.clone(),
80        };
81        (value, Style::default())
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_column_ids_have_correct_prefix() {
91        for id in EventResourceColumn::ids() {
92            assert!(id.starts_with("column.cloudtrail.resource."));
93        }
94    }
95
96    #[test]
97    fn test_all_columns_count() {
98        assert_eq!(EventResourceColumn::ids().len(), 3);
99    }
100
101    #[test]
102    fn test_column_from_id() {
103        assert_eq!(
104            EventResourceColumn::from_id(&EventResourceColumn::ID_RESOURCE_TYPE),
105            Some(EventResourceColumn::ResourceType)
106        );
107        assert_eq!(
108            EventResourceColumn::from_id(&EventResourceColumn::ID_RESOURCE_NAME),
109            Some(EventResourceColumn::ResourceName)
110        );
111        assert_eq!(
112            EventResourceColumn::from_id(&EventResourceColumn::ID_TIMELINE),
113            Some(EventResourceColumn::Timeline)
114        );
115        assert_eq!(EventResourceColumn::from_id(&"invalid"), None);
116    }
117}