summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOnielfa <onielfadev@gmail.com>2020-02-15 02:38:25 +0100
committerGitHub <noreply@github.com>2020-02-14 20:38:25 -0500
commitddd8cfb38827363666e5b6bff729cb886df56fc3 (patch)
treeb0e5a3d56ef25ab2072135d347102b220061ca38
parented04c61704fc263c92e9ec0b556a85fc7075a078 (diff)
perf: refactor git status to use HashMap for counts (#938)
-rw-r--r--src/modules/git_status.rs35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/modules/git_status.rs b/src/modules/git_status.rs
index 4a558faf6..0778bbce9 100644
--- a/src/modules/git_status.rs
+++ b/src/modules/git_status.rs
@@ -5,6 +5,7 @@ use super::{Context, Module, RootModuleConfig};
use crate::config::SegmentConfig;
use crate::configs::git_status::{CountConfig, GitStatusConfig};
use std::borrow::BorrowMut;
+use std::collections::HashMap;
/// Creates a module with the Git branch in the current directory
///
@@ -210,19 +211,41 @@ fn get_repo_status(repository: &mut Repository) -> Result<RepoStatus, git2::Erro
return Err(git2::Error::from_str("Repo has no status"));
}
+ let statuses_count = count_statuses(statuses);
+
let repo_status: RepoStatus = RepoStatus {
- conflicted: statuses.iter().filter(|s| is_conflicted(**s)).count(),
- deleted: statuses.iter().filter(|s| is_deleted(**s)).count(),
- renamed: statuses.iter().filter(|s| is_renamed(**s)).count(),
- modified: statuses.iter().filter(|s| is_modified(**s)).count(),
- staged: statuses.iter().filter(|s| is_staged(**s)).count(),
- untracked: statuses.iter().filter(|s| is_untracked(**s)).count(),
+ conflicted: *statuses_count.get("conflicted").unwrap_or(&0),
+ deleted: *statuses_count.get("deleted").unwrap_or(&0),
+ renamed: *statuses_count.get("renamed").unwrap_or(&0),
+ modified: *statuses_count.get("modified").unwrap_or(&0),
+ staged: *statuses_count.get("staged").unwrap_or(&0),
+ untracked: *statuses_count.get("untracked").unwrap_or(&0),
stashed: stashed_count(repository)?,
};
Ok(repo_status)
}
+fn count_statuses(statuses: Vec<Status>) -> HashMap<&'static str, usize> {
+ let mut predicates: HashMap<&'static str, fn(git2::Status) -> bool> = HashMap::new();
+ predicates.insert("conflicted", is_conflicted);
+ predicates.insert("deleted", is_deleted);
+ predicates.insert("renamed", is_renamed);
+ predicates.insert("modified", is_modified);
+ predicates.insert("staged", is_staged);
+ predicates.insert("untracked", is_untracked);
+
+ statuses.iter().fold(HashMap::new(), |mut map, status| {
+ for (key, predicate) in predicates.iter() {
+ if predicate(*status) {
+ let entry = map.entry(key).or_insert(0);
+ *entry += 1;
+ }
+ }
+ map
+ })
+}
+
fn is_conflicted(status: Status) -> bool {
status.is_conflicted()
}