diff --git a/src/toolbx/mod.rs b/src/toolbx/mod.rs index b8408e5..e5f783c 100644 --- a/src/toolbx/mod.rs +++ b/src/toolbx/mod.rs @@ -1,11 +1,55 @@ -use std::{iter::zip, process::Command, sync::Arc, fmt::Result, string::ParseError}; +use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc}; + +#[derive(Debug)] +pub enum ToolbxError { + ParseStatusError(String), +} + +impl std::error::Error for ToolbxError {} + +impl Display for ToolbxError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ToolbxError::ParseStatusError(parse_int_error) => write!(f, "{}", parse_int_error), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum ToolbxStatus { + Running, + Configured, + Exited, +} + +impl Default for ToolbxStatus { + fn default() -> Self { + ToolbxStatus::Configured + } +} + +impl FromStr for ToolbxStatus { + type Err = ToolbxError; + + fn from_str(s: &str) -> Result { + match s { + "running" => Ok(ToolbxStatus::Running), + "configured" => Ok(ToolbxStatus::Configured), + "exited" => Ok(ToolbxStatus::Exited), + s => Err(ToolbxError::ParseStatusError(format!( + "'{}' is not a valid toolbx status.", + s + ))), + } + } +} #[derive(Debug, PartialEq, Default)] pub struct ToolbxContainer { pub id: String, pub name: String, pub created: String, - pub status: String, + pub status: ToolbxStatus, pub image: String, } @@ -17,10 +61,10 @@ impl ToolbxContainer { } pub fn stop(self) { - todo!{} + todo! {} } pub fn start(self) { - todo!{} + todo! {} } } @@ -96,18 +140,18 @@ fn test_tokenize_line_list_containers() { assert_eq!(target, result); } -fn parse_line_list_containers(line: &str) -> ToolbxContainer { +fn parse_line_list_containers(line: &str) -> Result { let tokens = tokenize_line_list_containers(line); if tokens.len() != 5 { panic! {"Expected 5 tokens found {} in {:?}", tokens.len(), tokens}; } - ToolbxContainer { + Ok(ToolbxContainer { id: tokens[0].clone(), name: tokens[1].clone(), created: tokens[2].clone(), - status: tokens[3].clone(), + status: ToolbxStatus::from_str(&tokens[3])?, image: tokens[4].clone(), - } + }) } #[test] @@ -119,17 +163,17 @@ fn test_parse_line_list_containers() { id: "ae05203091ab".to_string(), name: "rust".to_string(), created: "4 months ago".to_string(), - status: "running".to_string(), + status: ToolbxStatus::Running, image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), }; let result = parse_line_list_containers(toolbox_cmd_container_header); - assert_eq!(target, result); + assert_eq!(target, result.unwrap()); } fn parse_cmd_list_containers(output: &str) -> Vec { let lines = output.trim().split("\n").skip(1); println!("{:?}", lines); - lines.map(parse_line_list_containers).collect() + lines.map(parse_line_list_containers).flatten().collect() } #[test] @@ -147,21 +191,21 @@ fn test_parse_cmd_list_containers() { id: "cee1002b5f0b".to_string(), name: "fedora-toolbox-35".to_string(), created: "2 months ago".to_string(), - status: "exited".to_string(), + status: ToolbxStatus::Exited, image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), }, ToolbxContainer { id: "9b611313bf65".to_string(), name: "latex".to_string(), created: "4 months ago".to_string(), - status: "configured".to_string(), + status: ToolbxStatus::Configured, image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), }, ToolbxContainer { id: "ae05203091ab".to_string(), name: "rust".to_string(), created: "4 months ago".to_string(), - status: "running".to_string(), + status: ToolbxStatus::Running, image: "registry.fedoraproject.org/fedora-toolbox:35".to_string(), }, ]; diff --git a/src/ui/app/toolbox_list.rs b/src/ui/app/toolbox_list.rs index fa484a3..7a3f078 100644 --- a/src/ui/app/toolbox_list.rs +++ b/src/ui/app/toolbox_list.rs @@ -8,14 +8,15 @@ use relm4::{ gtk, send, view, Sender, }; -use crate::{ui::{ - ui_strings::{ +use crate::{ + toolbx::{ToolbxContainer, ToolbxStatus}, + ui::ui_strings::{ APP_ICON, APP_TOOLTIP, SETTINGS_ICON, SETTINGS_TOOLTIP, SHUTDOWN_ICON, SHUTDOWN_TOOLTIP, START_ICON, START_TOOLTIP, TERMINAL_ICON, TERMINAL_TOOLTIP, UPDATE_ICON, UPDATE_TOOLTIP, }, -}, toolbx::ToolbxContainer}; +}; -use super::{messages::AppMsg}; +use super::messages::AppMsg; #[derive(Debug)] pub struct FactoryWidgets { @@ -36,7 +37,7 @@ impl FactoryPrototype for ToolbxContainer { ) -> Self::Widgets { view! { suffix_box = >k::Box{ - append = >k::AspectFrame{ + append = >k::AspectFrame{ set_ratio: 1.0, set_child = Some(>k::Button::from_icon_name(APP_ICON)) { set_margin_start: 10, @@ -49,7 +50,7 @@ impl FactoryPrototype for ToolbxContainer { }, } }, - append = >k::AspectFrame{ + append = >k::AspectFrame{ set_ratio: 1.0, set_child = Some(>k::Button::from_icon_name(TERMINAL_ICON)) { set_margin_start: 10, @@ -59,7 +60,7 @@ impl FactoryPrototype for ToolbxContainer { set_css_classes: &["flat"], } }, - append = >k::AspectFrame{ + append = >k::AspectFrame{ set_ratio: 1.0, set_child = Some(>k::Button::from_icon_name(SETTINGS_ICON)) { set_margin_start: 10,set_margin_start: 10, @@ -75,10 +76,10 @@ impl FactoryPrototype for ToolbxContainer { } }; - /* + /* if self.update_available { view! { - update_button = >k::AspectFrame{ + update_button = >k::AspectFrame{ set_ratio: 1.0, set_child = Some(>k::Button::from_icon_name(UPDATE_ICON)) { set_margin_top: 10, @@ -96,8 +97,8 @@ impl FactoryPrototype for ToolbxContainer { let mut status_button_tooltip = START_TOOLTIP; let mut status_button_icon = START_ICON; - match self.status.as_str() { - "running" => { + match self.status { + ToolbxStatus::Running => { status_button_tooltip = SHUTDOWN_TOOLTIP; status_button_icon = SHUTDOWN_ICON; } @@ -114,7 +115,7 @@ impl FactoryPrototype for ToolbxContainer { set_title: &self.name, set_subtitle: subtitle.as_str(), add_prefix = >k::Box { - append = >k::AspectFrame{ + append = >k::AspectFrame{ set_ratio: 1.0, set_child = Some(>k::Button::from_icon_name(status_button_icon)) { set_margin_top: 10, @@ -126,7 +127,7 @@ impl FactoryPrototype for ToolbxContainer { }, add_suffix: &suffix_box, } - + }; FactoryWidgets { action_row } }