use crate::utils; use std::env; use dirs::home_dir; use toml::value::Table; pub trait Config { fn initialize() -> Table; fn config_from_file() -> Option; fn get_module_config(&self, module_name: &str) -> Option<&Table>; // Config accessor methods fn get_as_bool(&self, key: &str) -> Option; fn get_as_str(&self, key: &str) -> Option<&str>; fn get_as_i64(&self, key: &str) -> Option; // Internal implementation for accessors fn get_config(&self, key: &str) -> Option<&toml::value::Value>; } impl Config for Table { /// Initialize the Config struct fn initialize() -> Table { if let Some(file_data) = Table::config_from_file() { return file_data; } Table::new() } /// Create a config from a starship configuration file fn config_from_file() -> Option
{ let file_path = match env::var("STARSHIP_CONFIG") { Ok(path) => { // Use $STARSHIP_CONFIG as the config path if available log::debug!("STARSHIP_CONFIG is set: \n{}", &path); path } Err(_) => { // Default to using ~/.config/starhip.toml log::debug!("STARSHIP_CONFIG is not set"); let config_path = home_dir()?.join(".config/starship.toml"); let config_path_str = config_path.to_str()?.to_owned(); log::debug!("Using default config path: {}", config_path_str); config_path_str } }; let toml_content = match utils::read_file(&file_path) { Ok(content) => { log::trace!("Config file content: \n{}", &content); Some(content) } Err(e) => { log::debug!("Unable to read config file content: \n{}", &e); None } }?; let config = toml::from_str(&toml_content).ok()?; log::debug!("Config parsed: \n{:?}", &config); Some(config) } /// Get the subset of the table for a module by its name fn get_module_config(&self, module_name: &str) -> Option<&toml::value::Table> { let module_config = self .get(module_name) .map(toml::Value::as_table) .unwrap_or(None); if module_config.is_some() { log::debug!( "Config found for \"{}\": \n{:?}", &module_name, &module_config ); } else { log::trace!("No config found for \"{}\"", &module_name); } module_config } /// Get the config value for a given key fn get_config(&self, key: &str) -> Option<&toml::value::Value> { log::trace!("Looking for config key \"{}\"", key); let config_value = self.get(key); if config_value.is_some() { log::trace!("Config found for \"{}\": {:?}", key, &config_value); } else { log::trace!("No value found for \"{}\"", key); } config_value } /// Get a key from a module's configuration as a boolean fn get_as_bool(&self, key: &str) -> Option { let value = self.get_config(key)?; let bool_value = value.as_bool(); if bool_value.is_none() { log::debug!( "Expected \"{}\" to be a boolean. Instead received {} of type {}.", key, value, value.type_str() ); } bool_value } /// Get a key from a module's configuration as a string fn get_as_str(&self, key: &str) -> Option<&str> { let value = self.get_config(key)?; let str_value = value.as_str(); if str_value.is_none() { log::debug!( "Expected \"{}\" to be a string. Instead received {} of type {}.", key, value, value.type_str() ); } str_value } /// Get a key from a module's configuration as an integer fn get_as_i64(&self, key: &str) -> Option { let value = self.get_config(key)?; let i64_value = value.as_integer(); if i64_value.is_none() { log::debug!( "Expected \"{}\" to be an integer. Instead received {} of type {}.", key, value, value.type_str() ); } i64_value } } mod tests { use super::*; #[test] fn table_get_as_bool() { let mut table = toml::value::Table::new(); // Use with boolean value table.insert(String::from("boolean"), toml::value::Value::Boolean(true)); assert_eq!(table.get_as_bool("boolean"), Some(true)); // Use with string value table.insert( String::from("string"), toml::value::Value::String(String::from("true")), ); assert_eq!(table.get_as_bool("string"), None); } #[test] fn table_get_as_str() { let mut table = toml::value::Table::new(); // Use with string value table.insert( String::from("string"), toml::value::Value::String(String::from("hello")), ); assert_eq!(table.get_as_str("string"), Some("hello")); // Use with boolean value table.insert(String::from("boolean"), toml::value::Value::Boolean(true)); assert_eq!(table.get_as_str("boolean"), None); } #[test] fn table_get_as_i64() { let mut table = toml::value::Table::new(); // Use with integer value table.insert(String::from("integer"), toml::value::Value::Integer(82)); assert_eq!(table.get_as_i64("integer"), Some(82)); // Use with string value table.insert( String::from("string"), toml::value::Value::String(String::from("82")), ); assert_eq!(table.get_as_bool("string"), None); } }