use unicode_segmentation::UnicodeSegmentation; use super::{Context, Module, RootModuleConfig}; use crate::configs::git_branch::GitBranchConfig; /// Creates a module with the Git branch in the current directory /// /// Will display the branch name if the current directory is a git repo pub fn module<'a>(context: &'a Context) -> Option> { let mut module = context.new_module("git_branch"); let config = GitBranchConfig::try_load(module.config); module.set_style(config.style); module.get_prefix().set_value("on "); let truncation_symbol = get_graphemes(config.truncation_symbol, 1); module.create_segment("symbol", &config.symbol); // TODO: Once error handling is implemented, warn the user if their config // truncation length is nonsensical let len = if config.truncation_length <= 0 { log::warn!( "\"truncation_length\" should be a positive value, found {}", config.truncation_length ); std::usize::MAX } else { config.truncation_length as usize }; let repo = context.get_repo().ok()?; // bare repos don't have a branch name, so `repo.branch.as_ref` would return None, // but git treats "master" as the default branch name let default_branch = String::from("master"); let branch_name = repo.branch.as_ref().unwrap_or(&default_branch); let truncated_graphemes = get_graphemes(&branch_name, len); // The truncation symbol should only be added if we truncated let truncated_and_symbol = if len < graphemes_len(&branch_name) { truncated_graphemes + &truncation_symbol } else { truncated_graphemes }; module.create_segment( "name", &config.branch_name.with_value(&truncated_and_symbol), ); Some(module) } fn get_graphemes(text: &str, length: usize) -> String { UnicodeSegmentation::graphemes(text, true) .take(length) .collect::>() .concat() } fn graphemes_len(text: &str) -> usize { UnicodeSegmentation::graphemes(&text[..], true).count() }