diff options
author | Thomas Otto <th1000s@posteo.net> | 2021-10-16 14:27:01 +0200 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2021-10-18 10:41:12 -0400 |
commit | cd50d301844991da65eaf613f753296217fb4cda (patch) | |
tree | 3d0f28de5d5476ba71593cd189782fb042f770ab | |
parent | 07228cc40809911c8694b85f0bfaa764156a2a74 (diff) |
Store line number prefix/suffix as SmolStr
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/features/line_numbers.rs | 59 | ||||
-rw-r--r-- | src/format.rs | 27 | ||||
-rw-r--r-- | src/handlers/blame.rs | 4 |
5 files changed, 65 insertions, 33 deletions
@@ -345,6 +345,7 @@ dependencies = [ "pathdiff", "regex", "shell-words", + "smol_str", "structopt", "syntect", "unicode-segmentation", @@ -813,6 +814,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074" [[package]] +name = "smol_str" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0" + +[[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -32,6 +32,7 @@ lazy_static = "1.4" pathdiff = "0.2.1" regex = "1.4.6" shell-words = "1.0.0" +smol_str = "0.1.18" structopt = "0.3.23" unicode-segmentation = "1.8.0" unicode-width = "0.1.9" diff --git a/src/features/line_numbers.rs b/src/features/line_numbers.rs index ff0a58ef..eee57b03 100644 --- a/src/features/line_numbers.rs +++ b/src/features/line_numbers.rs @@ -205,7 +205,7 @@ impl<'a> LineNumbersData<'a> { #[allow(clippy::too_many_arguments)] fn format_and_paint_line_number_field<'a>( - format_data: &[format::FormatStringPlaceholderData<'a>], + format_data: &'a [format::FormatStringPlaceholderData<'a>], style: &Style, minus_number: Option<usize>, plus_number: Option<usize>, @@ -218,7 +218,7 @@ fn format_and_paint_line_number_field<'a>( let mut ansi_strings = Vec::new(); let mut suffix = ""; for placeholder in format_data { - ansi_strings.push(style.paint(placeholder.prefix)); + ansi_strings.push(style.paint(placeholder.prefix.as_str())); let alignment_spec = placeholder.alignment_spec.unwrap_or("^"); let width = if let Some(placeholder_width) = placeholder.width { @@ -245,7 +245,7 @@ fn format_and_paint_line_number_field<'a>( None => {} Some(_) => unreachable!(), } - suffix = placeholder.suffix; + suffix = placeholder.suffix.as_str(); } ansi_strings.push(style.paint(suffix)); ansi_strings @@ -284,11 +284,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("{nm}", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "", + prefix: "".into(), placeholder: Some("nm"), alignment_spec: None, width: None, - suffix: "", + suffix: "".into(), prefix_len: 0, suffix_len: 0, }] @@ -300,11 +300,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("{np:4}", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "", + prefix: "".into(), placeholder: Some("np"), alignment_spec: None, width: Some(4), - suffix: "", + suffix: "".into(), prefix_len: 0, suffix_len: 0, }] @@ -316,11 +316,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("{np:>4}", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "", + prefix: "".into(), placeholder: Some("np"), alignment_spec: Some(">"), width: Some(4), - suffix: "", + suffix: "".into(), prefix_len: 0, suffix_len: 0, }] @@ -332,11 +332,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("{np:_>4}", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "", + prefix: "".into(), placeholder: Some("np"), alignment_spec: Some(">"), width: Some(4), - suffix: "", + suffix: "".into(), prefix_len: 0, suffix_len: 0, }] @@ -348,11 +348,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("__{np:_>4}@@", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "__", + prefix: "__".into(), placeholder: Some("np"), alignment_spec: Some(">"), width: Some(4), - suffix: "@@", + suffix: "@@".into(), prefix_len: 2, suffix_len: 2, }] @@ -368,20 +368,20 @@ pub mod tests { ), vec![ format::FormatStringPlaceholderData { - prefix: "__", + prefix: "__".into(), placeholder: Some("nm"), alignment_spec: Some("<"), width: Some(3), - suffix: "@@---{np:_>4}**", + suffix: "@@---{np:_>4}**".into(), prefix_len: 2, suffix_len: 15, }, format::FormatStringPlaceholderData { - prefix: "@@---", + prefix: "@@---".into(), placeholder: Some("np"), alignment_spec: Some(">"), width: Some(4), - suffix: "**", + suffix: "**".into(), prefix_len: 5, suffix_len: 2, } @@ -394,11 +394,11 @@ pub mod tests { assert_eq!( format::parse_line_number_format("__@@---**", &LINE_NUMBERS_PLACEHOLDER_REGEX), vec![format::FormatStringPlaceholderData { - prefix: "", + prefix: "".into(), placeholder: None, alignment_spec: None, width: None, - suffix: "__@@---**", + suffix: "__@@---**".into(), prefix_len: 0, suffix_len: 9, },] @@ -406,6 +406,27 @@ pub mod tests { } #[test] + fn test_line_number_format_long() { + let long = "line number format which is too large for SSO"; + assert!(long.len() > std::mem::size_of::<smol_str::SmolStr>()); + assert_eq!( + format::parse_line_number_format( + &format!("{long}{{nm}}{long}", long = long), + &LINE_NUMBERS_PLACEHOLDER_REGEX + ), + vec![format::FormatStringPlaceholderData { + prefix: long.into(), + prefix_len: long.len(), + placeholder: Some("nm"), + alignment_spec: None, + width: None, + suffix: long.into(), + suffix_len: long.len(), + },] + ) + } + + #[test] fn test_line_number_placeholder_width_one() { use format::parse_line_number_format; diff --git a/src/format.rs b/src/format.rs index 1f8bfb00..0b77e699 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,14 +1,15 @@ use regex::Regex; +use smol_str::SmolStr; use unicode_segmentation::UnicodeSegmentation; #[derive(Debug, Default, PartialEq)] pub struct FormatStringPlaceholderData<'a> { - pub prefix: &'a str, + pub prefix: SmolStr, + pub prefix_len: usize, pub placeholder: Option<&'a str>, pub alignment_spec: Option<&'a str>, pub width: Option<usize>, - pub suffix: &'a str, - pub prefix_len: usize, + pub suffix: SmolStr, pub suffix_len: usize, } @@ -57,11 +58,14 @@ pub fn parse_line_number_format<'a>( let mut offset = 0; for captures in placeholder_regex.captures_iter(format_string) { - let _match = captures.get(0).unwrap(); - let prefix = &format_string[offset.._match.start()]; - let suffix = &format_string[_match.end()..]; + let match_ = captures.get(0).unwrap(); + let prefix = SmolStr::new(&format_string[offset..match_.start()]); + let prefix_len = prefix.graphemes(true).count(); + let suffix = SmolStr::new(&format_string[match_.end()..]); + let suffix_len = suffix.graphemes(true).count(); format_data.push(FormatStringPlaceholderData { prefix, + prefix_len, placeholder: captures.get(1).map(|m| m.as_str()), alignment_spec: captures.get(3).map(|m| m.as_str()), width: captures.get(4).map(|m| { @@ -70,20 +74,19 @@ pub fn parse_line_number_format<'a>( .unwrap_or_else(|_| panic!("Invalid width in format string: {}", format_string)) }), suffix, - prefix_len: prefix.graphemes(true).count(), - suffix_len: suffix.graphemes(true).count(), + suffix_len, }); - offset = _match.end(); + offset = match_.end(); } if offset == 0 { // No placeholders format_data.push(FormatStringPlaceholderData { - prefix: &format_string[..0], + prefix: SmolStr::new(""), + prefix_len: 0, placeholder: None, alignment_spec: None, width: None, - suffix: &format_string[0..], - prefix_len: 0, + suffix: SmolStr::new(format_string), suffix_len: format_string.graphemes(true).count(), }) } diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs index af1057d9..a82b8995 100644 --- a/src/handlers/blame.rs +++ b/src/handlers/blame.rs @@ -148,7 +148,7 @@ pub fn format_blame_metadata( let mut s = String::new(); let mut suffix = ""; for placeholder in format_data { - s.push_str(placeholder.prefix); + s.push_str(placeholder.prefix.as_str()); let alignment_spec = placeholder.alignment_spec.unwrap_or("<"); let width = placeholder.width.unwrap_or(15); @@ -163,7 +163,7 @@ pub fn format_blame_metadata( None => {} Some(_) => unreachable!(), } - suffix = placeholder.suffix; + suffix = placeholder.suffix.as_str(); } s.push_str(suffix); s |