use structopt::clap;
use crate::cli;
use crate::config::user_supplied_option;
use crate::fatal;
pub fn apply_rewrite_rules(opt: &mut cli::Opt, arg_matches: &clap::ArgMatches) {
rewrite_style_strings_to_honor_deprecated_minus_plus_options(opt);
rewrite_options_to_implement_deprecated_commit_and_file_style_box_option(opt);
rewrite_options_to_implement_deprecated_hunk_style_option(opt);
rewrite_options_to_implement_deprecated_theme_option(opt, arg_matches);
}
fn rewrite_options_to_implement_deprecated_theme_option(
opt: &mut cli::Opt,
arg_matches: &clap::ArgMatches,
) {
if user_supplied_option("deprecated-theme", arg_matches) {
if let Some(syntax_theme) = opt.deprecated_theme.as_ref() {
opt.syntax_theme = Some(syntax_theme.to_string());
}
}
}
fn rewrite_style_strings_to_honor_deprecated_minus_plus_options(opt: &mut cli::Opt) {
let deprecated_minus_foreground_arg = if opt.deprecated_highlight_minus_lines {
Some("syntax")
} else {
None
};
if let Some(rewritten) = _get_rewritten_minus_plus_style_string(
&opt.minus_style,
("normal", "auto"),
(
deprecated_minus_foreground_arg,
opt.deprecated_minus_background_color.as_deref(),
),
"minus",
) {
opt.minus_style = rewritten;
}
if let Some(rewritten) = _get_rewritten_minus_plus_style_string(
&opt.minus_emph_style,
("normal", "auto"),
(
deprecated_minus_foreground_arg,
opt.deprecated_minus_emph_background_color.as_deref(),
),
"minus-emph",
) {
opt.minus_emph_style = rewritten;
}
if let Some(rewritten) = _get_rewritten_minus_plus_style_string(
&opt.plus_style,
("syntax", "auto"),
(None, opt.deprecated_plus_background_color.as_deref()),
"plus",
) {
opt.plus_style = rewritten;
}
if let Some(rewritten) = _get_rewritten_minus_plus_style_string(
&opt.plus_emph_style,
("syntax", "auto"),
(None, opt.deprecated_plus_emph_background_color.as_deref()),
"plus-emph",
) {
opt.plus_emph_style = rewritten;
}
}
fn rewrite_options_to_implement_deprecated_commit_and_file_style_box_option(opt: &mut cli::Opt) {
if &opt.commit_style == "box" {
opt.commit_decoration_style = format!("box ul {}", opt.commit_decoration_style);
opt.commit_style.clear();
}
if &opt.file_style == "box" {
opt.file_decoration_style = format!("box ul {}", opt.file_decoration_style);
opt.file_style.clear();
}
}
fn rewrite_options_to_implement_deprecated_hunk_style_option(opt: &mut cli::Opt) {
if opt.deprecated_hunk_style.is_some() {
let hunk_header_decoration_default = "blue box";
if opt.hunk_header_decoration_style != hunk_header_decoration_default {
fatal(
"Deprecated option --hunk-style cannot be used with --hunk-header-decoration-style. \
Use --hunk-header-decoration-style.");
}
match opt.deprecated_hunk_style.as_deref().map(str::to_lowercase) {
Some(attr) if attr == "plain" => opt.hunk_header_decoration_style = "".to_string(),
Some(attr) if attr.is_empty() => {}
Some(attr) => opt.hunk_header_decoration_style = attr,
None => {}
}
opt.deprecated_hunk_style = None;
}
}
fn _get_rewritten_commit_file_hunk_header_style_string(
style_default_pair: (&str, Option<&str>),
deprecated_args_style_pair: (Option<&str>, Option<&str>),
) -> Option<String> {
let format_style = |pair: (&str, Option<&str>)| {
format!(
"{}{}",
pair.0,
match pair.1 {
Some(s) => format!(" {}", s),
None => "".to_string(),
}
)
};
match deprecated_args_style_pair {
(None, None) => None,
deprecated_args_style_pair => Some(format_style((
deprecated_args_style_pair.0.unwrap_or(style_default_pair.0),
match deprecated_args_style_pair.1 {
Some(s) => Some(s),
None => style_default_pair.1,
},
))),
}
}
fn _get_rewritten_minus_plus_style_string(
style: &str,
style_default_pair: (&str, &str),
deprecated_args_style_pair: (Option<&str>, Option<&str>),
element_name: &str,
) -> Option<String> {
let format_style = |pair: (&str, &str)| format!("{} {}", pair.0, pair.1);
match (style, deprecated_args_style_pair) {
(_, (None, None)) => None, (style, deprecated_args_style_pair) if style == format_style(style_default_pair) => {
Some(format_style((
deprecated_args_style_pair.0.unwrap_or(style_default_pair.0),
deprecated_args_style_pair.1.unwrap_or(style_default_pair.1),
)))
}
(_, (_, Some(_))) => {
fatal(format!(
"--{name}-color cannot be used with --{name}-style. \
Use --{name}-style=\"fg bg attr1 attr2 ...\" to set \
foreground color, background color, and style attributes. \
--{name}-color can only be used to set the background color. \
(It is still available for backwards-compatibility.)",
name = element_name,
));
}
(_, (Some(_), None)) => {
fatal(format!(
"Deprecated option --highlight-removed cannot be used with \
--{name}-style. Use --{name}-style=\"fg bg attr1 attr2 ...\" \
to set foreground color, background color, and style \
attributes.",
name = element_name,
));
}
}
}
#[cfg(test)]
mod tests {
use std::ffi::OsString;
use structopt::{clap, StructOpt};
use crate::cli;
use crate::options::rewrite::apply_rewrite_rules;
#[test]
fn test_deprecated_hunk_style_is_rewritten() {
let mut opt = cli::Opt::from_iter(Vec::<OsString>::new());
opt.deprecated_hunk_style = Some("underline".to_string());
let default = "blue box";
assert_eq!(opt.hunk_header_decoration_style, default);
apply_rewrite_rules(&mut opt, &clap::ArgMatches::new());
assert_eq!(opt.deprecated_hunk_style, None);
assert_eq!(opt.hunk_header_decoration_style, "underline");
}
#[test]
fn test_deprecated_hunk_style_is_not_rewritten() {
let mut opt = cli::Opt::from_iter(Vec::<OsString>::new());
opt.deprecated_hunk_style = Some("".to_string());
let default = "blue box";
assert_eq!(opt.hunk_header_decoration_style, default);
apply_rewrite_rules(&mut opt, &clap::ArgMatches::new());
assert_eq!(opt.deprecated_hunk_style, None);
assert_eq!(opt.hunk_header_decoration_style, default);
}
}