summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Otto <th1000s@posteo.net>2021-10-16 14:27:01 +0200
committerDan Davison <dandavison7@gmail.com>2021-10-18 10:41:12 -0400
commitcd50d301844991da65eaf613f753296217fb4cda (patch)
tree3d0f28de5d5476ba71593cd189782fb042f770ab
parent07228cc40809911c8694b85f0bfaa764156a2a74 (diff)
Store line number prefix/suffix as SmolStr
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/features/line_numbers.rs59
-rw-r--r--src/format.rs27
-rw-r--r--src/handlers/blame.rs4
5 files changed, 65 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 52e2b368..8e9e2c61 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 7dc04b3f..2090983a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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