Skip to content

Commit

Permalink
WIP: fix: Preserve dotted-key ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
epage authored and mxndtaylor committed Nov 9, 2024
1 parent 224dc14 commit d9edae9
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
19 changes: 19 additions & 0 deletions crates/toml_edit/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct Key {
pub(crate) repr: Option<Repr>,
pub(crate) leaf_decor: Decor,
pub(crate) dotted_decor: Decor,
pub(crate) position: Option<usize>,
}

impl Key {
Expand All @@ -42,6 +43,7 @@ impl Key {
repr: None,
leaf_decor: Default::default(),
dotted_decor: Default::default(),
position: Default::default(),
}
}

Expand Down Expand Up @@ -76,6 +78,12 @@ impl Key {
self
}

/// While creating the `Key`, add a table position to it
pub fn with_position(mut self, position: Option<usize>) -> Self {
self.position = position;
self
}

/// Access a mutable proxy for the `Key`.
pub fn as_mut(&mut self) -> KeyMut<'_> {
KeyMut { key: self }
Expand Down Expand Up @@ -158,6 +166,16 @@ impl Key {
}
}

/// Get the position relative to other keys in parent table
pub fn position(&self) -> Option<usize> {
return self.position;
}

/// Set the position relative to other keys in parent table
pub fn set_position(&mut self, position: Option<usize>) {
self.position = position;
}

/// Auto formats the key.
pub fn fmt(&mut self) {
self.repr = None;
Expand Down Expand Up @@ -190,6 +208,7 @@ impl Clone for Key {
repr: self.repr.clone(),
leaf_decor: self.leaf_decor.clone(),
dotted_decor: self.dotted_decor.clone(),
position: self.position.clone(),
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/toml_edit/src/parser/inline_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ fn table_from_pairs(
// Assuming almost all pairs will be directly in `root`
root.items.reserve(v.len());

for (path, (key, value)) in v {
for (position, (path, (mut key, value))) in v.into_iter().enumerate() {
key.set_position(Some(position));
let table = descend_path(&mut root, &path)?;

// "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed"
Expand Down Expand Up @@ -162,6 +163,7 @@ mod test {
r#"{a = 1e165}"#,
r#"{ hello = "world", a = 1}"#,
r#"{ hello.world = "a" }"#,
r#"{ hello.world = "a", goodbye = "b", hello.moon = "c" }"#,
];
for input in inputs {
dbg!(input);
Expand Down
4 changes: 4 additions & 0 deletions crates/toml_edit/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ that
key = "value"
"#,
r#"hello.world = "a"
"#,
r#"hello.world = "a"
goodbye = "b"
hello.moon = "c"
"#,
r#"foo = 1979-05-27 # Comment
"#,
Expand Down
7 changes: 7 additions & 0 deletions crates/toml_edit/src/parser/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub(crate) struct ParseState {
root: Table,
trailing: Option<std::ops::Range<usize>>,
current_table_position: usize,
// Current position within a table, to help order dotted keys
current_value_position: usize,
current_table: Table,
current_is_array: bool,
current_table_path: Vec<Key>,
Expand All @@ -20,6 +22,7 @@ impl ParseState {
root: Table::new(),
trailing: None,
current_table_position: 0,
current_value_position: 0,
current_table: root,
current_is_array: false,
current_table_path: Vec::new(),
Expand Down Expand Up @@ -74,6 +77,9 @@ impl ParseState {
if let (Some(existing), Some(value)) = (self.current_table.span(), value.span()) {
self.current_table.span = Some((existing.start)..(value.end));
}
key.set_position(Some(self.current_value_position));
self.current_value_position += 1;

let table = &mut self.current_table;
let table = Self::descend_path(table, &path, true)?;

Expand Down Expand Up @@ -161,6 +167,7 @@ impl ParseState {
}

self.current_table_position += 1;
self.current_value_position = 0;
self.current_table.decor = decor;
self.current_table.set_implicit(false);
self.current_table.set_dotted(false);
Expand Down

0 comments on commit d9edae9

Please sign in to comment.