Skip to content

Commit fd52d09

Browse files
authored
Merge pull request #642 from epage/sort
feat: Add Array::sort_by
2 parents ef689bc + ddadd45 commit fd52d09

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

crates/toml_edit/src/array.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,36 @@ impl Array {
317317
.retain(|item| item.as_value().map(&mut keep).unwrap_or(false));
318318
}
319319

320+
/// Sorts the slice with a comparator function.
321+
///
322+
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
323+
///
324+
/// The comparator function must define a total ordering for the elements in the slice. If
325+
/// the ordering is not total, the order of the elements is unspecified. An order is a
326+
/// total order if it is (for all `a`, `b` and `c`):
327+
///
328+
/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
329+
/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
330+
///
331+
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
332+
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
333+
#[inline]
334+
pub fn sort_by<F>(&mut self, mut compare: F)
335+
where
336+
F: FnMut(&Value, &Value) -> std::cmp::Ordering,
337+
{
338+
self.values.sort_by(move |lhs, rhs| {
339+
let lhs = lhs.as_value();
340+
let rhs = rhs.as_value();
341+
match (lhs, rhs) {
342+
(None, None) => std::cmp::Ordering::Equal,
343+
(Some(_), None) => std::cmp::Ordering::Greater,
344+
(None, Some(_)) => std::cmp::Ordering::Less,
345+
(Some(lhs), Some(rhs)) => compare(lhs, rhs),
346+
}
347+
})
348+
}
349+
320350
/// Sorts the array with a key extraction function.
321351
///
322352
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))

crates/toml_edit/tests/testsuite/edit.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,3 +853,10 @@ src.git = "https://github.com/nixos/nixpkgs"
853853
"#,
854854
);
855855
}
856+
857+
#[test]
858+
fn sorting_with_references() {
859+
let values = vec!["foo", "qux", "bar"];
860+
let mut array = toml_edit::Array::from_iter(values);
861+
array.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
862+
}

0 commit comments

Comments
 (0)