Unnamed repository; edit this file 'description' to name the repository.
remove unnecessary allocations in switch_case (#12786)
may 2025-02-27
parent 7bebe0a · commit e1c7a1e
-rw-r--r--helix-term/src/commands.rs38
1 files changed, 35 insertions, 3 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index a95e2a90..6c221ed3 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -67,6 +67,7 @@ use crate::{
use crate::job::{self, Jobs};
use std::{
+ char::{ToLowercase, ToUppercase},
cmp::Ordering,
collections::{HashMap, HashSet},
error::Error,
@@ -1727,17 +1728,48 @@ where
exit_select_mode(cx);
}
+enum CaseSwitcher {
+ Upper(ToUppercase),
+ Lower(ToLowercase),
+ Keep(Option<char>),
+}
+
+impl Iterator for CaseSwitcher {
+ type Item = char;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self {
+ CaseSwitcher::Upper(upper) => upper.next(),
+ CaseSwitcher::Lower(lower) => lower.next(),
+ CaseSwitcher::Keep(ch) => ch.take(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self {
+ CaseSwitcher::Upper(upper) => upper.size_hint(),
+ CaseSwitcher::Lower(lower) => lower.size_hint(),
+ CaseSwitcher::Keep(ch) => {
+ let n = if ch.is_some() { 1 } else { 0 };
+ (n, Some(n))
+ }
+ }
+ }
+}
+
+impl ExactSizeIterator for CaseSwitcher {}
+
fn switch_case(cx: &mut Context) {
switch_case_impl(cx, |string| {
string
.chars()
.flat_map(|ch| {
if ch.is_lowercase() {
- ch.to_uppercase().collect()
+ CaseSwitcher::Upper(ch.to_uppercase())
} else if ch.is_uppercase() {
- ch.to_lowercase().collect()
+ CaseSwitcher::Lower(ch.to_lowercase())
} else {
- vec![ch]
+ CaseSwitcher::Keep(Some(ch))
}
})
.collect()