use std::ffi::OsString;
pub const MODE_OPTIONS: [&str; 5] = ["--icase-pathspecs", "--glob-pathspecs", "--noglob-pathspecs", "--literal-pathspecs", "--no-literal-pathspecs"];
pub const MODE_VARIABLES: [&str; 4] = ["GIT_ICASE_PATHSPECS", "GIT_GLOB_PATHSPECS", "GIT_NOGLOB_PATHSPECS", "GIT_LITERAL_PATHSPECS"];
pub fn modes_in_effect(global_prefix: &[OsString], overlay: &[(OsString, OsString)]) -> Vec<String> {
let mut found: Vec<String> = Vec::new();
for option in MODE_OPTIONS {
for each in global_prefix {
if each.as_encoded_bytes() == option.as_bytes() {
found.push(String::from(option));
break;
}
}
}
for variable in MODE_VARIABLES {
let mut set: bool = std::env::var_os(variable).is_some();
for (name, _) in overlay {
set |= name.as_encoded_bytes() == variable.as_bytes();
}
if set {
found.push(String::from(variable));
}
}
return found;
}
fn backticked<'item>(items: impl Iterator<Item = &'item str>) -> String {
let mut text: String = String::new();
for (position, item) in items.enumerate() {
if position > 0 {
text.push_str(", ");
}
text.push('`');
text.push_str(item);
text.push('`');
}
return text;
}
fn first_of(pair: &(String, String)) -> &str {
return pair.0.as_str();
}
fn second_of(pair: &(String, String)) -> &str {
return pair.1.as_str();
}
fn operation_word(operation: crate::conflict_side_state::Operation) -> &'static str {
use crate::conflict_side_state::Operation;
return match operation {
Operation::Merge => "merge",
Operation::Rebase => "rebase",
Operation::CherryPick => "cherry-pick",
Operation::Revert => "revert",
};
}
pub fn mode_note(modes: &[String], operation: crate::conflict_side_state::Operation) -> String {
let named: String = backticked(modes.iter().map(String::as_str));
return format!(
" This {} is in progress and every path named is a conflicted file, so the same command without {named} would be saved first \
and then allowed. {named} changes which files a pathspec names, so the line is rejected as it stands: run it again without \
{named} (drop the option or unset the variable).",
operation_word(operation)
);
}
pub fn magic_note(magic: &[(String, String)], operation: crate::conflict_side_state::Operation) -> String {
let spellings: String = backticked(magic.iter().map(first_of));
let names: String = backticked(magic.iter().map(second_of));
return format!(
" This {} is in progress and every path named is a conflicted file once the pathspec magic is left off ({spellings}). Pathspec \
magic changes which files a pathspec names, so name each conflicted file itself ({names}) and the line is saved first and \
then allowed.",
operation_word(operation)
);
}
#[cfg(test)]
#[path = "conflict_side_modes_tests.rs"]
mod tests;