diff --git a/Cargo.lock b/Cargo.lock index 7ad75843..34c409bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -437,15 +437,6 @@ dependencies = [ "url", ] -[[package]] -name = "hashbrown" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" -dependencies = [ - "autocfg", -] - [[package]] name = "hashbrown" version = "0.9.1" @@ -488,12 +479,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9" +checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" dependencies = [ "autocfg", - "hashbrown 0.8.2", + "hashbrown", ] [[package]] @@ -819,7 +810,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87a6df8506c2d359d5105344891f283e8e7ef81a7c6a542d516f8707e4a09b6b" dependencies = [ "dlv-list", - "hashbrown 0.9.1", + "hashbrown", ] [[package]] @@ -1184,6 +1175,7 @@ dependencies = [ "dirs-next", "gethostname", "git2", + "indexmap", "log", "native-tls", "nix", diff --git a/Cargo.toml b/Cargo.toml index b3778161..1d2112dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ term_size = "0.3.2" quick-xml = "0.19.0" rand = "0.7.3" serde_derive = "1.0.115" +indexmap = "1.6.0" notify-rust = { version = "4.0.0", optional = true } # Optional/http: diff --git a/src/config.rs b/src/config.rs index c781e903..cc3beaa5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ use crate::configs::StarshipRootConfig; use crate::utils; use ansi_term::{Color, Style}; +use indexmap::IndexMap; use std::clone::Clone; use std::collections::HashMap; @@ -146,6 +147,22 @@ where } } +impl<'a, T, S: ::std::hash::BuildHasher + Default> ModuleConfig<'a> for IndexMap +where + T: ModuleConfig<'a>, + S: Clone, +{ + fn from_config(config: &'a Value) -> Option { + let mut im = IndexMap::default(); + + for (x, y) in config.as_table()?.iter() { + im.insert(x.clone(), T::from_config(y)?); + } + + Some(im) + } +} + impl<'a, T> ModuleConfig<'a> for Option where T: ModuleConfig<'a> + Sized, diff --git a/src/configs/directory.rs b/src/configs/directory.rs index 6df4516e..87e16599 100644 --- a/src/configs/directory.rs +++ b/src/configs/directory.rs @@ -1,5 +1,5 @@ use crate::config::{ModuleConfig, RootModuleConfig}; -use std::collections::HashMap; +use indexmap::IndexMap; use starship_module_config_derive::ModuleConfig; @@ -7,7 +7,7 @@ use starship_module_config_derive::ModuleConfig; pub struct DirectoryConfig<'a> { pub truncation_length: i64, pub truncate_to_repo: bool, - pub substitutions: HashMap, + pub substitutions: IndexMap, pub fish_style_pwd_dir_length: i64, pub use_logical_path: bool, pub format: &'a str, @@ -24,7 +24,7 @@ impl<'a> RootModuleConfig<'a> for DirectoryConfig<'a> { truncation_length: 3, truncate_to_repo: true, fish_style_pwd_dir_length: 0, - substitutions: HashMap::new(), + substitutions: IndexMap::new(), use_logical_path: true, format: "[$path]($style)[$read_only]($read_only_style) ", style: "cyan bold", diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 4f13177c..04673f41 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -2,8 +2,8 @@ use super::utils::directory_nix as directory_utils; #[cfg(target_os = "windows")] use super::utils::directory_win as directory_utils; +use indexmap::IndexMap; use path_slash::PathExt; -use std::collections::HashMap; use std::iter::FromIterator; use std::path::{Path, PathBuf}; use unicode_segmentation::UnicodeSegmentation; @@ -246,7 +246,7 @@ fn real_path>(path: P) -> PathBuf { /// /// Given a list of (from, to) pairs, this will perform the string /// substitutions, in order, on the path. Any non-pair of strings is ignored. -fn substitute_path(dir_string: String, substitutions: &HashMap) -> String { +fn substitute_path(dir_string: String, substitutions: &IndexMap) -> String { let mut substituted_dir = dir_string; for substitution_pair in substitutions.iter() { substituted_dir = substituted_dir.replace(substitution_pair.0, substitution_pair.1); @@ -365,7 +365,7 @@ mod tests { #[test] fn substitute_prefix_and_middle() { let full_path = "/absolute/path/foo/bar/baz"; - let mut substitutions = HashMap::new(); + let mut substitutions = IndexMap::new(); substitutions.insert("/absolute/path".to_string(), ""); substitutions.insert("/bar/".to_string(), "/"); @@ -607,6 +607,22 @@ mod tests { Ok(()) } + #[test] + fn substitution_order() -> io::Result<()> { + let actual = ModuleRenderer::new("directory") + .path("/path/to/sub") + .config(toml::toml! { + [directory.substitutions] + "/path/to/sub" = "/correct/order" + "/to/sub" = "/wrong/order" + }) + .collect(); + let expected = Some(format!("{} ", Color::Cyan.bold().paint("/correct/order"))); + + assert_eq!(expected, actual); + Ok(()) + } + #[test] fn strange_substitution() -> io::Result<()> { let strange_sub = "/\\/;,!";