Simplify assert_sorted_by_name! macro

By extracting the equivalent of i32::cmp() into its own const function,
it becomes a lot easier to see what is happening and the logic can be
more direct.
This commit is contained in:
Mahmoud Al-Qudsi 2023-03-04 16:56:18 -06:00
parent 2c331e9c69
commit f2f7d1d183

View file

@ -142,43 +142,32 @@ macro_rules! assert_sorted_by_name {
use std::cmp::Ordering; use std::cmp::Ordering;
// ugly const eval workarounds below. // ugly const eval workarounds below.
const fn cmp_slice(s1: &[char], s2: &[char]) -> Ordering { const fn cmp_i32(lhs: i32, rhs: i32) -> Ordering {
let mut i = 0; match lhs - rhs {
while i < s1.len() { ..=-1 => Ordering::Less,
if s2.len() <= i { 0 => Ordering::Equal,
return Ordering::Greater; 1.. => Ordering::Greater,
}
if s1[i] < s2[i] {
return Ordering::Less;
} else if s1[i] > s2[i] {
return Ordering::Greater;
}
i += 1;
}
if s1.len() < s2.len() {
Ordering::Less
} else {
Ordering::Equal
} }
} }
let mut i = 0; const fn cmp_slice(s1: &[char], s2: &[char]) -> Ordering {
let mut prev: Option<&wstr> = None; let mut i = 0;
while i < $slice.len() { while i < s1.len() && i < s2.len() {
let cur = $slice[i].$field; match cmp_i32(s1[i] as i32, s2[i] as i32) {
if let Some(prev) = prev { Ordering::Equal => i += 1,
assert!( other => return other,
matches!( }
cmp_slice(prev.as_char_slice(), cur.as_char_slice()),
Ordering::Equal | Ordering::Less
),
"array must be sorted"
);
} }
cmp_i32(s1.len() as i32, s2.len() as i32)
}
prev = Some(cur); let mut i = 1;
while i < $slice.len() {
let prev = $slice[i - 1].$field.as_char_slice();
let cur = $slice[i].$field.as_char_slice();
if matches!(cmp_slice(prev, cur), Ordering::Greater) {
panic!("array must be sorted");
}
i += 1; i += 1;
} }
}; };