diff options
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | ci/azure-test-docker.yml | 6 | ||||
-rw-r--r-- | ci/azure-test-stable.yml | 9 | ||||
-rwxr-xr-x | integration_test | 2 | ||||
-rw-r--r-- | src/config.rs | 42 | ||||
-rw-r--r-- | src/context.rs | 11 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/module.rs | 33 | ||||
-rw-r--r-- | src/modules/battery.rs | 4 | ||||
-rw-r--r-- | src/modules/character.rs | 4 | ||||
-rw-r--r-- | src/modules/directory.rs | 4 | ||||
-rw-r--r-- | src/modules/git_branch.rs | 4 | ||||
-rw-r--r-- | src/modules/git_status.rs | 4 | ||||
-rw-r--r-- | src/modules/go.rs | 4 | ||||
-rw-r--r-- | src/modules/line_break.rs | 4 | ||||
-rw-r--r-- | src/modules/mod.rs | 2 | ||||
-rw-r--r-- | src/modules/nodejs.rs | 4 | ||||
-rw-r--r-- | src/modules/package.rs | 70 | ||||
-rw-r--r-- | src/modules/python.rs | 11 | ||||
-rw-r--r-- | src/modules/rust.rs | 4 | ||||
-rw-r--r-- | src/modules/username.rs | 4 | ||||
-rw-r--r-- | src/segment.rs | 65 | ||||
-rw-r--r-- | src/utils.rs | 11 | ||||
-rw-r--r-- | tests/Dockerfile | 41 | ||||
-rw-r--r-- | tests/testsuite/directory.rs | 4 | ||||
-rw-r--r-- | tests/testsuite/username.rs | 21 |
27 files changed, 196 insertions, 182 deletions
@@ -57,7 +57,7 @@ I'm very new to Rust, so any help is appreciated when it comes to improving deve ### Other features -- [ ] `.starshiprc` configuration (JSON or TOML) +- [x] `starship.toml` configuration - [ ] Custom sections given commands or binaries - [ ] Self-updating @@ -69,9 +69,9 @@ I'm very new to Rust, so any help is appreciated when it comes to improving deve ### Test strategy -- [x] Per-segment benchmarking +- [ ] Per-segment benchmarking - [x] Per-segment unit + integration tests -- [ ] Shell + OS matrix acceptance tests +- [x] Shell + OS matrix acceptance tests ## Setup diff --git a/ci/azure-test-docker.yml b/ci/azure-test-docker.yml index 22df04cb5..99a7d5078 100644 --- a/ci/azure-test-docker.yml +++ b/ci/azure-test-docker.yml @@ -8,7 +8,11 @@ jobs: - script: docker pull starshipcommand/starship-test displayName: Pull docker image - - script: ./integration_test + - script: | + # In order to run tests as a non-root user in docker, + # the files need to be accessible to non-root users + chmod -R a+w . + ./integration_test displayName: Run integration test suite - script: | diff --git a/ci/azure-test-stable.yml b/ci/azure-test-stable.yml index 031b69399..9c445bf5e 100644 --- a/ci/azure-test-stable.yml +++ b/ci/azure-test-stable.yml @@ -7,8 +7,10 @@ jobs: vmImage: ubuntu-16.04 MacOS: vmImage: macOS-10.13 - Windows: - vmImage: vs2017-win2016 + # # Temporarily disabling Windows tests while I'm away + # # Will reenable Windows tests once I'm able to troubleshoot Windows bugs + # Windows: + # vmImage: vs2017-win2016 pool: vmImage: $(vmImage) @@ -19,5 +21,6 @@ jobs: - template: azure-setup-test-env.yml - - script: cargo test -- --ignored + # "-Z unstable-options" is required for "--include-ignored" + - script: cargo test -- -Z unstable-options --include-ignored displayName: cargo test diff --git a/integration_test b/integration_test index cf91a2134..93a6466df 100755 --- a/integration_test +++ b/integration_test @@ -13,4 +13,4 @@ docker build -f tests/Dockerfile \ . printf 'Running test suite:\n' -docker run --rm -v $(pwd):/starship starshipcommand/starship-test +docker run --rm -v $(pwd):/src/starship starshipcommand/starship-test diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 000000000..7c0509a2b --- /dev/null +++ b/src/config.rs @@ -0,0 +1,42 @@ +use crate::utils; + +use dirs::home_dir; + +pub struct Config { + data: toml::value::Table, +} + +impl Config { + /// Initialize the Config struct + pub fn initialize() -> Config { + if let Some(file_data) = Config::config_from_file() { + return Config { data: file_data }; + } + + Config { + data: toml::value::Table::new(), + } + } + + /// Create a config from a starship configuration file + fn config_from_file() -> Option<toml::value::Table> { + let file_path = home_dir()?.join(".config/starship.toml"); + let toml_content = utils::read_file(&file_path.to_str()?).ok()?; + log::trace!("Config file content: \n{}", &toml_content); + + let config = toml::from_str(&toml_content).ok()?; + log::debug!("Config found: \n{:?}", &config); + Some(config) + } + + /// Get the subset of the table for a module by its name + pub fn get_module_config(&self, module_name: &str) -> Option<&toml::value::Table> { + let module_config = self + .data + .get(module_name) + .map(toml::Value::as_table) + .unwrap_or(None); + log::debug!("Config found for {}: {:?}", &module_name, &module_config); + module_config + } +} diff --git a/src/context.rs b/src/context.rs index e0e7e286c..fd0ccc825 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,3 +1,6 @@ +use crate::config::Config; +use crate::module::Module; + use clap::ArgMatches; use git2::Repository; use std::env; @@ -6,6 +9,7 @@ use std::fs; use std::path::PathBuf; pub struct Context<'a> { + pub config: Config, pub current_dir: PathBuf, pub dir_files: Vec<PathBuf>, pub arguments: ArgMatches<'a>, @@ -28,6 +32,8 @@ impl<'a> Context<'a> { where T: Into<PathBuf>, { + let config = Config::initialize(); + // TODO: Currently gets the physical directory. Get the logical directory. let current_dir = Context::expand_tilde(dir.into()); @@ -51,6 +57,7 @@ impl<'a> Context<'a> { .and_then(|repo| get_current_branch(&repo)); Context { + config, arguments, current_dir, dir_files, @@ -68,6 +75,10 @@ impl<'a> Context<'a> { dir } + pub fn new_module(&self, name: &str) -> Module { + Module::new(name, self.config.get_module_config(name)) + } + // returns a new ScanDir struct with reference to current dir_files of context // see ScanDir for methods pub fn new_scan_dir(&'a self) -> ScanDir<'a> { diff --git a/src/lib.rs b/src/lib.rs index 078fcd021..b8bef9afb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ // Lib is present to allow for benchmarking +mod config; pub mod context; pub mod module; pub mod modules; pub mod print; pub mod segment; +mod utils; diff --git a/src/main.rs b/src/main.rs index 4707cd816..70f68e2e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,13 @@ #[macro_use] extern crate clap; +mod config; mod context; mod module; mod modules; mod print; mod segment; +mod utils; use clap::{App, Arg, SubCommand}; diff --git a/src/module.rs b/src/module.rs index 43ff78c1e..604258e19 100644 --- a/src/module.rs +++ b/src/module.rs @@ -6,7 +6,10 @@ use std::string::ToString; /// A module is a collection of segments showing data for a single integration /// (e.g. The git module shows the current git branch and status) -pub struct Module { +pub struct Module<'a> { + /// The module's configuration map if available + config: Option<&'a toml::value::Table>, + /// The module's name, to be used in configuration and logging. name: String, @@ -23,10 +26,11 @@ pub struct Module { suffix: ModuleAffix, } -impl Module { +impl<'a> Module<'a> { /// Creates a module with no segments. - pub fn new(name: &str) -> Module { + pub fn new(name: &str, config: Option<&'a toml::value::Table>) -> Module<'a> { Module { + config, name: name.to_string(), style: Style::default(), prefix: ModuleAffix::default_prefix(name.to_string()), @@ -42,7 +46,8 @@ impl Module { { let mut segment = Segment::new(name); segment.set_style(self.style); - segment.set_value(value.into()); + // Use the provided value unless overwritten by config + segment.set_value(self.config_value(name).unwrap_or_else(|| value.into())); self.segments.push(segment); self.segments.last_mut().unwrap() @@ -66,7 +71,7 @@ impl Module { /// Sets the style of the segment. /// /// Accepts either `Color` or `Style`. - pub fn set_style<T>(&mut self, style: T) -> &mut Module + pub fn set_style<T>(&mut self, style: T) -> &mut Module<'a> where T: Into<Style>, { @@ -80,8 +85,7 @@ impl Module { let mut ansi_strings = self .segments .iter() - .map(|s| s.ansi_strings()) - .flat_map(|s| s.into_iter()) + .map(|s| s.ansi_string()) .collect::<Vec<ANSIString>>(); ansi_strings.insert(0, self.prefix.ansi_string()); @@ -93,9 +97,22 @@ impl Module { pub fn to_string_without_prefix(&self) -> String { ANSIStrings(&self.ansi_strings()[1..]).to_string() } + + /// Get a module's config value as a string + fn config_value(&self, key: &str) -> Option<String> { + self.config + // Find the config value by its key + .map(|config| config.get(key)) + .unwrap_or(None) + // Get the config value as a `&str` + .map(toml::Value::as_str) + .unwrap_or(None) + // Convert it to a String + .map(str::to_string) + } } -impl fmt::Display for Module { +impl<'a> fmt::Display for Module<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let ansi_strings = self.ansi_strings(); write!(f, "{}", ANSIStrings(&ansi_strings)) diff --git a/src/modules/battery.rs b/src/modules/battery.rs index f7f7a0e08..75ac1c554 100644 --- a/src/modules/battery.rs +++ b/src/modules/battery.rs @@ -3,7 +3,7 @@ use ansi_term::Color; use super::{Context, Module}; /// Creates a segment for the battery percentage and charging state -pub fn segment(_context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { const BATTERY_FULL: &str = "•"; const BATTERY_CHARGING: &str = "⇡"; const BATTERY_DISCHARGING: &str = "⇣"; @@ -22,7 +22,7 @@ pub fn segment(_context: &Context) -> Option<Module> { } // TODO: Set style based on percentage when threshold is modifiable - let mut module = Module::new("battery"); + let mut module = context.new_module("battery"); module.set_style(Color::Red.bold()); module.get_prefix().set_value(""); diff --git a/src/modules/character.rs b/src/modules/character.rs index 1dfc27991..1a55cf78f 100644 --- a/src/modules/character.rs +++ b/src/modules/character.rs @@ -9,12 +9,12 @@ use ansi_term::Color; /// (green by default) /// - If the exit-code was anything else, the arrow will be formatted with /// `COLOR_FAILURE` (red by default) -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { const PROMPT_CHAR: &str = "➜"; let color_success = Color::Green.bold(); let color_failure = Color::Red.bold(); - let mut module = Module::new("char"); + let mut module = context.new_module("char"); module.get_prefix().set_value(""); let symbol = module.new_segment("symbol", PROMPT_CHAR); diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 991378bbb..8e719c452 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -12,12 +12,12 @@ use super::{Context, Module}; /// /// **Truncation** /// Paths will be limited in length to `3` path components by default. -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { const HOME_SYMBOL: &str = "~"; const DIR_TRUNCATION_LENGTH: usize = 3; let module_color = Color::Cyan.bold(); - let mut module = Module::new("directory"); + let mut module = context.new_module("directory"); module.set_style(module_color); let current_dir = &context.current_dir; diff --git a/src/modules/git_branch.rs b/src/modules/git_branch.rs index 500cc10b8..010c4eccb 100644 --- a/src/modules/git_branch.rs +++ b/src/modules/git_branch.rs @@ -5,13 +5,13 @@ use super::{Context, Module}; /// Creates a segment with the Git branch in the current directory /// /// Will display the branch name if the current directory is a git repo -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let branch_name = context.branch_name.as_ref()?; const GIT_BRANCH_CHAR: &str = " "; let segment_color = Color::Purple.bold(); - let mut module = Module::new("git_branch"); + let mut module = context.new_module("git_branch"); module.set_style(segment_color); module.get_prefix().set_value("on "); diff --git a/src/modules/git_status.rs b/src/modules/git_status.rs index 453edd9a5..6db29ba12 100644 --- a/src/modules/git_status.rs +++ b/src/modules/git_status.rs @@ -17,7 +17,7 @@ use super::{Context, Module}; /// - `+` — A new file has been added to the staging area /// - `»` — A renamed file has been added to the staging area /// - `✘` — A file's deletion has been added to the staging area -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { // This is the order that the sections will appear in const GIT_STATUS_CONFLICTED: &str = "="; const GIT_STATUS_AHEAD: &str = "⇡"; @@ -35,7 +35,7 @@ pub fn segment(context: &Context) -> Option<Module> { let repository = Repository::open(repo_root).ok()?; let module_style = Color::Red.bold(); - let mut module = Module::new("git_status"); + let mut module = context.new_module("git_status"); module.get_prefix().set_value("[").set_style(module_style); module.get_suffix().set_value("] ").set_style(module_style); module.set_style(module_style); diff --git a/src/modules/go.rs b/src/modules/go.rs index 661f98800..e4b689aff 100644 --- a/src/modules/go.rs +++ b/src/modules/go.rs @@ -13,7 +13,7 @@ use super::{Context, Module}; /// - Current directory contains a `Gopkg.lock` file /// - Current directory contains a `.go` file /// - Current directory contains a `Godeps` directory -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let is_go_project = context .new_scan_dir() .set_files(&["go.mod", "go.sum", "glide.yaml", "Gopkg.yml", "Gopkg.lock"]) @@ -30,7 +30,7 @@ pub fn segment(context: &Context) -> Option<Module> { const GO_CHAR: &str = "🐹 "; let module_color = Color::Cyan.bold(); - let mut module = Module::new("go"); + let mut module = context.new_module("go"); module.set_style(module_color); let formatted_version = format_go_version(go_version)?; diff --git a/src/modules/line_break.rs b/src/modules/line_break.rs index 223695dcf..0b11367ec 100644 --- a/src/modules/line_break.rs +++ b/src/modules/line_break.rs @@ -1,10 +1,10 @@ use super::{Context, Module}; /// Creates a segment for the line break -pub fn segment(_context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { const LINE_ENDING: &str = "\n"; - let mut module = Module::new("line_break"); + let mut module = context.new_module("line_break"); module.get_prefix().set_value(""); module.get_suffix().set_value(""); diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 808e33744..cf1c64018 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -14,7 +14,7 @@ mod username; use crate::context::Context; use crate::module::Module; -pub fn handle(module: &str, context: &Context) -> Option<Module> { +pub fn handle<'a>(module: &str, context: &'a Context) -> Option<Module<'a>> { match module { "dir" | "directory" => directory::segment(context), "char" | "character" => character::segment(context), diff --git a/src/modules/nodejs.rs b/src/modules/nodejs.rs index b9736687e..e542acf1e 100644 --- a/src/modules/nodejs.rs +++ b/src/modules/nodejs.rs @@ -9,7 +9,7 @@ use super::{Context, Module}; /// - Current directory contains a `.js` file /// - Current directory contains a `package.json` file /// - Current directory contains a `node_modules` directory -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let is_js_project = context .new_scan_dir() .set_files(&["package.json"]) @@ -26,7 +26,7 @@ pub fn segment(context: &Context) -> Option<Module> { const NODE_CHAR: &str = "⬢ "; let module_color = Color::Green.bold(); - let mut module = Module::new("node"); + let mut module = context.new_module("node"); module.set_style(module_color); let formatted_version = node_version.trim(); diff --git a/src/modules/package.rs b/src/modules/package.rs index b2666c8de..a9af63891 100644 --- a/src/modules/package.rs +++ b/src/modules/package.rs @@ -1,23 +1,20 @@ use super::{Context, Module}; +use crate::utils; use ansi_term::Color; -use serde_json; -use std::fs::File; -use std::io; -use std::io::Read; -use std::path::PathBuf; +use serde_json as json; use toml; /// Creates a segment with the current package version /// /// Will display if a version is defined for your Node.js or Rust project (if one exists) -pub fn segment(context: &Context) -> Option<Module> { - match get_package_version(context) { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { + match get_package_version() { Some(package_version) => { const PACKAGE_CHAR: &str = "📦 "; let module_color = Color::Red.bold(); - let mut module = Module::new("package"); + let mut module = context.new_module("package"); module.set_style(module_color); module.get_prefix().set_value("is "); @@ -30,27 +27,8 @@ pub fn segment(context: &Context) -> Option<Module> { } } -// TODO: Combine into one function and just call for different file names! -fn is_cargo_toml(dir_entry: &PathBuf) -> bool { - dir_entry.is_file() && dir_entry.file_name().unwrap_or_default() == "Cargo.toml" -} - -fn is_package_json(dir_entry: &PathBuf) -> bool { - dir_entry.is_file() && dir_entry.file_name().unwrap_or_default() == "package.json" -} - -// TODO: Move to `utils.rs` file and import -fn read_file(file_name: &str) -> io::Result<String> { - let mut file = File::open(file_name)?; - let mut data = String::new(); - - file.read_to_string(&mut data)?; - - Ok(data) -} - fn extract_cargo_version(file_contents: &str) -> Option<String> { - let cargo_toml = file_contents.parse::<toml::Value>().ok()?; + let cargo_toml: toml::Value = toml::from_str(&file_contents).ok()?; let raw_version = cargo_toml.get("package")?.get("version")?.as_str()?; let formatted_version = format_version(raw_version); @@ -58,7 +36,7 @@ fn extract_cargo_version(file_contents: &str) -> Option<String> { } fn extract_package_version(file_contents: &str) -> Option<String> { - let package_json: serde_json::Value = serde_json::from_str(&file_contents).ok()?; + let package_json: json::Value = json::from_str(&file_contents).ok()?; let raw_version = package_json.get("version")?.as_str()?; if raw_version == "null" { return None; @@ -68,17 +46,15 @@ fn extract_package_version(file_contents: &str) -> Option<String> { Some(formatted_version) } -fn get_package_version(context: &Context) -> Option<String> { - let has_cargo_toml = context.dir_files.iter().any(is_cargo_toml); - if has_cargo_toml { - let file_contents = read_file("Cargo.toml").ok()?; - return extract_cargo_version(&file_contents); +fn get_package_version() -> Option<String> { + let cargo_toml = utils::read_file("Cargo.toml"); + if let Ok(cargo_toml) = cargo_toml { + return extract_cargo_version(&cargo_toml); } - let has_package_json = context.dir_files.iter().any(is_package_json); - if has_package_json { - let file_contents = read_file("package.json").ok()?; - return extract_package_version(&file_contents); + let package_json = utils::read_file("package.json"); + if let Ok(package_json) = package_json { + return extract_package_version(&package_json); } None @@ -99,15 +75,19 @@ mod tests { #[test] fn test_extract_cargo_version() { - let cargo_with_version = "[package] - name = \"starship\" - version = \"0.1.0\""; + let cargo_with_version = r#" + [package] + name = "starship" + version = "0.1.0" + "#; let expected_version = Some("v0.1.0".to_string()); assert_eq!(extract_cargo_version(&cargo_with_version), expected_version); - let cargo_without_version = "[package] - name = \"starship\""; + let cargo_without_version = r#" + [package] + name = "starship" + "#; let expected_version = None; assert_eq!( @@ -118,7 +98,7 @@ mod tests { #[test] fn test_extract_package_version() { - let package_with_version = serde_json::json!({ + let package_with_version = json::json!({ "name": "spacefish", "version": "0.1.0" }) @@ -130,7 +110,7 @@ mod tests { expected_version ); - let package_without_version = serde_json::json!({ + let package_without_version = json::json!({ "name": "spacefish" }) .to_string(); diff --git a/src/modules/python.rs b/src/modules/python.rs index f19da3509..8b72e5187 100644 --- a/src/modules/python.rs +++ b/src/modules/python.rs @@ -10,15 +10,10 @@ use super::{Context, Module}; /// - Current directory contains a `.python-version` file /// - Current directory contains a `requirements.txt` file /// - Current directory contains a `pyproject.toml` file -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let is_py_project = context .new_scan_dir() - .set_files(&[ - "requirements.txt", - ".python-version", - "pyproject.toml", - "pyproject.toml", - ]) + .set_files(&["requirements.txt", ".python-version", "pyproject.toml"]) .set_extensions(&["py"]) .scan(); @@ -31,7 +26,7 @@ pub fn segment(context: &Context) -> Option<Module> { const PYTHON_CHAR: &str = "🐍 "; let module_color = Color::Yellow.bold(); - let mut module = Module::new("python"); + let mut module = context.new_module("python"); module.set_style(module_color); let formatted_version = format_python_version(python_version); diff --git a/src/modules/rust.rs b/src/modules/rust.rs index ab3679e76..9ccdcc5d2 100644 --- a/src/modules/rust.rs +++ b/src/modules/rust.rs @@ -8,7 +8,7 @@ use super::{Context, Module}; /// Will display the Rust version if any of the following criteria are met: /// - Current directory contains a file with a `.rs` extension /// - Current directory contains a `Cargo.toml` file -pub fn segment(context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let is_rs_project = context .new_scan_dir() .set_files(&["Cargo.toml"]) @@ -24,7 +24,7 @@ pub fn segment(context: &Context) -> Option<Module> { const RUST_CHAR: &str = "🦀 "; let module_color = Color::Red.bold(); - let mut module = Module::new("rust"); + let mut module = context.new_module("rust"); module.set_style(module_color); let formatted_version = format_rustc_version(rust_version); diff --git a/src/modules/username.rs b/src/modules/username.rs index 1e35ff679..8885791b9 100644 --- a/src/modules/username.rs +++ b/src/modules/username.rs @@ -10,7 +10,7 @@ use super::{Context, Module}; /// - The current user isn't the same as the one that is logged in ($LOGNAME != $USER) /// - The current user is root (UID = 0) /// - The user is currently connected as an SSH session ($SSH_CONNECTION) -pub fn segment(_context: &Context) -> Option<Module> { +pub fn segment<'a>(context: &'a Context) -> Option<Module<'a>> { let user = env::var("USER").ok(); let logname = env::var("LOGNAME").ok(); let ssh_connection = env::var("SSH_CONNECTION").ok(); @@ -18,7 +18,7 @@ pub fn segment(_context: &Context) -> Option<Module> { let mut module_color = Color::Yellow.bold(); if user != logname || ssh_connection.is_some() || is_root(&mut module_color) { - let mut module = Module::new("username"); + let mut module = context.new_module("username"); module.set_style(module_color); module.new_segment("username", user?); diff --git a/src/segment.rs b/src/segment.rs index 0d71af1af..4e3a2c086 100644 --- a/src/segment.rs +++ b/src/segment.rs @@ -1,4 +1,4 @@ -use ansi_term::{ANSIString, ANSIStrings, Style}; +use ansi_term::{ANSIString, Style}; use std::fmt; /// A segment is a single configurable element in a module. This will usually @@ -11,14 +11,8 @@ pub struct Segment { /// The segment's style. If None, will inherit the style of the module containing it. style: Option<Style>, - /// The prefix used to preceed the contents of a segment. - prefix: Option<SegmentAffix>, - /// The string value of the current segment. value: String, - - /// The suffix used following the contents of a segment. - suffix: Option<SegmentAffix>, } impl Segment { @@ -27,9 +21,7 @@ impl Segment { Segment { name: name.to_string(), style: None, - prefix: None, value: "".to_string(), - suffix: None, } } @@ -54,59 +46,6 @@ impl Segment { } // Returns the ANSIString of the segment value, not including its prefix and suffix - fn value_ansi_string(&self) -> ANSIString { - match self.style { - Some(style) => style.paint(&self.value), - None => ANSIString::from(&self.value), - } - } - - /// Returns a vector of colored ANSIString elements to be later used with - /// `ANSIStrings()` to optimize ANSI codes - pub fn ansi_strings(&self) -> Vec<ANSIString> { - let prefix = self.prefix.as_ref().and_then(|p| Some(p.ansi_string())); - let suffix = self.suffix.as_ref().and_then(|s| Some(s.ansi_string())); - let value = Some(self.value_ansi_string()); - - // Remove `None` values from the vector - vec![prefix, value, suffix] - .into_iter() - .filter_map(|e| e) - .collect::<Vec<ANSIString>>() - } -} - -impl fmt::Display for Segment { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let ansi_strings = self.ansi_strings(); - write!(f, "{}", ANSIStrings(&ansi_strings)) - } -} - -/// Segment affixes are to be used for the prefix or suffix of a segment. -/// By default they will inherit the styling of its segment, unless otherwise specified. -pub struct SegmentAffix { - /// The affix's name, to be used in configuration and logging. - name: String, - - /// The affix's style. If None, will inherit the style of the segment containing it. - style: Option<Style>, - - /// The string value of the affix. - value: String, -} - |