use core::cmp::Ordering;
use crate::folding::mapping::{lookup, Mode};
#[inline]
#[must_use]
pub fn casecmp(left: &str, right: &str) -> Ordering {
let left = left.chars().flat_map(|c| lookup(c, Mode::Full));
let right = right.chars().flat_map(|c| lookup(c, Mode::Full));
left.cmp(right)
}
#[inline]
#[must_use]
pub fn case_eq(left: &str, right: &str) -> bool {
let left = left.chars().flat_map(|c| lookup(c, Mode::Full));
let right = right.chars().flat_map(|c| lookup(c, Mode::Full));
left.eq(right)
}
#[cfg(test)]
mod tests {
use core::cmp::Ordering;
use super::{case_eq, casecmp};
#[test]
fn empty_string() {
assert!(case_eq("", ""));
assert_eq!(casecmp("", ""), Ordering::Equal);
assert!(!case_eq("", "rake"));
assert_eq!(casecmp("", "rake"), Ordering::Less);
assert!(!case_eq("rake", ""));
assert_eq!(casecmp("rake", ""), Ordering::Greater);
assert!(!case_eq("", "São Paulo"));
assert_eq!(casecmp("", "São Paulo"), Ordering::Less);
assert!(!case_eq("São Paulo", ""));
assert_eq!(casecmp("São Paulo", ""), Ordering::Greater);
}
#[test]
fn unicode_replacement_character() {
assert!(case_eq("\u{FFFD}", "\u{FFFD}"));
assert_eq!(casecmp("\u{FFFD}", "\u{FFFD}"), Ordering::Equal);
assert_eq!(casecmp("\u{FFFD}", "\u{FFFD}yam"), Ordering::Less);
assert_eq!(casecmp("\u{FFFD}yam", "\u{FFFD}"), Ordering::Greater);
}
#[test]
fn compares_symbols_without_regard_to_case() {
assert!(!case_eq("abcdef", "abcde"));
assert!(case_eq("aBcDeF", "abcdef"));
assert!(!case_eq("abcdef", "abcdefg"));
assert!(case_eq("abcdef", "ABCDEF"));
assert_eq!(casecmp("abcdef", "abcde"), Ordering::Greater);
assert_eq!(casecmp("aBcDeF", "abcdef"), Ordering::Equal);
assert_eq!(casecmp("abcdef", "abcdefg"), Ordering::Less);
assert_eq!(casecmp("abcdef", "ABCDEF"), Ordering::Equal);
assert_eq!(casecmp("abcdef", "abcde") as i32, 1);
assert_eq!(casecmp("aBcDeF", "abcdef") as i32, 0);
assert_eq!(casecmp("abcdef", "abcdefg") as i32, -1);
assert_eq!(casecmp("abcdef", "ABCDEF") as i32, 0);
assert_eq!(casecmp("abcdef", "abcde") as i32, 1);
}
#[test]
fn non_ascii_chars_that_are_not_fold_eq_are_not_eq() {
let upper_a_tilde = "Ã";
let lower_a_tilde = "ã";
let upper_a_umlaut = "Ä";
let lower_a_umlaut = "ä";
assert!(!case_eq(lower_a_tilde, lower_a_umlaut));
assert!(!case_eq(lower_a_umlaut, lower_a_tilde));
assert!(!case_eq(upper_a_tilde, upper_a_umlaut));
assert!(!case_eq(upper_a_umlaut, upper_a_tilde));
assert_ne!(casecmp(lower_a_tilde, lower_a_umlaut), Ordering::Equal);
assert_ne!(casecmp(lower_a_umlaut, lower_a_tilde), Ordering::Equal);
assert_ne!(casecmp(upper_a_tilde, upper_a_umlaut), Ordering::Equal);
assert_ne!(casecmp(upper_a_umlaut, upper_a_tilde), Ordering::Equal);
}
#[test]
fn does_case_mapping_for_unicode_chars() {
let upper_a_tilde = "Ã";
let lower_a_tilde = "ã";
let upper_a_umlaut = "Ä";
let lower_a_umlaut = "ä";
assert!(case_eq(upper_a_tilde, lower_a_tilde));
assert!(case_eq(upper_a_umlaut, lower_a_umlaut));
assert!(case_eq(lower_a_tilde, upper_a_tilde));
assert!(case_eq(lower_a_umlaut, upper_a_umlaut));
assert_eq!(casecmp(upper_a_tilde, lower_a_tilde), Ordering::Equal);
assert_eq!(casecmp(upper_a_umlaut, lower_a_umlaut), Ordering::Equal);
assert_eq!(casecmp(lower_a_tilde, upper_a_tilde), Ordering::Equal);
assert_eq!(casecmp(lower_a_umlaut, upper_a_umlaut), Ordering::Equal);
}
}