aboutsummaryrefslogtreecommitdiff
path: root/src/compare.rs
blob: 59f997d232dda4ddbb347b4e909cbdb834926525 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use proc_macro2::Ident;
use std::cmp::Ordering;

#[derive(PartialEq, Eq)]
pub struct Path {
    pub segments: Vec<Ident>,
}

impl PartialOrd for Path {
    fn partial_cmp(&self, other: &Path) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Path {
    fn cmp(&self, other: &Path) -> Ordering {
        // Lexicographic ordering across path segments.
        for (lhs, rhs) in self.segments.iter().zip(&other.segments) {
            match cmp(&lhs.to_string(), &rhs.to_string()) {
                Ordering::Equal => {}
                non_eq => return non_eq,
            }
        }

        self.segments.len().cmp(&other.segments.len())
    }
}

// TODO: more intelligent comparison
// for example to handle numeric cases like E9 < E10.
fn cmp(lhs: &str, rhs: &str) -> Ordering {
    // Sort `_` last.
    match (lhs == "_", rhs == "_") {
        (true, true) => return Ordering::Equal,
        (true, false) => return Ordering::Greater,
        (false, true) => return Ordering::Less,
        (false, false) => {}
    }

    let lhs = lhs.to_ascii_lowercase();
    let rhs = rhs.to_ascii_lowercase();

    // For now: asciibetical ordering.
    lhs.cmp(&rhs)
}