diff --git a/core/src/config.rs b/core/src/config.rs index d4f5e5c5..8c874101 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -1,14 +1,31 @@ use serde::Deserialize; use std::path::Path; use std::process; +use std::rc::Rc; +use crate::{ListNode, TabList}; + +// Struct that defines what values can be used in the toml file #[derive(Deserialize)] +#[serde(deny_unknown_fields)] pub struct Config { - pub auto_execute: Vec, + #[serde(default)] + auto_execute: Option>, + #[serde(default)] + skip_confirmation: Option, + #[serde(default)] + size_bypass: Option, +} + +// Struct that holds the parsed values from the toml so that it can be applied in the AppState +pub struct ConfigValues { + pub auto_execute_commands: Vec>, + pub skip_confirmation: bool, + pub size_bypass: bool, } impl Config { - pub fn from_file(path: &Path) -> Self { + pub fn new(path: &Path, tabs: &TabList) -> ConfigValues { let content = match std::fs::read_to_string(path) { Ok(content) => content, Err(e) => { @@ -17,12 +34,29 @@ impl Config { } }; - match toml::from_str(&content) { + let config: Config = match toml::from_str(&content) { Ok(config) => config, Err(e) => { eprintln!("Failed to parse config file: {}", e); process::exit(1); } + }; + + ConfigValues { + auto_execute_commands: config.auto_execute_commands(tabs), + skip_confirmation: config.skip_confirmation.unwrap_or(false), + size_bypass: config.size_bypass.unwrap_or(false), } } + + fn auto_execute_commands(&self, tabs: &TabList) -> Vec> { + self.auto_execute + .as_ref() + .map_or_else(Vec::new, |commands| { + commands + .iter() + .filter_map(|name| tabs.iter().find_map(|tab| tab.find_command(name))) + .collect() + }) + } } diff --git a/core/src/lib.rs b/core/src/lib.rs index 986d9ac1..ee8eb89a 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -7,7 +7,7 @@ pub use ego_tree; use ego_tree::Tree; use std::path::PathBuf; -pub use config::Config; +pub use config::{Config, ConfigValues}; pub use inner::{get_tabs, TabList}; #[derive(Clone, Hash, Eq, PartialEq)] diff --git a/tui/src/state.rs b/tui/src/state.rs index 7f96aee9..a2614264 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -9,7 +9,7 @@ use crate::{ theme::Theme, }; -use linutil_core::{ego_tree::NodeId, Config, ListNode, TabList}; +use linutil_core::{ego_tree::NodeId, Config, ConfigValues, ListNode, TabList}; #[cfg(feature = "tips")] use rand::Rng; use ratatui::{ @@ -105,8 +105,6 @@ impl AppState { let tabs = linutil_core::get_tabs(!override_validation); let root_id = tabs[0].tree.root().id(); - let auto_execute_commands = config_path.map(|path| Config::from_file(&path).auto_execute); - let mut state = Self { areas: None, theme, @@ -131,28 +129,38 @@ impl AppState { } state.update_items(); - if let Some(auto_execute_commands) = auto_execute_commands { - state.handle_initial_auto_execute(&auto_execute_commands); + + if let Some(config_path) = config_path { + let config = Config::new(&config_path, &state.tabs); + state.apply_config(config); } state } - fn handle_initial_auto_execute(&mut self, auto_execute_commands: &[String]) { - self.selected_commands = auto_execute_commands - .iter() - .filter_map(|name| self.tabs.iter().find_map(|tab| tab.find_command(name))) - .collect(); + fn apply_config(&mut self, config_values: ConfigValues) { + self.skip_confirmation = config_values.skip_confirmation; + self.size_bypass = config_values.size_bypass; + if !config_values.auto_execute_commands.is_empty() { + self.selected_commands = config_values.auto_execute_commands; + self.handle_initial_auto_execute(); + } + } + fn handle_initial_auto_execute(&mut self) { if !self.selected_commands.is_empty() { - let cmd_names: Vec<_> = self - .selected_commands - .iter() - .map(|node| node.name.as_str()) - .collect(); + if !self.skip_confirmation { + let cmd_names: Vec<_> = self + .selected_commands + .iter() + .map(|node| node.name.as_str()) + .collect(); - let prompt = ConfirmPrompt::new(&cmd_names); - self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40)); + let prompt = ConfirmPrompt::new(&cmd_names); + self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40)); + } else { + self.handle_confirm_command(); + } } }