use super::super::lexeme::LexemeKind;
const DETECTED: LexemeKind = LexemeKind::WhitespaceTrimmable;
const UNDETECTED: (LexemeKind, usize) = (LexemeKind::Undetected, 0);
pub fn detect_whitespace(
orig: &str,
chr: usize,
) -> (
LexemeKind,
usize,
) {
let len = orig.len();
if chr >= len || !orig.is_char_boundary(chr) { return UNDETECTED }
let mut i = chr;
while i < len {
let c = get_aot(orig, i);
if c == " " || c == "\n" || c == "\t" || c == "\r" || c == "\u{000B}" || c == "\u{000C}" { i += 1; continue }
if c != "~" { break }
if i >= len - 1 { break }
let mut j = i + 1;
while !orig.is_char_boundary(j) { j += 1 }
let c = &orig[i..j];
if c == "~" { break }
if c == "\u{0085}" || c == "\u{200E}" || c == "\u{200F}" || c == "\u{2028}" || c == "\u{2029}" { i = j; continue }
break;
}
if i == chr { UNDETECTED } else { (DETECTED, i) }
}
fn get_aot(orig: &str, c: usize) -> &str { orig.get(c..c+1).unwrap_or("~") }
#[cfg(test)]
mod tests {
use super::detect_whitespace as detect;
use super::DETECTED as D;
use super::UNDETECTED as U;
#[test]
fn detect_whitespace_correct() {
let orig = "~abc \t\nxyz~";
assert_eq!(detect(orig, 3), U); assert_eq!(detect(orig, 4), (D,7)); assert_eq!(detect(orig, 5), (D,7)); assert_eq!(detect(orig, 6), (D,7)); assert_eq!(detect(orig, 7), U);
assert_eq!(detect("\u{0000}", 0), U); assert_eq!(detect("\u{0009}", 0), (D,1)); assert_eq!(detect("\u{000A}", 0), (D,1)); assert_eq!(detect("\u{000B}", 0), (D,1)); assert_eq!(detect("\u{000C}", 0), (D,1)); assert_eq!(detect("\u{000D}", 0), (D,1)); assert_eq!(detect("\u{0020}", 0), (D,1)); assert_eq!(detect("\u{0085}", 0), (D,2)); assert_eq!(detect("\u{00A0}", 0), U); assert_eq!(detect("\u{200E}", 0), (D,3)); assert_eq!(detect("\u{200F}", 0), (D,3)); assert_eq!(detect("\u{2028}", 0), (D,3)); assert_eq!(detect("\u{2029}", 0), (D,3)); let orig = "\u{0000}\u{0009}\u{000A}\u{000B}\u{000C}\u{000D}\u{0020}\u{0085}";
assert_eq!(detect(orig, 0), U); assert_eq!(detect(orig, 1), (D,9)); let orig = "\u{00A0}\u{200E}\u{200F}\u{2028}\u{2029}";
assert_eq!(detect(orig, 0), U); assert_eq!(detect(orig, 2), (D,14));
let orig = "xyz~ \n";
assert_eq!(detect(orig, 2), U); assert_eq!(detect(orig, 3), U); assert_eq!(detect(orig, 4), (D,6)); assert_eq!(detect(orig, 5), (D,6)); }
#[test]
fn detect_whitespace_will_not_panic() {
assert_eq!(detect("", 0), U); assert_eq!(detect("~", 0), U); assert_eq!(detect("\n", 0), (D,1)); assert_eq!(detect("abc", 2), U); assert_eq!(detect("abc", 3), U); assert_eq!(detect("abc", 4), U); assert_eq!(detect("abc", 100), U); let orig = "\u{00A0}\u{200E}\u{200F}\u{2028}\u{2029}";
assert_eq!(detect(orig, 1), U); assert_eq!(detect("€", 1), U); assert_eq!(detect(" €", 0), (D,1)); assert_eq!(detect("\u{2029}€", 0), (D,3)); }
}