aboutsummaryrefslogtreecommitdiff
path: root/src/compare.rs
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2020-03-17 13:20:31 -0700
committerChih-Hung Hsieh <chh@google.com>2020-03-19 11:34:20 -0700
commit5846f731f46c552ac3a2dc8b38dea64df8aca81a (patch)
tree1b9f1909282fc1970ffd41958cc0188f03db2636 /src/compare.rs
parent3095d1536defaeecd3bda0e10483589a2ebc1428 (diff)
downloadremain-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.rs68
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;
+ }
+ }
+ }
+}