From c3600e60976437395eb7366f79e27fbe58292bd1 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 23 Sep 2024 20:00:29 -0500 Subject: [PATCH 1/2] test(edit): Verify key spacing --- crates/toml_edit/tests/testsuite/edit.rs | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/crates/toml_edit/tests/testsuite/edit.rs b/crates/toml_edit/tests/testsuite/edit.rs index 01d9ef02..41c0e613 100644 --- a/crates/toml_edit/tests/testsuite/edit.rs +++ b/crates/toml_edit/tests/testsuite/edit.rs @@ -980,3 +980,49 @@ fn sorting_with_references() { let mut array = toml_edit::Array::from_iter(values); array.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str())); } + +#[test] +fn table_str_key_whitespace() { + let mut document = "bookmark = 1010".parse::().unwrap(); + + let key: &str = "bookmark"; + + document.insert(key, array()); + let table = document[key].as_array_of_tables_mut().unwrap(); + + let mut bookmark_table = Table::new(); + bookmark_table["name"] = value("test.swf".to_owned()); + table.push(bookmark_table); + + assert_data_eq!( + document.to_string(), + str![[r#" +[[bookmark ]] +name = "test.swf" + +"#]] + ); +} + +#[test] +fn table_key_decor_whitespace() { + let mut document = "bookmark = 1010".parse::().unwrap(); + + let key = Key::parse(" bookmark ").unwrap().remove(0); + + document.insert_formatted(&key, array()); + let table = document[&key].as_array_of_tables_mut().unwrap(); + + let mut bookmark_table = Table::new(); + bookmark_table["name"] = value("test.swf".to_owned()); + table.push(bookmark_table); + + assert_data_eq!( + document.to_string(), + str![[r#" +[[bookmark ]] +name = "test.swf" + +"#]] + ); +} From 9bca304828b7b4e472e4360135aeb13a1c5a8a92 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 24 Sep 2024 13:16:52 -0500 Subject: [PATCH 2/2] fix(edit): Preserve new key's formatting when inserting Fixes #787 --- crates/toml_edit/src/inline_table.rs | 33 ++++++++++++++++++------ crates/toml_edit/src/table.rs | 27 ++++++++++++++++--- crates/toml_edit/tests/testsuite/edit.rs | 4 +-- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/crates/toml_edit/src/inline_table.rs b/crates/toml_edit/src/inline_table.rs index 462294b6..9b8e9c42 100644 --- a/crates/toml_edit/src/inline_table.rs +++ b/crates/toml_edit/src/inline_table.rs @@ -381,20 +381,37 @@ impl InlineTable { /// Inserts a key-value pair into the map. pub fn insert(&mut self, key: impl Into, value: Value) -> Option { - let key = Key::new(key.into()); + use indexmap::map::MutableEntryKey; + let key = Key::new(key); let value = Item::Value(value); - self.items - .insert(key, value) - .and_then(|old| old.into_value().ok()) + match self.items.entry(key.clone()) { + indexmap::map::Entry::Occupied(mut entry) => { + entry.key_mut().fmt(); + let old = std::mem::replace(entry.get_mut(), value); + old.into_value().ok() + } + indexmap::map::Entry::Vacant(entry) => { + entry.insert(value); + None + } + } } /// Inserts a key-value pair into the map. pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option { - let key = key.to_owned(); + use indexmap::map::MutableEntryKey; let value = Item::Value(value); - self.items - .insert(key, value) - .and_then(|old| old.into_value().ok()) + match self.items.entry(key.clone()) { + indexmap::map::Entry::Occupied(mut entry) => { + *entry.key_mut() = key.clone(); + let old = std::mem::replace(entry.get_mut(), value); + old.into_value().ok() + } + indexmap::map::Entry::Vacant(entry) => { + entry.insert(value); + None + } + } } /// Removes an item given the key. diff --git a/crates/toml_edit/src/table.rs b/crates/toml_edit/src/table.rs index c90298f5..1ae02310 100644 --- a/crates/toml_edit/src/table.rs +++ b/crates/toml_edit/src/table.rs @@ -393,14 +393,35 @@ impl Table { /// Inserts a key-value pair into the map. pub fn insert(&mut self, key: &str, item: Item) -> Option { + use indexmap::map::MutableEntryKey; let key = Key::new(key); - self.items.insert(key, item) + match self.items.entry(key.clone()) { + indexmap::map::Entry::Occupied(mut entry) => { + entry.key_mut().fmt(); + let old = std::mem::replace(entry.get_mut(), item); + Some(old) + } + indexmap::map::Entry::Vacant(entry) => { + entry.insert(item); + None + } + } } /// Inserts a key-value pair into the map. pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option { - let key = key.to_owned(); - self.items.insert(key, item) + use indexmap::map::MutableEntryKey; + match self.items.entry(key.clone()) { + indexmap::map::Entry::Occupied(mut entry) => { + *entry.key_mut() = key.clone(); + let old = std::mem::replace(entry.get_mut(), item); + Some(old) + } + indexmap::map::Entry::Vacant(entry) => { + entry.insert(item); + None + } + } } /// Removes an item given the key. diff --git a/crates/toml_edit/tests/testsuite/edit.rs b/crates/toml_edit/tests/testsuite/edit.rs index 41c0e613..84c53d05 100644 --- a/crates/toml_edit/tests/testsuite/edit.rs +++ b/crates/toml_edit/tests/testsuite/edit.rs @@ -997,7 +997,7 @@ fn table_str_key_whitespace() { assert_data_eq!( document.to_string(), str![[r#" -[[bookmark ]] +[[bookmark]] name = "test.swf" "#]] @@ -1020,7 +1020,7 @@ fn table_key_decor_whitespace() { assert_data_eq!( document.to_string(), str![[r#" -[[bookmark ]] +[[ bookmark ]] name = "test.swf" "#]]