Skip to main content

find_case_insensitive

Function find_case_insensitive 

Source
fn find_case_insensitive(haystack: &str, needle_lower: &str) -> Option<usize>
Expand description

Case-insensitive substring search returning a byte offset into the original haystack, not into a lowercased copy of it.

The naive version of this (haystack.to_lowercase().find(needle), then slice haystack at the result) is wrong, and wrong in a way that can panic: lowercasing is not length-preserving. Turkish İ (U+0130, 2 bytes) lowercases to i̇ (3 bytes), so every such character before the match shifts the two strings out of alignment — slicing the original at an offset derived from the lowercased copy can land mid-character and panic, or silently return a misaligned snippet. Caught by reagentx P1 on PR #3321.

So the lowercase mapping is built explicitly, recording which original byte each lowercased byte came from.