diff --git a/src/controller.rs b/src/controller.rs index 58eade1..ea984f9 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -1,4 +1,4 @@ -use crate::model::{AppState, AppStateFullView}; +use crate::model::{AppState, AppStateFullView, Service, ServiceStatus}; use crate::{view, App}; use crossterm::event; use crossterm::event::{Event, KeyCode}; @@ -33,9 +33,18 @@ impl App { table: AppState { table_state: TableState::default(), items: vec![ - vec!["backend".to_string(), "running".to_string()], - vec!["frontend".to_string(), "exited (0)".to_string()], - vec!["database".to_string(), "failed (1)".to_string()], + Service { + name: "backend".to_string(), + status: ServiceStatus::Running, + }, + Service { + name: "frontend".to_string(), + status: ServiceStatus::Exited, + }, + Service { + name: "database".to_string(), + status: ServiceStatus::Failed(1), + }, ], }, selected: None, @@ -49,9 +58,7 @@ impl App { fn select_service(&mut self) { if self.is_table() { if let Some(selected) = self.table.table_state.selected() { - self.selected = Some(AppStateFullView { - name: self.table.items[selected][0].to_string(), - }); + self.selected = Some(AppStateFullView { index: selected }); } } } diff --git a/src/model.rs b/src/model.rs index 73f4848..6b80025 100644 --- a/src/model.rs +++ b/src/model.rs @@ -3,16 +3,29 @@ use tui::widgets::TableState; #[derive(Debug)] pub struct App { pub table: AppState, - pub selected: Option + pub selected: Option, } #[derive(Debug)] pub struct AppState { pub table_state: TableState, - pub items: Vec>, + pub items: Vec, } #[derive(Debug)] pub struct AppStateFullView { - pub name: String, + pub index: usize, +} + +#[derive(Debug)] +pub struct Service { + pub name: String, + pub status: ServiceStatus, +} + +#[derive(Debug)] +pub enum ServiceStatus { + Running, + Exited, + Failed(u8), } diff --git a/src/view.rs b/src/view.rs index d903170..a59d8eb 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,3 +1,4 @@ +use std::fmt::{Display, Formatter}; use tui::backend::Backend; use tui::layout::{Constraint, Layout, Rect}; use tui::style::{Color, Modifier, Style}; @@ -5,7 +6,7 @@ use tui::text::Spans; use tui::widgets::{Block, Borders, Cell, Paragraph, Row, Table}; use tui::Frame; -use crate::model::{AppState, AppStateFullView}; +use crate::model::{AppState, AppStateFullView, ServiceStatus}; use crate::App; pub fn render_ui(f: &mut Frame, app: &mut App) { @@ -23,10 +24,14 @@ pub fn render_ui(f: &mut Frame, app: &mut App) { None => { render_table(f, &mut app.table, chunks[0]); } - Some(AppStateFullView { ref name }) => f.render_widget( - Block::default().borders(Borders::ALL).title(name.as_ref()), - chunks[0], - ), + Some(AppStateFullView { index }) => { + let name = &app.table.items[index].name; + + f.render_widget( + Block::default().borders(Borders::ALL).title(name.as_ref()), + chunks[0], + ) + } } if let Some(footer_chunk) = chunks.get(1) { @@ -46,14 +51,12 @@ fn render_table(f: &mut Frame, state: &mut AppState, area: Rect) .height(1) .bottom_margin(1); - let rows = state.items.iter().map(|item| { - let height = item - .iter() - .map(|content| content.chars().filter(|c| *c == '\n').count()) - .max() - .unwrap_or(0) - + 1; - let cells = item.iter().map(|c| Cell::from(c.as_ref())); + let rows = state.items.iter().map(|service| { + let height = service.name.chars().filter(|c| *c == '\n').count() + 1; + let cells = [ + Cell::from(service.name.as_ref()), + Cell::from(service.status.to_string()), + ]; Row::new(cells).height(height as u16).bottom_margin(1) }); @@ -66,7 +69,7 @@ fn render_table(f: &mut Frame, state: &mut AppState, area: Rect) f.render_stateful_widget(t, area, &mut state.table_state); } -pub fn render_help_footer(f: &mut Frame, app: &App, area: Rect) { +fn render_help_footer(f: &mut Frame, app: &App, area: Rect) { let block = Block::default().title("help").borders(Borders::ALL); let paragraph = Paragraph::new(if app.is_table() { @@ -78,3 +81,13 @@ pub fn render_help_footer(f: &mut Frame, app: &App, area: Rect) { f.render_widget(paragraph, area); } + +impl Display for ServiceStatus { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ServiceStatus::Running => f.write_str("running"), + ServiceStatus::Exited => f.write_str("exited (0)"), + ServiceStatus::Failed(code) => write!(f, "failed ({})", code), + } + } +}