diff --git a/crates/toml_edit/src/encode.rs b/crates/toml_edit/src/encode.rs index a8ccaa2a..b6142a6c 100644 --- a/crates/toml_edit/src/encode.rs +++ b/crates/toml_edit/src/encode.rs @@ -6,7 +6,9 @@ use toml_datetime::Datetime; use crate::inline_table::DEFAULT_INLINE_KEY_DECOR; use crate::key::Key; use crate::repr::{Formatted, Repr, ValueRepr}; -use crate::table::{DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_TABLE_DECOR}; +use crate::table::{ + DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_ROOT_DECOR, DEFAULT_TABLE_DECOR, +}; use crate::value::{ DEFAULT_LEADING_VALUE_DECOR, DEFAULT_TRAILING_VALUE_DECOR, DEFAULT_VALUE_DECOR, }; @@ -197,6 +199,9 @@ pub(crate) fn encode_value( impl Display for DocumentMut { fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let decor = self.decor(); + decor.prefix_encode(f, None, DEFAULT_ROOT_DECOR.0)?; + let mut path = Vec::new(); let mut last_position = 0; let mut tables = Vec::new(); @@ -214,6 +219,7 @@ impl Display for DocumentMut { for (_, table, path, is_array) in tables { visit_table(f, None, table, &path, is_array, &mut first_table)?; } + decor.suffix_encode(f, None, DEFAULT_ROOT_DECOR.1)?; self.trailing().encode_with_default(f, None, "") } } diff --git a/crates/toml_edit/src/table.rs b/crates/toml_edit/src/table.rs index 2b52aec7..2863946f 100644 --- a/crates/toml_edit/src/table.rs +++ b/crates/toml_edit/src/table.rs @@ -504,6 +504,7 @@ fn decorate_table(table: &mut Table) { } // `key1 = value1` +pub(crate) const DEFAULT_ROOT_DECOR: (&str, &str) = ("", ""); pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " "); pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", ""); pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", ""); diff --git a/crates/toml_edit/tests/testsuite/edit.rs b/crates/toml_edit/tests/testsuite/edit.rs index 3b6a21a2..01d9ef02 100644 --- a/crates/toml_edit/tests/testsuite/edit.rs +++ b/crates/toml_edit/tests/testsuite/edit.rs @@ -41,6 +41,15 @@ impl Test { } self } + fn running_on_doc(&mut self, func: F) -> &mut Self + where + F: Fn(&mut DocumentMut), + { + { + func(&mut self.doc); + } + self + } #[track_caller] fn produces_display(&self, expected: snapbox::data::Inline) -> &Self { @@ -49,6 +58,97 @@ impl Test { } } +#[test] +fn test_add_root_decor() { + given( + r#"[package] +name = "hello" +version = "1.0.0" + +[[bin]] +name = "world" +path = "src/bin/world/main.rs" + +[dependencies] +nom = "4.0" # future is here + +[[bin]] +name = "delete me please" +path = "src/bin/dmp/main.rs""#, + ) + .running_on_doc(|document| { + document.decor_mut().set_prefix("# Some Header\n\n"); + document.decor_mut().set_suffix("# Some Footer"); + document.set_trailing("\n\ntrailing..."); + }) + .produces_display(str![[r#" +# Some Header + +[package] +name = "hello" +version = "1.0.0" + +[[bin]] +name = "world" +path = "src/bin/world/main.rs" + +[dependencies] +nom = "4.0" # future is here + +[[bin]] +name = "delete me please" +path = "src/bin/dmp/main.rs" +# Some Footer + +trailing... +"#]]); +} + +/// Tests that default decor is None for both suffix and prefix and that this means empty strings +#[test] +fn test_no_root_decor() { + given( + r#"[package] +name = "hello" +version = "1.0.0" + +[[bin]] +name = "world" +path = "src/bin/world/main.rs" + +[dependencies] +nom = "4.0" # future is here + +[[bin]] +name = "delete me please" +path = "src/bin/dmp/main.rs""#, + ) + .running_on_doc(|document| { + assert!(document.decor().prefix().is_none()); + assert!(document.decor().suffix().is_none()); + document.set_trailing("\n\ntrailing..."); + }) + .produces_display(str![[r#" +[package] +name = "hello" +version = "1.0.0" + +[[bin]] +name = "world" +path = "src/bin/world/main.rs" + +[dependencies] +nom = "4.0" # future is here + +[[bin]] +name = "delete me please" +path = "src/bin/dmp/main.rs" + + +trailing... +"#]]); +} + // insertion #[test]