Skip to content

Commit

Permalink
Implement Ord for Path
Browse files Browse the repository at this point in the history
The ordering of path (as obtained when iterating over a directory) in Littlefs
is not exactly what is expected.

This implementation matches the ordering that  will be observed when iterating,
as described in littlefs-project/littlefs#923
  • Loading branch information
sosthene-nitrokey committed Feb 2, 2024
1 parent ebd27e4 commit 811a02a
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions src/path.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Paths

use core::{convert::TryFrom, fmt, iter::FusedIterator, marker::PhantomData, ops, ptr, slice, str};
use core::{
cmp::Ordering, convert::TryFrom, fmt, iter::FusedIterator, marker::PhantomData, ops, ptr,
slice, str,
};

use cstr_core::CStr;
use cty::{c_char, size_t};
Expand All @@ -20,6 +23,40 @@ pub struct Path {
inner: CStr,
}

impl Path {
fn cmp(&self, other: &Path) -> Ordering {
let this = self.inner.to_bytes();
let other = other.inner.to_bytes();

let min_len = this.len().min(other.len());

match this[0..min_len].cmp(&other[0..min_len]) {
Ordering::Less => Ordering::Less,
Ordering::Greater => Ordering::Greater,
Ordering::Equal if this.len() != other.len() => {
if this.len() < other.len() {
Ordering::Greater
} else {
Ordering::Less
}
}
Ordering::Equal => Ordering::Equal,
}
}
}

impl Ord for Path {
fn cmp(&self, other: &Path) -> Ordering {
self.cmp(other)
}
}

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

/// Iterator over the ancestors of a Path
///
/// See documentation for [`Path::ancestors`][]
Expand Down Expand Up @@ -258,7 +295,7 @@ impl Path {
let rk_path_bytes = self.as_ref()[..].as_bytes();
match rk_path_bytes.iter().rposition(|x| *x == b'/') {
Some(0) if rk_path_bytes.len() != 1 => {
return Some(PathBuf::from("/"));
Some(PathBuf::from("/"));
}
Some(slash_index) => {
// if we have a directory that ends with `/`,
Expand Down Expand Up @@ -750,4 +787,12 @@ mod tests {
let path = path!("/some/path/.././file.extension/");
assert_eq!(path.file_name(), None);
}

#[test]
fn path_ord() {
assert!(path!("some_path_a") < path!("some_path_b"));
assert!(path!("some_path_b") > path!("some_path_a"));
assert!(path!("some_path") > path!("some_path_a"));
assert!(path!("some_path") > path!("some_path_b"));
}
}

0 comments on commit 811a02a

Please sign in to comment.