Skip to content

Commit d72ad7f

Browse files
committed
fix: position=None keys broke key order when inserted into the table without sort_by_key
1 parent 07f82d2 commit d72ad7f

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

crates/toml_edit/src/table.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -519,14 +519,21 @@ fn decorate_table(table: &mut Table) {
519519
}
520520
}
521521

522+
/// sort_by_key works because we add the position to _every_ item's key during parsing,
523+
/// so keys without positions would be either:
524+
/// 1. non-leaf keys (i.e. "foo" or "bar" in dotted key "foo.bar.baz")
525+
/// 2. custom keys added to the doc without an explicit position
526+
/// and in the case of (1), we'd never see it since we only look at the last
527+
/// key in a dotted-key. So, we can safely return a constant value for these cases.
528+
///
529+
/// To support the most intuitive behavior, we return the maximum usize, placing
530+
/// position=None items at the end, so when you insert it without position, it
531+
/// appends it to the end.
522532
pub(crate) fn sort_values_by_position<'s>(values: &mut [(Vec<&'s Key>, &'s Value)]) {
523-
values.sort_by(|(left_kp, _), (right_kp, _)| {
524-
return match (left_kp.last().map(|x| x.position),
525-
right_kp.last().map(|x| x.position)) {
526-
// first if both have Some() position, its easy
527-
(Some(Some(p1)), Some(Some(p2))) => p1.cmp(&p2),
528-
// if one or more do not, preserve order
529-
_ => std::cmp::Ordering::Equal
533+
values.sort_by_key(|(left_kp, _)| {
534+
return match left_kp.last().map(|x| x.position) {
535+
Some(Some(pos)) => pos,
536+
_ => usize::MAX
530537
}
531538
});
532539
}

0 commit comments

Comments
 (0)