rusticity_term/efs/
access_point.rs1use crate::common::{translate_column, ColumnId};
2use crate::ui::table::Column as TableColumn;
3use ratatui::prelude::*;
4use rusticity_core::efs::EfsAccessPoint as AccessPoint;
5use std::collections::HashMap;
6
7pub fn init(i18n: &mut HashMap<String, String>) {
8 for col in Column::all() {
9 i18n.entry(col.id().to_string())
10 .or_insert_with(|| col.default_name().to_string());
11 }
12}
13
14#[derive(Debug, Clone, Copy, PartialEq)]
15pub enum Column {
16 Name,
17 AccessPointId,
18 Path,
19 PosixUser,
20 CreationInfo,
21 State,
22}
23
24impl Column {
25 const ID_NAME: &'static str = "column.efs.ap.name";
26 const ID_ACCESS_POINT_ID: &'static str = "column.efs.ap.access_point_id";
27 const ID_PATH: &'static str = "column.efs.ap.path";
28 const ID_POSIX_USER: &'static str = "column.efs.ap.posix_user";
29 const ID_CREATION_INFO: &'static str = "column.efs.ap.creation_info";
30 const ID_STATE: &'static str = "column.efs.ap.state";
31
32 pub const fn id(&self) -> &'static str {
33 match self {
34 Column::Name => Self::ID_NAME,
35 Column::AccessPointId => Self::ID_ACCESS_POINT_ID,
36 Column::Path => Self::ID_PATH,
37 Column::PosixUser => Self::ID_POSIX_USER,
38 Column::CreationInfo => Self::ID_CREATION_INFO,
39 Column::State => Self::ID_STATE,
40 }
41 }
42
43 pub const fn default_name(&self) -> &'static str {
44 match self {
45 Column::Name => "Name",
46 Column::AccessPointId => "Access point ID",
47 Column::Path => "Path",
48 Column::PosixUser => "POSIX user",
49 Column::CreationInfo => "Creation info",
50 Column::State => "State",
51 }
52 }
53
54 pub const fn all() -> [Column; 6] {
55 [
56 Column::Name,
57 Column::AccessPointId,
58 Column::Path,
59 Column::PosixUser,
60 Column::CreationInfo,
61 Column::State,
62 ]
63 }
64
65 pub fn ids() -> Vec<ColumnId> {
66 Self::all().iter().map(|c| c.id()).collect()
67 }
68
69 pub fn default_visible_ids() -> Vec<ColumnId> {
71 Self::ids()
72 }
73
74 pub fn from_id(id: &str) -> Option<Self> {
75 match id {
76 Self::ID_NAME => Some(Column::Name),
77 Self::ID_ACCESS_POINT_ID => Some(Column::AccessPointId),
78 Self::ID_PATH => Some(Column::Path),
79 Self::ID_POSIX_USER => Some(Column::PosixUser),
80 Self::ID_CREATION_INFO => Some(Column::CreationInfo),
81 Self::ID_STATE => Some(Column::State),
82 _ => None,
83 }
84 }
85
86 pub fn name(&self) -> String {
87 translate_column(self.id(), self.default_name())
88 }
89}
90
91impl TableColumn<AccessPoint> for Column {
92 fn name(&self) -> &str {
93 Box::leak(translate_column(self.id(), self.default_name()).into_boxed_str())
94 }
95
96 fn width(&self) -> u16 {
97 let translated = translate_column(self.id(), self.default_name());
98 translated.len().max(match self {
99 Column::Name => 24,
100 Column::AccessPointId => 22,
101 Column::Path => 24,
102 Column::PosixUser => 14,
103 Column::CreationInfo => 22,
104 Column::State => 14,
105 }) as u16
106 }
107
108 fn render(&self, item: &AccessPoint) -> (String, Style) {
109 match self {
110 Column::Name => (item.name.clone(), Style::default()),
111 Column::AccessPointId => (item.access_point_id.clone(), Style::default()),
112 Column::Path => (item.path.clone(), Style::default()),
113 Column::PosixUser => (item.posix_user.clone(), Style::default()),
114 Column::CreationInfo => (item.creation_info.clone(), Style::default()),
115 Column::State => {
116 let (text, color) = format_state(&item.life_cycle_state);
117 (text.to_string(), Style::default().fg(color))
118 }
119 }
120 }
121}
122
123fn format_state(state: &str) -> (&'static str, Color) {
124 match state {
125 "available" | "Available" | "AVAILABLE" => ("✅ Available", Color::Green),
126 "creating" | "Creating" | "CREATING" => ("⏳ Creating", Color::Yellow),
127 "deleting" | "Deleting" | "DELETING" => ("🗑 Deleting", Color::Red),
128 "deleted" | "Deleted" | "DELETED" => ("🗑 Deleted", Color::Red),
129 "updating" | "Updating" | "UPDATING" => ("🔄 Updating", Color::Yellow),
130 "error" | "Error" | "ERROR" => ("⚠ Error", Color::Red),
131 _ => ("Unknown", Color::White),
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_ap_column_ids_have_prefix() {
141 for col in Column::all() {
142 assert!(col.id().starts_with("column.efs.ap."));
143 }
144 }
145
146 #[test]
147 fn test_ap_from_id_roundtrip() {
148 for col in Column::all() {
149 assert_eq!(Column::from_id(col.id()), Some(col));
150 }
151 }
152
153 #[test]
154 fn test_ap_all_six_columns_visible_by_default() {
155 assert_eq!(Column::all().len(), 6);
156 assert_eq!(Column::default_visible_ids().len(), 6);
157 }
158}