Skip to content

Commit 95ed000

Browse files
committed
Implement comparator function for TreeNodes
1 parent e239fb3 commit 95ed000

4 files changed

Lines changed: 106 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

edit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ cbor4ii = { workspace = true }
99
compact_str = { workspace = true }
1010
foldhash = { workspace = true }
1111
git2 = "0.20"
12+
icu_collator = "2.2"
1213
mmm-core = { path = "../core" }
1314
thiserror = { workspace = true }
1415
tracing = { workspace = true }

edit/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
mod instance;
1919
mod r#mod;
20-
mod util;
20+
pub mod util;
2121
mod writer;
2222

2323
pub use instance::{EditableInstance, InstanceOpenError};

edit/src/util.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,40 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1515

16+
//! Miscellaneous functions.
17+
18+
use std::cmp::Ordering;
19+
use std::sync::LazyLock;
20+
21+
use icu_collator::options::{AlternateHandling, CaseLevel, CollatorOptions, Strength};
22+
use icu_collator::preferences::{CollationCaseFirst, CollationNumericOrdering};
23+
use icu_collator::{Collator, CollatorBorrowed, CollatorPreferences};
24+
25+
use mmm_core::file_tree::{TreeNode, TreeNodeKind};
26+
27+
static COLLATOR: LazyLock<CollatorBorrowed<'static>> = LazyLock::new(|| {
28+
let mut prefs = CollatorPreferences::default();
29+
prefs.numeric_ordering = Some(CollationNumericOrdering::True);
30+
prefs.case_first = Some(CollationCaseFirst::False);
31+
32+
let mut options = CollatorOptions::default();
33+
options.strength = Some(Strength::Tertiary);
34+
options.alternate_handling = Some(AlternateHandling::NonIgnorable);
35+
options.case_level = Some(CaseLevel::Off);
36+
37+
Collator::try_new(prefs, options).unwrap()
38+
});
39+
40+
/// A comparator for [`TreeNode`]s that sorts directories before files
41+
/// and sorts names using the CLDR Collation Algorithm provided by ICU4X.
42+
pub fn node_ord<F>(left: &TreeNode<F>, right: &TreeNode<F>) -> Ordering {
43+
match (&left.kind, &right.kind) {
44+
(TreeNodeKind::Dir, TreeNodeKind::File(_)) => Ordering::Less,
45+
(TreeNodeKind::File(_), TreeNodeKind::Dir) => Ordering::Greater,
46+
_ => COLLATOR.compare(&left.name, &right.name),
47+
}
48+
}
49+
1650
/// Moves multiple items in a slice to the specified index.
1751
///
1852
/// When moving items to the right, the target index needs to be adjusted to compensate for the items shifted left,

0 commit comments

Comments
 (0)