use super::*; use std::cmp::Ordering; #[derive(PartialEq, Eq)] pub struct DirectoryChild { pub byte_path: Vec, pub entry_type: EntryType, } impl PartialOrd for DirectoryChild { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for DirectoryChild { fn cmp(&self, other: &Self) -> Ordering { match self.entry_type.cmp(&other.entry_type) { Ordering::Equal => compare_ascii_arrays(&self.byte_path,&other.byte_path), other => other, } } } // Compare two ASCII arrays in case-agnostic alphabetic order. fn compare_ascii_arrays(left: &[u8], right: &[u8]) -> Ordering { let l = std::cmp::min(left.len(), right.len()); let lhs = &left[..l]; let rhs = &right[..l]; for i in 0..l { let a = remap_ascii(lhs[i]); let b = remap_ascii(rhs[i]); match a.cmp(&b) { Ordering::Equal => (), non_eq => return non_eq, } } left.len().cmp(&right.len()) } // Remap ASCII values so that they sort in case-agnostic alphabetic order: // !"#$%&'()*+,-./0123456789:;<=>? // @`AaBbCcDdEeFfGgHhIiJjKkLlMmNnOo // PpQqRrSsTtUuVvWwXxYyZz[{\|]}^~_ fn remap_ascii(c: u8) -> u8 { if 0x40 <= c && c <= 0x5F { (c - 0x40) * 2 + 0x40 } else if 0x60 <= c && c <= 0x7F { (c - 0x60) * 2 + 0x41 } else { c } }