Unnamed repository; edit this file 'description' to name the repository.
remove unnecessary allocations in switch_case (#12786)
| -rw-r--r-- | helix-term/src/commands.rs | 38 |
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() |