Repository: toml-rs/toml
Pull request #864 (2025-04-22 13:42:42)

fix(write): Make things work


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 74173cbf..165431a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -976,7 +976,9 @@ dependencies = [
 name = "toml_write"
 version = "0.1.0"
 dependencies = [
+ "proptest",
  "snapbox",
+ "toml 0.5.11",
 ]
 
 [[package]]
diff --git a/crates/toml_write/Cargo.toml b/crates/toml_write/Cargo.toml
index 186726b6..3eca6fca 100644
--- a/crates/toml_write/Cargo.toml
+++ b/crates/toml_write/Cargo.toml
@@ -34,7 +34,9 @@ alloc = []
 [dependencies]
 
 [dev-dependencies]
+proptest = "1.6.0"
 snapbox = "0.6.0"
+toml_old = { version = "0.5.10", package = "toml" }
 
 [lints]
 workspace = true
diff --git a/crates/toml_write/src/lib.rs b/crates/toml_write/src/lib.rs
index 9795905f..53068da2 100644
--- a/crates/toml_write/src/lib.rs
+++ b/crates/toml_write/src/lib.rs
@@ -1,4 +1,32 @@
 //! A low-level interface for writing out TOML
+//!
+//! # Example
+//!
+//! ```rust
+//! use toml_write::TomlWrite as _;
+//!
+//! # fn main() -> std::fmt::Result {
+//! let mut output = String::new();
+//! output.newline()?;
+//! output.open_table_header()?;
+//! output.key("table")?;
+//! output.close_table_header()?;
+//! output.newline()?;
+//!
+//! output.key("key")?;
+//! output.space()?;
+//! output.keyval_sep()?;
+//! output.space()?;
+//! output.value("value")?;
+//! output.newline()?;
+//!
+//! assert_eq!(output, r#"
+//! [table]
+//! key = "value"
+//! "#);
+//! #   Ok(())
+//! # }
+//! ```
 
 #![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
diff --git a/crates/toml_write/src/write.rs b/crates/toml_write/src/write.rs
index 45fd89cf..7f4c67e4 100644
--- a/crates/toml_write/src/write.rs
+++ b/crates/toml_write/src/write.rs
@@ -35,11 +35,11 @@ pub trait TomlWrite: core::fmt::Write {
         write!(self, "=")
     }
 
-    fn key(&mut self, value: &impl crate::WriteTomlKey) -> core::fmt::Result {
+    fn key(&mut self, value: &(impl crate::WriteTomlKey + ?Sized)) -> core::fmt::Result {
         value.write_toml_key(self)
     }
 
-    fn value(&mut self, value: &impl crate::WriteTomlValue) -> core::fmt::Result {
+    fn value(&mut self, value: &(impl crate::WriteTomlValue + ?Sized)) -> core::fmt::Result {
         value.write_toml_value(self)
     }
 


Test patch:
diff --git a/crates/toml_write/tests/string.rs b/crates/toml_write/tests/string.rs
index 91cf6583..46250168 100644
--- a/crates/toml_write/tests/string.rs
+++ b/crates/toml_write/tests/string.rs
@@ -1,6 +1,7 @@
 #![cfg(feature = "alloc")]
 #![allow(clippy::dbg_macro)] // unsure why config isn't working
 
+use proptest::prelude::*;
 use snapbox::prelude::*;
 use snapbox::str;
 
@@ -31,6 +32,20 @@ fn t(decoded: &str, expected: impl IntoData) {
         string_ml_basic: string.as_ml_basic().to_toml_value(),
     };
     snapbox::assert_data_eq!(results.to_debug(), expected.raw());
+
+    // Verify defaults are compatible with the old TOML parser so new Cargo doesn't cause an MSRV
+    // bump
+    let toml = format!("{} = {}", results.key_default, results.string_default);
+    dbg!(&toml);
+    let value = toml.parse::<toml_old::Value>();
+    let value = match value {
+        Ok(value) => value,
+        Err(err) => panic!("could not parse: {err}"),
+    };
+    let table = value.as_table().unwrap();
+    let (key, value) = table.iter().next().unwrap();
+    assert_eq!(key, decoded);
+    assert_eq!(value.as_str().unwrap(), decoded);
 }
 
 #[derive(Debug)]
@@ -562,3 +577,28 @@ StringResults {
 "#]],
     );
 }
+
+proptest! {
+    /// Verify defaults are compatible with the old TOML parser so new Cargo doesn't cause an MSRV
+    /// bump
+    #[test]
+    fn parseable(decoded in "\\PC*") {
+        let key = TomlKeyBuilder::new(&decoded);
+        let string = TomlStringBuilder::new(&decoded);
+
+        let key_default = key.as_default().to_toml_key();
+        let string_default = string.as_default().to_toml_value();
+
+        let toml = format!("{key_default} = {string_default}");
+        dbg!(&toml);
+        let value = toml.parse::<toml_old::Value>();
+        let value = match value {
+            Ok(value) => value,
+            Err(err) => panic!("could not parse: {err}"),
+        };
+        let table = value.as_table().unwrap();
+        let (key, value) = table.iter().next().unwrap();
+        assert_eq!(*key, decoded);
+        assert_eq!(value.as_str().unwrap(), decoded);
+    }
+}