diff options
author | Chih-Hung Hsieh <chh@google.com> | 2020-03-17 13:20:31 -0700 |
---|---|---|
committer | Chih-Hung Hsieh <chh@google.com> | 2020-03-19 11:34:20 -0700 |
commit | 5846f731f46c552ac3a2dc8b38dea64df8aca81a (patch) | |
tree | 1b9f1909282fc1970ffd41958cc0188f03db2636 /src/compare.rs | |
parent | 3095d1536defaeecd3bda0e10483589a2ebc1428 (diff) | |
download | remain-5846f731f46c552ac3a2dc8b38dea64df8aca81a.tar.gz |
Remove old 0.1.3; used only by old crosvm.
* 0.2.1 becomes the default
Test: make
Bug: 151628085
Change-Id: If095bf4f0fa9e33269df62fc346d5b4d75b0e5aa
Diffstat (limited to 'src/compare.rs')
-rw-r--r-- | src/compare.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/compare.rs b/src/compare.rs new file mode 100644 index 0000000..3fa4198 --- /dev/null +++ b/src/compare.rs @@ -0,0 +1,68 @@ +use proc_macro2::Ident; +use std::cmp::Ordering; + +use crate::atom::iter_atoms; + +#[derive(Copy, Clone, PartialEq)] +pub enum UnderscoreOrder { + First, + Last, +} + +pub struct Path { + pub segments: Vec<Ident>, +} + +pub fn cmp(lhs: &Path, rhs: &Path, mode: UnderscoreOrder) -> Ordering { + // Lexicographic ordering across path segments. + for (lhs, rhs) in lhs.segments.iter().zip(&rhs.segments) { + match cmp_segment(&lhs.to_string(), &rhs.to_string(), mode) { + Ordering::Equal => {} + non_eq => return non_eq, + } + } + + lhs.segments.len().cmp(&rhs.segments.len()) +} + +fn cmp_segment(lhs: &str, rhs: &str, mode: UnderscoreOrder) -> Ordering { + // Sort `_` last. + match (lhs, rhs) { + ("_", "_") => return Ordering::Equal, + ("_", _) => return Ordering::Greater, + (_, "_") => return Ordering::Less, + (_, _) => {} + } + + let mut lhs_atoms = iter_atoms(lhs); + let mut rhs_atoms = iter_atoms(rhs); + + // Path segments can't be empty. + let mut left = lhs_atoms.next().unwrap(); + let mut right = rhs_atoms.next().unwrap(); + + if mode == UnderscoreOrder::Last { + // Compare leading underscores. + match left.underscores().cmp(&right.underscores()) { + Ordering::Equal => {} + non_eq => return non_eq, + } + } + + loop { + match left.cmp(&right) { + Ordering::Equal => {} + non_eq => return non_eq, + } + + match (lhs_atoms.next(), rhs_atoms.next()) { + (None, None) => return Ordering::Equal, + (None, Some(_)) => return Ordering::Less, + (Some(_), None) => return Ordering::Greater, + (Some(nextl), Some(nextr)) => { + left = nextl; + right = nextr; + } + } + } +} |