#[must_use]
pub fn is_persian_letter(c: char) -> bool {
matches!(c, 'پ' | 'چ' | 'ژ' | 'گ' | 'ی' | 'ک')
}
#[must_use]
pub fn is_arabic_only_letter(c: char) -> bool {
matches!(c, 'ة' | 'ى' | 'ي' | 'ك' | 'إ' | 'أ' | 'ؤ' | 'ئ')
}
#[must_use]
pub fn is_arabic_or_persian(c: char) -> bool {
let cp = c as u32;
(0x0600..=0x06FF).contains(&cp)
|| (0xFB50..=0xFDFF).contains(&cp)
|| (0xFE70..=0xFEFF).contains(&cp)
}
#[must_use]
pub fn has_arabic(text: &str) -> bool {
text.chars().any(is_arabic_only_letter)
}
#[must_use]
pub fn has_persian(text: &str) -> bool {
text.chars().any(is_persian_letter)
}
#[must_use]
pub fn is_pure_persian(text: &str) -> bool {
let mut had_letter = false;
for c in text.chars() {
if c.is_alphabetic() {
had_letter = true;
if !is_arabic_or_persian(c) {
return false;
}
}
}
had_letter
}
#[must_use]
pub fn to_arabic(text: &str) -> String {
text.chars()
.map(|c| match c {
'ک' => 'ك',
'ی' => 'ي',
other => other,
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn detects_arabic_letter() {
assert!(has_arabic("هذة مدرسة"));
assert!(!has_arabic("این مدرسه است")); }
#[test]
fn detects_persian_letter() {
assert!(has_persian("پارسی زبان است"));
assert!(!has_persian("هذا كتاب"));
}
#[test]
fn pure_persian_detection() {
assert!(is_pure_persian("سلام دنیا"));
assert!(is_pure_persian("یک، دو، سه!"));
assert!(!is_pure_persian("hello سلام"));
}
#[test]
fn pure_persian_empty_no_letters() {
assert!(!is_pure_persian(""));
assert!(!is_pure_persian("12345"));
}
#[test]
fn to_arabic_basic() {
assert_eq!(to_arabic("کتاب"), "كتاب");
assert_eq!(to_arabic("یا علی"), "يا علي");
assert_eq!(to_arabic("سلام"), "سلام"); }
#[test]
fn classification_predicates() {
assert!(is_persian_letter('پ'));
assert!(!is_persian_letter('ك'));
assert!(is_arabic_only_letter('ك'));
assert!(is_arabic_or_persian('ا'));
assert!(!is_arabic_or_persian('a'));
}
}