From a8ded9cb0d00e6d569b38d215bab1c98e3ff75e6 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 27 Dec 2025 08:15:47 +0100 Subject: [PATCH] Separate wcscasecmp() concerns better --- crates/fallback/src/lib.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/crates/fallback/src/lib.rs b/crates/fallback/src/lib.rs index e55de22a6..13edf7fc9 100644 --- a/crates/fallback/src/lib.rs +++ b/crates/fallback/src/lib.rs @@ -3,7 +3,7 @@ //! //! Many of these functions are more or less broken and incomplete. -use fish_wchar::prelude::*; +use fish_wchar::{CharsUtf32, prelude::*}; use fish_widecharwidth::{WcLookupTable, WcWidth}; use once_cell::sync::Lazy; use std::cmp; @@ -116,7 +116,17 @@ pub fn wcscasecmp(lhs: &wstr, rhs: &wstr) -> cmp::Ordering { } /// Compare two wide strings in a case-insensitive fashion -pub fn wcscasecmp_fuzzy(lhs: &wstr, rhs: &wstr, canonicalize: fn(char) -> char) -> cmp::Ordering { +pub fn wcscasecmp_fuzzy( + lhs: &wstr, + rhs: &wstr, + extra_canonicalization: fn(char) -> char, +) -> cmp::Ordering { + lowercase(lhs.chars()) + .map(extra_canonicalization) + .cmp(lowercase(rhs.chars()).map(extra_canonicalization)) +} + +pub fn lowercase(chars: CharsUtf32) -> impl Iterator { use std::char::ToLowercase; use widestring::utfstr::CharsUtf32; @@ -125,12 +135,12 @@ pub fn wcscasecmp_fuzzy(lhs: &wstr, rhs: &wstr, canonicalize: fn(char) -> char) /// `char::to_lowercase()` returns an iterator of chars and we sometimes need to cmp the last /// char of one char's `to_lowercase()` with the first char of the other char's /// `to_lowercase()`. This makes that possible. - struct ToLowerBuffer<'a, Canonicalize: Fn(char) -> char> { + struct ToLowerBuffer<'a> { current: ToLowercase, - chars: std::iter::Map, Canonicalize>, + chars: CharsUtf32<'a>, } - impl<'a, Canonicalize: Fn(char) -> char> Iterator for ToLowerBuffer<'a, Canonicalize> { + impl<'a> Iterator for ToLowerBuffer<'a> { type Item = char; fn next(&mut self) -> Option { @@ -143,8 +153,8 @@ fn next(&mut self) -> Option { } } - impl<'a, Canonicalize: Fn(char) -> char> ToLowerBuffer<'a, Canonicalize> { - pub fn new(mut chars: std::iter::Map, Canonicalize>) -> Self { + impl<'a> ToLowerBuffer<'a> { + pub fn new(mut chars: CharsUtf32<'a>) -> Self { Self { current: chars.next().map_or_else( || { @@ -160,9 +170,7 @@ pub fn new(mut chars: std::iter::Map, Canonicalize>) -> Self { } } - let lhs = ToLowerBuffer::new(lhs.chars().map(canonicalize)); - let rhs = ToLowerBuffer::new(rhs.chars().map(canonicalize)); - lhs.cmp(rhs) + ToLowerBuffer::new(chars) } #[cfg(test)]