use crate::constants::*;
use itertools::Itertools;
pub fn format_commit_line(line: &str, highlight_background: bool) -> String {
let header: String = if highlight_background {
YELLOW.to_string() + BLUE_TO_END_OF_LINE
} else {
YELLOW.to_string()
};
let parts = line.split('(').collect::<Vec<_>>();
if parts.len() == 1 {
return format!("{}{}{}", header, line, NORMAL);
}
let commit_part = parts[0].trim();
let without_trailing_parenthesis = parts[1].strip_suffix(')');
if without_trailing_parenthesis.is_none() {
return format!("{}{}{}", header, line, NORMAL);
}
let parenthesis_parts = without_trailing_parenthesis
.unwrap()
.split(", ")
.collect_vec();
let current_branch = compute_current_branch(&parenthesis_parts);
let comma = format!("{}, ", YELLOW);
return format!(
"{}{} ({}{}){}",
header,
commit_part,
parenthesis_parts
.iter()
.map(|part| format_commit_part(part, ¤t_branch))
.join(&comma),
YELLOW,
NORMAL
);
}
fn format_commit_part(part: &str, current_branch: &Option<String>) -> String {
if part.starts_with("tag: ") {
return format!("{}{}{}", BOLD, part, NORMAL_INTENSITY);
}
if let Some(current_branch_4_realz) = current_branch {
if current_branch_4_realz == part {
return format!("{}{}{}{}", BOLD, GREEN, part, NORMAL_INTENSITY);
}
}
if let Some(head_branch) = part.strip_prefix("HEAD -> ") {
return format!(
"{}{}HEAD -> {}{}{}",
BOLD, CYAN, GREEN, head_branch, NORMAL_INTENSITY
);
}
return format!("{}{}{}{}", BOLD, RED, part, NORMAL_INTENSITY);
}
fn compute_current_branch(candidates: &Vec<&str>) -> Option<String> {
let mut fewest_slashes: Vec<&str> = vec![];
let mut lowest_slash_count = usize::MAX;
for candidate in candidates {
if candidate.starts_with("tag: ") {
continue;
}
if let Some(headless) = candidate.strip_prefix("HEAD -> ") {
return Some(headless.to_owned());
}
let candidate_slash_count = candidate.matches('/').count();
if candidate_slash_count > lowest_slash_count {
continue;
}
if candidate_slash_count < lowest_slash_count {
fewest_slashes.clear();
}
lowest_slash_count = candidate_slash_count;
fewest_slashes.push(candidate);
}
if fewest_slashes.is_empty() {
return None;
}
if fewest_slashes.len() == 1 {
return Some(fewest_slashes[0].to_owned());
}
return None;
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
#[test]
fn test_compute_current_branch() {
assert_eq!(
None,
compute_current_branch(&"tag: 2.15".split(", ").collect_vec())
);
assert_eq!(
Some(String::from("master")),
compute_current_branch(
&"HEAD -> master, tag: 2.20.0, origin/master, origin/HEAD"
.split(", ")
.collect_vec()
)
);
assert_eq!(
Some(String::from("master")),
compute_current_branch(
&"tag: 2.20.0, origin/master, origin/HEAD, master"
.split(", ")
.collect_vec()
)
);
assert_eq!(
Some(String::from("walles/threaded")),
compute_current_branch(
&"origin/walles/threaded, walles/threaded"
.split(", ")
.collect_vec()
)
);
assert_eq!(
Some(String::from("xeago-master")),
compute_current_branch(&"xeago/master, xeago-master".split(", ").collect_vec())
);
}
#[test]
fn test_format_commit_line_tags_branches() {
assert_eq!(
"".to_owned() +
YELLOW +
BLUE_TO_END_OF_LINE +
"commit 62da46c7b300321119d399bdc69bfb2d56d5da57 (" +
BOLD +
"tag: 2.21.0"+
NORMAL_INTENSITY + YELLOW + ", "+
BOLD + RED +
"origin/master" +
NORMAL_INTENSITY + YELLOW +
", " +
BOLD + RED +
"origin/HEAD" +
NORMAL_INTENSITY + YELLOW +
", " +
BOLD + GREEN +
"master" +
NORMAL_INTENSITY + YELLOW +
")" +
NORMAL,
format_commit_line("commit 62da46c7b300321119d399bdc69bfb2d56d5da57 (tag: 2.21.0, origin/master, origin/HEAD, master)", true));
}
}