rtl-flip-detect 0.1.0

Detect right-to-left override (U+202E) and other bidi-control characters that flip rendering of strings. Used in filename-spoof and prompt-injection attacks. Zero deps.
Documentation
use rtl_flip_detect::{find_rtl_flips, has_rtl_flip, strip_rtl_flips};

#[test]
fn detects_rlo() {
    let s = "evil\u{202E}cod.exe";
    assert!(has_rtl_flip(s));
    assert_eq!(strip_rtl_flips(s), "evilcod.exe");
}

#[test]
fn finds_position() {
    let f = find_rtl_flips("a\u{202E}b");
    assert_eq!(f.len(), 1);
    assert_eq!(f[0].0, 1);
    assert_eq!(f[0].1, '\u{202E}');
}

#[test]
fn covers_all_directional_formatting() {
    for c in ['\u{202A}', '\u{202B}', '\u{202C}', '\u{202D}', '\u{202E}'] {
        assert!(has_rtl_flip(&c.to_string()), "missed {c:?}");
    }
}

#[test]
fn covers_all_isolates() {
    for c in ['\u{2066}', '\u{2067}', '\u{2068}', '\u{2069}'] {
        assert!(has_rtl_flip(&c.to_string()), "missed {c:?}");
    }
}

#[test]
fn pure_text_passes() {
    assert!(!has_rtl_flip("hello world"));
    assert_eq!(strip_rtl_flips("hello"), "hello");
}

#[test]
fn arabic_text_not_flagged() {
    // Real Arabic should pass — we only flag the explicit override controls.
    let s = "السلام عليكم";
    assert!(!has_rtl_flip(s));
    assert_eq!(strip_rtl_flips(s), s);
}