Skip to content

Commit

Permalink
Merge pull request #642 from epage/sort
Browse files Browse the repository at this point in the history
feat: Add Array::sort_by
  • Loading branch information
epage authored Oct 27, 2023
2 parents ef689bc + ddadd45 commit fd52d09
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
30 changes: 30 additions & 0 deletions crates/toml_edit/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,36 @@ impl Array {
.retain(|item| item.as_value().map(&mut keep).unwrap_or(false));
}

/// Sorts the slice with a comparator function.
///
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
///
/// The comparator function must define a total ordering for the elements in the slice. If
/// the ordering is not total, the order of the elements is unspecified. An order is a
/// total order if it is (for all `a`, `b` and `c`):
///
/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
#[inline]
pub fn sort_by<F>(&mut self, mut compare: F)
where
F: FnMut(&Value, &Value) -> std::cmp::Ordering,
{
self.values.sort_by(move |lhs, rhs| {
let lhs = lhs.as_value();
let rhs = rhs.as_value();
match (lhs, rhs) {
(None, None) => std::cmp::Ordering::Equal,
(Some(_), None) => std::cmp::Ordering::Greater,
(None, Some(_)) => std::cmp::Ordering::Less,
(Some(lhs), Some(rhs)) => compare(lhs, rhs),
}
})
}

/// Sorts the array with a key extraction function.
///
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
Expand Down
7 changes: 7 additions & 0 deletions crates/toml_edit/tests/testsuite/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,3 +853,10 @@ src.git = "https://github.com/nixos/nixpkgs"
"#,
);
}

#[test]
fn sorting_with_references() {
let values = vec!["foo", "qux", "bar"];
let mut array = toml_edit::Array::from_iter(values);
array.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
}

0 comments on commit fd52d09

Please sign in to comment.