From 18a02189f9c8e2c47c69102637a93b7be3259fdd Mon Sep 17 00:00:00 2001 From: Integral Date: Tue, 17 Dec 2024 18:02:58 +0800 Subject: [PATCH] refactor: avoid strange round-trip of draw_fn arguments --- src/handlers/commit_meta.rs | 10 +-- src/handlers/diff_header.rs | 11 +-- src/handlers/draw.rs | 131 ++++++++++++++++++++++++--------- src/handlers/hunk_header.rs | 15 ++-- src/handlers/merge_conflict.rs | 8 +- src/subcommands/external.rs | 2 +- 6 files changed, 120 insertions(+), 57 deletions(-) diff --git a/src/handlers/commit_meta.rs b/src/handlers/commit_meta.rs index aee18c91b..0c8e2449b 100644 --- a/src/handlers/commit_meta.rs +++ b/src/handlers/commit_meta.rs @@ -30,8 +30,7 @@ impl StateMachine<'_> { if self.config.commit_style.is_omitted { return Ok(()); } - let (mut draw_fn, pad, decoration_ansi_term_style) = - draw::get_draw_function(self.config.commit_style.decoration_style); + let draw_fn = draw::get_draw_function(self.config.commit_style.decoration_style); let (formatted_line, formatted_raw_line) = if self.config.hyperlinks { ( features::hyperlinks::format_commit_line_with_osc8_commit_hyperlink( @@ -49,13 +48,14 @@ impl StateMachine<'_> { draw_fn( self.painter.writer, - &format!("{}{}", formatted_line, if pad { " " } else { "" }), - &format!("{}{}", formatted_raw_line, if pad { " " } else { "" }), + &formatted_line, + &formatted_raw_line, "", &self.config.decorations_width, self.config.commit_style, - decoration_ansi_term_style, + false, )?; + Ok(()) } } diff --git a/src/handlers/diff_header.rs b/src/handlers/diff_header.rs index 78157cbdb..2f82bd174 100644 --- a/src/handlers/diff_header.rs +++ b/src/handlers/diff_header.rs @@ -277,21 +277,22 @@ pub fn write_generic_diff_header_header_line( if config.file_style.is_omitted && !config.color_only { return Ok(()); } - let (mut draw_fn, pad, decoration_ansi_term_style) = - draw::get_draw_function(config.file_style.decoration_style); + let draw_fn = draw::get_draw_function(config.file_style.decoration_style); if !config.color_only { // Maintain 1-1 correspondence between input and output lines. writeln!(painter.writer)?; } + draw_fn( painter.writer, - &format!("{}{}", line, if pad { " " } else { "" }), - &format!("{}{}", raw_line, if pad { " " } else { "" }), + line, + raw_line, mode_info, &config.decorations_width, config.file_style, - decoration_ansi_term_style, + false, )?; + if !mode_info.is_empty() { mode_info.truncate(0); } diff --git a/src/handlers/draw.rs b/src/handlers/draw.rs index 2e6655853..430b14f7e 100644 --- a/src/handlers/draw.rs +++ b/src/handlers/draw.rs @@ -15,41 +15,104 @@ fn paint_text(text_style: Style, text: &str, addendum: &str) -> String { } } -pub type DrawFunction = dyn FnMut( - &mut dyn Write, - &str, - &str, - &str, - &Width, - Style, - ansi_term::Style, -) -> std::io::Result<()>; +pub type DrawFunction = + dyn Fn(&mut dyn Write, &str, &str, &str, &Width, Style, bool) -> std::io::Result<()>; -pub fn get_draw_function( - decoration_style: DecorationStyle, -) -> (Box, bool, ansi_term::Style) { - match decoration_style { - DecorationStyle::Box(style) => (Box::new(write_boxed), true, style), - DecorationStyle::BoxWithUnderline(style) => { - (Box::new(write_boxed_with_underline), true, style) - } - DecorationStyle::BoxWithOverline(style) => { - // TODO: not implemented - (Box::new(write_boxed), true, style) - } - DecorationStyle::BoxWithUnderOverline(style) => { - // TODO: not implemented - (Box::new(write_boxed), true, style) - } - DecorationStyle::Underline(style) => (Box::new(write_underlined), false, style), - DecorationStyle::Overline(style) => (Box::new(write_overlined), false, style), - DecorationStyle::UnderOverline(style) => (Box::new(write_underoverlined), false, style), - DecorationStyle::NoDecoration => ( - Box::new(write_no_decoration), - false, - ansi_term::Style::new(), - ), - } +pub fn get_draw_function(decoration_style: DecorationStyle) -> Box { + Box::new( + move |writer, text, raw_text, addendum, line_width, text_style, never_pad| { + match decoration_style { + DecorationStyle::Box(style) => { + if never_pad { + write_boxed( + writer, text, raw_text, addendum, line_width, text_style, style, + ) + } else { + write_boxed( + writer, + &format!("{text} "), + &format!("{raw_text} "), + addendum, + line_width, + text_style, + style, + ) + } + } + DecorationStyle::BoxWithUnderline(style) => { + if never_pad { + write_boxed_with_underline( + writer, text, raw_text, addendum, line_width, text_style, style, + ) + } else { + write_boxed_with_underline( + writer, + &format!("{text} "), + &format!("{raw_text} "), + addendum, + line_width, + text_style, + style, + ) + } + } + // TODO: not implemented + DecorationStyle::BoxWithOverline(style) => { + if never_pad { + write_boxed_with_underline( + writer, text, raw_text, addendum, line_width, text_style, style, + ) + } else { + write_boxed_with_underline( + writer, + &format!("{text} "), + &format!("{raw_text} "), + addendum, + line_width, + text_style, + style, + ) + } + } + // TODO: not implemented + DecorationStyle::BoxWithUnderOverline(style) => { + if never_pad { + write_boxed_with_underline( + writer, text, raw_text, addendum, line_width, text_style, style, + ) + } else { + write_boxed_with_underline( + writer, + &format!("{text} "), + &format!("{raw_text} "), + addendum, + line_width, + text_style, + style, + ) + } + } + DecorationStyle::Underline(style) => write_underlined( + writer, text, raw_text, addendum, line_width, text_style, style, + ), + DecorationStyle::Overline(style) => write_overlined( + writer, text, raw_text, addendum, line_width, text_style, style, + ), + DecorationStyle::UnderOverline(style) => write_underoverlined( + writer, text, raw_text, addendum, line_width, text_style, style, + ), + DecorationStyle::NoDecoration => write_no_decoration( + writer, + text, + raw_text, + addendum, + line_width, + text_style, + ansi_term::Style::new(), + ), + } + }, + ) } fn write_no_decoration( diff --git a/src/handlers/hunk_header.rs b/src/handlers/hunk_header.rs index 34f6d8692..9b3843c59 100644 --- a/src/handlers/hunk_header.rs +++ b/src/handlers/hunk_header.rs @@ -265,20 +265,21 @@ fn write_hunk_header_raw( raw_line: &str, config: &Config, ) -> std::io::Result<()> { - let (mut draw_fn, pad, decoration_ansi_term_style) = - draw::get_draw_function(config.hunk_header_style.decoration_style); + let draw_fn = draw::get_draw_function(config.hunk_header_style.decoration_style); if config.hunk_header_style.decoration_style != DecorationStyle::NoDecoration { writeln!(painter.writer)?; } + draw_fn( painter.writer, - &format!("{}{}", line, if pad { " " } else { "" }), - &format!("{}{}", raw_line, if pad { " " } else { "" }), + line, + raw_line, "", &config.decorations_width, config.hunk_header_style, - decoration_ansi_term_style, + false, )?; + Ok(()) } @@ -300,7 +301,7 @@ pub fn write_line_of_code_with_optional_path_and_line_number( file_path_separator: &str, config: &Config, ) -> std::io::Result<()> { - let (mut draw_fn, _, decoration_ansi_term_style) = draw::get_draw_function(decoration_style); + let draw_fn = draw::get_draw_function(decoration_style); let line = if config.color_only { line.to_string() } else if matches!(include_code_fragment, HunkHeaderIncludeCodeFragment::Yes) @@ -340,7 +341,7 @@ pub fn write_line_of_code_with_optional_path_and_line_number( "", &config.decorations_width, config.null_style, - decoration_ansi_term_style, + true, )?; painter.output_buffer.clear(); } diff --git a/src/handlers/merge_conflict.rs b/src/handlers/merge_conflict.rs index 60b545c57..efdca93b7 100644 --- a/src/handlers/merge_conflict.rs +++ b/src/handlers/merge_conflict.rs @@ -183,15 +183,13 @@ fn write_diff_header( painter: &mut paint::Painter, config: &config::Config, ) -> std::io::Result<()> { - let (mut draw_fn, pad, decoration_ansi_term_style) = - draw::get_draw_function(style.decoration_style); + let draw_fn = draw::get_draw_function(style.decoration_style); let derived_commit_name = &painter.merge_conflict_commit_names[derived_commit_type]; let text = if let Some(_ancestral_commit) = &painter.merge_conflict_commit_names[Ancestral] { format!( - "ancestor {} {}{}", + "ancestor {} {}", config.right_arrow, derived_commit_name.as_deref().unwrap_or("?"), - if pad { " " } else { "" } ) } else { derived_commit_name.as_deref().unwrap_or("?").to_string() @@ -203,7 +201,7 @@ fn write_diff_header( "", &config.decorations_width, style, - decoration_ansi_term_style, + false, )?; Ok(()) } diff --git a/src/subcommands/external.rs b/src/subcommands/external.rs index dc98a20fb..4f14c4ba0 100644 --- a/src/subcommands/external.rs +++ b/src/subcommands/external.rs @@ -216,7 +216,7 @@ mod test { } let mut writer = Cursor::new(vec![]); - let needle = format!("{}{}", "Y40ii4RihK6", "lHiK4BDsGS").to_string(); + let needle = concat!("Y40ii4RihK6", "lHiK4BDsGS"); // --minus-style has no effect, just for cmdline parsing let runargs = [ "--minus-style",