bazaar_dirstate/
lib.rs

1use std::cmp::Ordering;
2use std::path::Path;
3
4pub fn lt_by_dirs(path1: &Path, path2: &Path) -> bool {
5    let path1_parts = path1.components();
6    let path2_parts = path2.components();
7    let mut path1_parts_iter = path1_parts.into_iter();
8    let mut path2_parts_iter = path2_parts.into_iter();
9
10    loop {
11        match (path1_parts_iter.next(), path2_parts_iter.next()) {
12            (None, None) => return false,
13            (None, Some(_)) => return true,
14            (Some(_), None) => return false,
15            (Some(part1), Some(part2)) => {
16                match part1.cmp(&part2) {
17                    Ordering::Equal => continue,
18                    Ordering::Less => return true,
19                    Ordering::Greater => return false,
20                }
21            }
22        }
23    }
24}
25
26pub fn lt_path_by_dirblock(path1: &Path, path2: &Path) -> bool {
27    let key1 = (path1.parent(), path1.file_name());
28    let key2 = (path2.parent(), path2.file_name());
29
30    key1 < key2
31}
32
33pub fn bisect_path_left(paths: &[&Path], path: &Path) -> usize {
34    let mut hi = paths.len();
35    let mut lo = 0;
36    while lo < hi {
37        let mid = (lo + hi) / 2;
38        // Grab the dirname for the current dirblock
39        let cur = paths[mid];
40        if lt_path_by_dirblock(cur, path) {
41            lo = mid + 1;
42        } else {
43            hi = mid;
44        }
45    }
46    lo
47}
48
49pub fn bisect_path_right(paths: &[&Path], path: &Path) -> usize {
50    let mut hi = paths.len();
51    let mut lo = 0;
52    while lo < hi {
53        let mid = (lo + hi) / 2;
54        // Grab the dirname for the current dirblock
55        let cur = paths[mid];
56        if lt_path_by_dirblock(path, cur) {
57            hi = mid;
58        } else {
59            lo = mid + 1;
60        }
61    }
62    lo
63}