From f03c3f1de9ddf47844d3cf02ddca2c282f7e3465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Furkan=20T=C3=BCrkal?= Date: Thu, 7 Jan 2021 21:04:06 +0300 Subject: [PATCH] feat(command): add 'toggle' command (#1917) Closes #894 Signed-off-by: Dentrax --- src/configure.rs | 75 +++++++++++++++++++++++++++++++++++++++--------- src/main.rs | 34 ++++++++++++++++++---- 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index bb70c88cb..48f765aa9 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -8,6 +8,7 @@ use crate::config::StarshipConfig; use std::fs::File; use std::io::Write; use toml::map::Map; +use toml::value::Table; use toml::Value; #[cfg(not(windows))] @@ -16,20 +17,13 @@ const STD_EDITOR: &str = "vi"; const STD_EDITOR: &str = "notepad.exe"; pub fn update_configuration(name: &str, value: &str) { - let config_path = get_config_path(); - let keys: Vec<&str> = name.split('.').collect(); if keys.len() != 2 { log::error!("Please pass in a config key with a '.'"); process::exit(1); } - let starship_config = StarshipConfig::initialize(); - let mut config = starship_config - .config - .expect("Failed to load starship config"); - - if let Some(table) = config.as_table_mut() { + if let Some(table) = get_configuration().as_table_mut() { if !table.contains_key(keys[0]) { table.insert(keys[0].to_string(), Value::Table(Map::new())); } @@ -54,14 +48,68 @@ pub fn update_configuration(name: &str, value: &str) { table.insert(keys[0].to_string(), Value::Table(updated_values)); } - let config_str = - toml::to_string_pretty(&table).expect("Failed to serialize the config to string"); - File::create(&config_path) - .and_then(|mut file| file.write_all(config_str.as_ref())) - .expect("Error writing starship config"); + write_configuration(table); } } +pub fn toggle_configuration(name: &str, key: &str) { + if let Some(table) = get_configuration().as_table_mut() { + match table.get(name) { + Some(v) => { + if let Some(values) = v.as_table() { + let mut updated_values = values.clone(); + + let current: bool = match updated_values.get(key) { + Some(v) => match v.as_bool() { + Some(b) => b, + _ => { + log::error!( + "Given config key '{}' must be in 'boolean' format", + key + ); + process::exit(1); + } + }, + _ => { + log::error!("Given config key '{}' must be exist in config file", key); + process::exit(1); + } + }; + + updated_values.insert(key.to_string(), Value::Boolean(!current)); + + table.insert(name.to_string(), Value::Table(updated_values)); + + write_configuration(table); + } + } + _ => { + log::error!("Given module '{}' not found in config file", name); + process::exit(1); + } + }; + } +} + +pub fn get_configuration() -> Value { + let starship_config = StarshipConfig::initialize(); + + starship_config + .config + .expect("Failed to load starship config") +} + +pub fn write_configuration(table: &mut Table) { + let config_path = get_config_path(); + + let config_str = + toml::to_string_pretty(&table).expect("Failed to serialize the config to string"); + + File::create(&config_path) + .and_then(|mut file| file.write_all(config_str.as_ref())) + .expect("Error writing starship config"); +} + pub fn edit_configuration() { let config_path = get_config_path(); let editor_cmd = shell_words::split(&get_editor()).expect("Unmatched quotes found in $EDITOR."); @@ -119,7 +167,6 @@ mod tests { use super::*; // This is every possible permutation, 3² = 9. - #[test] fn visual_set_editor_set() { let actual = get_editor_internal(Some("foo".into()), Some("bar".into())); diff --git a/src/main.rs b/src/main.rs index a31294098..1224e08a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,11 +29,11 @@ fn main() { .takes_value(true); let shell_arg = Arg::with_name("shell") - .value_name("SHELL") - .help( - "The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion", - ) - .required(true); + .value_name("SHELL") + .help( + "The name of the currently running shell\nCurrently supported options: bash, zsh, fish, powershell, ion", + ) + .required(true); let cmd_duration_arg = Arg::with_name("cmd_duration") .short("d") @@ -117,6 +117,21 @@ fn main() { ) .arg(Arg::with_name("value").help("Value to place into that key")), ) + .subcommand( + SubCommand::with_name("toggle") + .about("Toggle a given starship module") + .arg( + Arg::with_name("name") + .help("The name of the module to be toggled") + .required(true), + ) + .arg( + Arg::with_name("key") + .help("The key of the config to be toggled") + .required(false) + .required_unless("name"), + ), + ) .subcommand( SubCommand::with_name("bug-report").about( "Create a pre-populated GitHub issue with information about your configuration", @@ -179,6 +194,15 @@ fn main() { configure::edit_configuration() } } + ("toggle", Some(sub_m)) => { + if let Some(name) = sub_m.value_of("name") { + if let Some(value) = sub_m.value_of("key") { + configure::toggle_configuration(name, value) + } else { + configure::toggle_configuration(name, "disabled") + } + } + } ("bug-report", Some(_)) => bug_report::create(), ("time", _) => { match SystemTime::now()