Repository: toml-rs/toml
Pull request #464 (2023-01-18 18:38:50)

fix(ser): Report the name of the unsupported type
This will help with debugging

This only addresses #396 for `toml_edit`.  The rest won't be addressed until #340 is resolved.


Patch:
diff --git a/crates/toml_edit/src/ser/item.rs b/crates/toml_edit/src/ser/item.rs
index eb499476..a3f1cada 100644
--- a/crates/toml_edit/src/ser/item.rs
+++ b/crates/toml_edit/src/ser/item.rs
@@ -101,11 +101,11 @@ impl serde::ser::Serializer for ItemSerializer {
     }
 
     fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
-        Err(ErrorKind::UnsupportedType.into())
+        Err(ErrorKind::UnsupportedType(Some("unit")).into())
     }
 
-    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
-        Err(ErrorKind::UnsupportedType.into())
+    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
+        Err(ErrorKind::UnsupportedType(Some(name)).into())
     }
 
     fn serialize_unit_variant(
@@ -130,7 +130,7 @@ impl serde::ser::Serializer for ItemSerializer {
 
     fn serialize_newtype_variant<T: ?Sized>(
         self,
-        _name: &'static str,
+        name: &'static str,
         _variant_index: u32,
         _variant: &'static str,
         _value: &T,
@@ -138,7 +138,7 @@ impl serde::ser::Serializer for ItemSerializer {
     where
         T: serde::ser::Serialize,
     {
-        Err(ErrorKind::UnsupportedType.into())
+        Err(ErrorKind::UnsupportedType(Some(name)).into())
     }
 
     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
@@ -189,11 +189,11 @@ impl serde::ser::Serializer for ItemSerializer {
 
     fn serialize_struct_variant(
         self,
-        _name: &'static str,
+        name: &'static str,
         _variant_index: u32,
         _variant: &'static str,
         _len: usize,
     ) -> Result<Self::SerializeStructVariant, Self::Error> {
-        Err(ErrorKind::UnsupportedType.into())
+        Err(ErrorKind::UnsupportedType(Some(name)).into())
     }
 }
diff --git a/crates/toml_edit/src/ser/mod.rs b/crates/toml_edit/src/ser/mod.rs
index c829d7a2..73434dbf 100644
--- a/crates/toml_edit/src/ser/mod.rs
+++ b/crates/toml_edit/src/ser/mod.rs
@@ -69,7 +69,7 @@ impl From<ErrorKind> for Error {
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 enum ErrorKind {
-    UnsupportedType,
+    UnsupportedType(Option<&'static str>),
     UnsupportedNone,
     KeyNotString,
     Custom(String),
@@ -78,7 +78,8 @@ enum ErrorKind {
 impl std::fmt::Display for ErrorKind {
     fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
         match self {
-            ErrorKind::UnsupportedType => "unsupported Rust type".fmt(formatter),
+            ErrorKind::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
+            ErrorKind::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
             ErrorKind::UnsupportedNone => "unsupported None value".fmt(formatter),
             ErrorKind::KeyNotString => "map key was not a string".fmt(formatter),
             ErrorKind::Custom(s) => s.fmt(formatter),
@@ -162,7 +163,9 @@ where
     T: serde::ser::Serialize,
 {
     let item = to_item(value)?;
-    let root = item.into_table().map_err(|_| ErrorKind::UnsupportedType)?;
+    let root = item
+        .into_table()
+        .map_err(|_| ErrorKind::UnsupportedType(None))?;
     Ok(root.into())
 }
 


Test patch:
diff --git a/crates/toml_edit/tests/testsuite/serde.rs b/crates/toml_edit/tests/testsuite/serde.rs
index 1fa78178..2d0e3f35 100644
--- a/crates/toml_edit/tests/testsuite/serde.rs
+++ b/crates/toml_edit/tests/testsuite/serde.rs
@@ -781,3 +781,22 @@ fn float_max() {
         Table(map! { a_b: Float(f64::MAX) }),
     }
 }
+
+#[test]
+fn unsupported_root_type() {
+    let native = "value";
+    let err = toml_edit::ser::to_string_pretty(&native).unwrap_err();
+    snapbox::assert_eq("unsupported rust type", err.to_string());
+}
+
+#[test]
+fn unsupported_nested_type() {
+    #[derive(Debug, Serialize, Deserialize)]
+    struct Foo {
+        unused: (),
+    }
+
+    let native = Foo { unused: () };
+    let err = toml_edit::ser::to_string_pretty(&native).unwrap_err();
+    snapbox::assert_eq("unsupported unit type", err.to_string());
+}