Repository: toml-rs/toml (language: rust)

Issue:
Implement Deserializer for Table and Array
I'm writing a config system for a CLI application based in TOML. The top layer is always a Table, but in order to use the `Deserializer` implementation in `Value`, I currently have to store a Value instead (meaning I then have to do something like `as_table().unwrap()` in all the other methods).


Discussion / hints:
I'd be willing to deserialze tables at the `toml` crate level but we can't guarantee that we can deserialize an `Array`.
Note, I was looking for `Deserializer`, not `Deserialize`. I found out however that they are mostly just aliases to std types, so I've made newtype wrappers instead so that I can implement traits on the types. That way I've been able to `impl<'de> Deserializer<'de> for &'de MyNewType`.

Fix patch:
diff --git a/crates/toml/src/lib.rs b/crates/toml/src/lib.rs
index 6897044b..d68d9bea 100644
--- a/crates/toml/src/lib.rs
+++ b/crates/toml/src/lib.rs
@@ -17,7 +17,7 @@
 //!
 //! ## TOML values
 //!
-//! A value in TOML is represented with the [`Value`] enum in this crate:
+//! A TOML document is represented with the [`Table`] type which maps `String` to the [`Value`] enum:
 //!
 //! ```rust,ignore
 //! pub enum Value {
@@ -31,25 +31,21 @@
 //! }
 //! ```
 //!
-//! TOML is similar to JSON with the notable addition of a [`Datetime`]
-//! type. In general, TOML and JSON are interchangeable in terms of
-//! formats.
-//!
 //! ## Parsing TOML
 //!
-//! The easiest way to parse a TOML document is via the [`Value`] type:
+//! The easiest way to parse a TOML document is via the [`Table`] type:
 //!
 //! ```rust
-//! use toml::Value;
+//! use toml::Table;
 //!
-//! let value = "foo = 'bar'".parse::<Value>().unwrap();
+//! let value = "foo = 'bar'".parse::<Table>().unwrap();
 //!
 //! assert_eq!(value["foo"].as_str(), Some("bar"));
 //! ```
 //!
-//! The [`Value`] type implements a number of convenience methods and
+//! The [`Table`] type implements a number of convenience methods and
 //! traits; the example above uses [`FromStr`] to parse a [`str`] into a
-//! [`Value`].
+//! [`Table`].
 //!
 //! ## Deserialization and Serialization
 //!
@@ -57,16 +53,19 @@
 //! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
 //! `Serializer` traits. Namely, you'll find:
 //!
+//! * `Deserialize for Table`
+//! * `Serialize for Table`
 //! * `Deserialize for Value`
 //! * `Serialize for Value`
 //! * `Deserialize for Datetime`
 //! * `Serialize for Datetime`
 //! * `Deserializer for de::Deserializer`
 //! * `Serializer for ser::Serializer`
+//! * `Deserializer for Table`
 //! * `Deserializer for Value`
 //!
 //! This means that you can use Serde to deserialize/serialize the
-//! [`Value`] type as well as the [`Datetime`] type in this crate. You can also
+//! [`Table`] type as well as [`Value`] and [`Datetime`] type in this crate. You can also
 //! use the [`Deserializer`], [`Serializer`], or [`Value`] type itself to act as
 //! a deserializer/serializer for arbitrary types.
 //!
diff --git a/crates/toml/src/value.rs b/crates/toml/src/value.rs
index 769da351..775b76d7 100644
--- a/crates/toml/src/value.rs
+++ b/crates/toml/src/value.rs
@@ -22,6 +22,33 @@ pub use crate::map::{Entry, Map};
 /// to use a LinkedHashMap instead.
 pub type Table = Map<String, Value>;
 
+impl Table {
+    /// Convert a `T` into `toml::Table`.
+    ///
+    /// This conversion can fail if `T`'s implementation of `Serialize` decides to
+    /// fail, or if `T` contains a map with non-string keys.
+    pub fn try_from<T>(value: T) -> Result<Self, crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        value.serialize(TableSerializer)
+    }
+
+    /// Interpret a `toml::Table` as an instance of type `T`.
+    ///
+    /// This conversion can fail if the structure of the `Table` does not match the structure
+    /// expected by `T`, for example if `T` is a bool which can't be mapped to a `Table`. It can
+    /// also fail if the structure is correct but `T`'s implementation of `Deserialize` decides
+    /// that something is wrong with the data, for example required struct fields are missing from
+    /// the TOML map or some number is too big to fit in the expected primitive type.
+    pub fn try_into<'de, T>(self) -> Result<T, crate::de::Error>
+    where
+        T: de::Deserialize<'de>,
+    {
+        de::Deserialize::deserialize(self)
+    }
+}
+
 impl fmt::Display for Table {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         crate::ser::to_string(self)
@@ -37,6 +64,64 @@ impl FromStr for Table {
     }
 }
 
+impl<'de> de::Deserializer<'de> for Table {
+    type Error = crate::de::Error;
+
+    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error>
+    where
+        V: de::Visitor<'de>,
+    {
+        Value::Table(self).deserialize_any(visitor)
+    }
+
+    #[inline]
+    fn deserialize_enum<V>(
+        self,
+        name: &'static str,
+        variants: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, crate::de::Error>
+    where
+        V: de::Visitor<'de>,
+    {
+        Value::Table(self).deserialize_enum(name, variants, visitor)
+    }
+
+    // `None` is interpreted as a missing field so be sure to implement `Some`
+    // as a present field.
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, crate::de::Error>
+    where
+        V: de::Visitor<'de>,
+    {
+        Value::Table(self).deserialize_option(visitor)
+    }
+
+    fn deserialize_newtype_struct<V>(
+        self,
+        name: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, crate::de::Error>
+    where
+        V: de::Visitor<'de>,
+    {
+        Value::Table(self).deserialize_newtype_struct(name, visitor)
+    }
+
+    serde::forward_to_deserialize_any! {
+        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
+        bytes byte_buf map unit_struct tuple_struct struct
+        tuple ignored_any identifier
+    }
+}
+
+impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Table {
+    type Deserializer = Self;
+
+    fn into_deserializer(self) -> Self {
+        self
+    }
+}
+
 /// Type representing a TOML array, payload of the `Value::Array` variant
 pub type Array = Vec<Value>;
 
@@ -69,7 +154,7 @@ impl Value {
     where
         T: ser::Serialize,
     {
-        value.serialize(Serializer)
+        value.serialize(ValueSerializer)
     }
 
     /// Interpret a `toml::Value` as an instance of type `T`.
@@ -557,6 +642,7 @@ impl<'de> de::Deserialize<'de> for Value {
     }
 }
 
+// This is wrapped by `Table` and any trait methods implemented here need to be wrapped there.
 impl<'de> de::Deserializer<'de> for Value {
     type Error = crate::de::Error;
 
@@ -675,12 +761,12 @@ impl<'de> de::SeqAccess<'de> for SeqDeserializer {
 }
 
 struct MapDeserializer {
-    iter: <Map<String, Value> as IntoIterator>::IntoIter,
+    iter: <Table as IntoIterator>::IntoIter,
     value: Option<(String, Value)>,
 }
 
 impl MapDeserializer {
-    fn new(map: Map<String, Value>) -> Self {
+    fn new(map: Table) -> Self {
         MapDeserializer {
             iter: map.into_iter(),
             value: None,
@@ -731,18 +817,18 @@ impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value {
     }
 }
 
-struct Serializer;
+struct ValueSerializer;
 
-impl ser::Serializer for Serializer {
+impl ser::Serializer for ValueSerializer {
     type Ok = Value;
     type Error = crate::ser::Error;
 
-    type SerializeSeq = SerializeVec;
-    type SerializeTuple = SerializeVec;
-    type SerializeTupleStruct = SerializeVec;
-    type SerializeTupleVariant = SerializeVec;
-    type SerializeMap = SerializeMap;
-    type SerializeStruct = SerializeMap;
+    type SerializeSeq = ValueSerializeVec;
+    type SerializeTuple = ValueSerializeVec;
+    type SerializeTupleStruct = ValueSerializeVec;
+    type SerializeTupleVariant = ValueSerializeVec;
+    type SerializeMap = ValueSerializeMap;
+    type SerializeStruct = ValueSerializeMap;
     type SerializeStructVariant = ser::Impossible<Value, crate::ser::Error>;
 
     fn serialize_bool(self, value: bool) -> Result<Value, crate::ser::Error> {
@@ -861,7 +947,7 @@ impl ser::Serializer for Serializer {
     }
 
     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, crate::ser::Error> {
-        Ok(SerializeVec {
+        Ok(ValueSerializeVec {
             vec: Vec::with_capacity(len.unwrap_or(0)),
         })
     }
@@ -888,6 +974,182 @@ impl ser::Serializer for Serializer {
         self.serialize_seq(Some(len))
     }
 
+    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> {
+        Ok(ValueSerializeMap {
+            ser: SerializeMap {
+                map: Map::new(),
+                next_key: None,
+            },
+        })
+    }
+
+    fn serialize_struct(
+        self,
+        _name: &'static str,
+        len: usize,
+    ) -> Result<Self::SerializeStruct, crate::ser::Error> {
+        self.serialize_map(Some(len))
+    }
+
+    fn serialize_struct_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeStructVariant, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+}
+
+struct TableSerializer;
+
+impl ser::Serializer for TableSerializer {
+    type Ok = Table;
+    type Error = crate::ser::Error;
+
+    type SerializeSeq = ser::Impossible<Table, crate::ser::Error>;
+    type SerializeTuple = ser::Impossible<Table, crate::ser::Error>;
+    type SerializeTupleStruct = ser::Impossible<Table, crate::ser::Error>;
+    type SerializeTupleVariant = ser::Impossible<Table, crate::ser::Error>;
+    type SerializeMap = SerializeMap;
+    type SerializeStruct = SerializeMap;
+    type SerializeStructVariant = ser::Impossible<Table, crate::ser::Error>;
+
+    fn serialize_bool(self, _value: bool) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_i8(self, _value: i8) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_i16(self, _value: i16) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_i32(self, _value: i32) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_i64(self, _value: i64) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_u8(self, _value: u8) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_u16(self, _value: u16) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_u32(self, _value: u32) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_u64(self, _value: u64) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_f32(self, _value: f32) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_f64(self, _value: f64) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_char(self, _value: char) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_str(self, _value: &str) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_bytes(self, _value: &[u8]) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_unit(self) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_unit_struct(self, _name: &'static str) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_unit_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+    ) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_newtype_struct<T: ?Sized>(
+        self,
+        _name: &'static str,
+        value: &T,
+    ) -> Result<Table, crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        value.serialize(self)
+    }
+
+    fn serialize_newtype_variant<T: ?Sized>(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _value: &T,
+    ) -> Result<Table, crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_none(self) -> Result<Table, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedNone)
+    }
+
+    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Table, crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        value.serialize(self)
+    }
+
+    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_tuple_struct(
+        self,
+        _name: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleStruct, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
+    fn serialize_tuple_variant(
+        self,
+        _name: &'static str,
+        _variant_index: u32,
+        _variant: &'static str,
+        _len: usize,
+    ) -> Result<Self::SerializeTupleVariant, crate::ser::Error> {
+        Err(crate::ser::Error::UnsupportedType)
+    }
+
     fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> {
         Ok(SerializeMap {
             map: Map::new(),
@@ -914,16 +1176,11 @@ impl ser::Serializer for Serializer {
     }
 }
 
-struct SerializeVec {
+struct ValueSerializeVec {
     vec: Vec<Value>,
 }
 
-struct SerializeMap {
-    map: Map<String, Value>,
-    next_key: Option<String>,
-}
-
-impl ser::SerializeSeq for SerializeVec {
+impl ser::SerializeSeq for ValueSerializeVec {
     type Ok = Value;
     type Error = crate::ser::Error;
 
@@ -940,7 +1197,7 @@ impl ser::SerializeSeq for SerializeVec {
     }
 }
 
-impl ser::SerializeTuple for SerializeVec {
+impl ser::SerializeTuple for ValueSerializeVec {
     type Ok = Value;
     type Error = crate::ser::Error;
 
@@ -956,7 +1213,7 @@ impl ser::SerializeTuple for SerializeVec {
     }
 }
 
-impl ser::SerializeTupleStruct for SerializeVec {
+impl ser::SerializeTupleStruct for ValueSerializeVec {
     type Ok = Value;
     type Error = crate::ser::Error;
 
@@ -972,7 +1229,7 @@ impl ser::SerializeTupleStruct for SerializeVec {
     }
 }
 
-impl ser::SerializeTupleVariant for SerializeVec {
+impl ser::SerializeTupleVariant for ValueSerializeVec {
     type Ok = Value;
     type Error = crate::ser::Error;
 
@@ -988,8 +1245,13 @@ impl ser::SerializeTupleVariant for SerializeVec {
     }
 }
 
+struct SerializeMap {
+    map: Map<String, Value>,
+    next_key: Option<String>,
+}
+
 impl ser::SerializeMap for SerializeMap {
-    type Ok = Value;
+    type Ok = Table;
     type Error = crate::ser::Error;
 
     fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), crate::ser::Error>
@@ -1019,12 +1281,60 @@ impl ser::SerializeMap for SerializeMap {
         Ok(())
     }
 
-    fn end(self) -> Result<Value, crate::ser::Error> {
-        Ok(Value::Table(self.map))
+    fn end(self) -> Result<Table, crate::ser::Error> {
+        Ok(self.map)
     }
 }
 
 impl ser::SerializeStruct for SerializeMap {
+    type Ok = Table;
+    type Error = crate::ser::Error;
+
+    fn serialize_field<T: ?Sized>(
+        &mut self,
+        key: &'static str,
+        value: &T,
+    ) -> Result<(), crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        ser::SerializeMap::serialize_key(self, key)?;
+        ser::SerializeMap::serialize_value(self, value)
+    }
+
+    fn end(self) -> Result<Table, crate::ser::Error> {
+        ser::SerializeMap::end(self)
+    }
+}
+
+struct ValueSerializeMap {
+    ser: SerializeMap,
+}
+
+impl ser::SerializeMap for ValueSerializeMap {
+    type Ok = Value;
+    type Error = crate::ser::Error;
+
+    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        self.ser.serialize_key(key)
+    }
+
+    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
+    where
+        T: ser::Serialize,
+    {
+        self.ser.serialize_value(value)
+    }
+
+    fn end(self) -> Result<Value, crate::ser::Error> {
+        self.ser.end().map(Value::Table)
+    }
+}
+
+impl ser::SerializeStruct for ValueSerializeMap {
     type Ok = Value;
     type Error = crate::ser::Error;
 


Test patch:
diff --git a/crates/toml/tests/testsuite/display.rs b/crates/toml/tests/testsuite/display.rs
index 88efbe93..7430fac8 100644
--- a/crates/toml/tests/testsuite/display.rs
+++ b/crates/toml/tests/testsuite/display.rs
@@ -20,21 +20,21 @@ fn simple_show() {
 
 #[test]
 fn table() {
-    assert_eq!(Table(map! {}).to_string(), "");
+    assert_eq!(map! {}.to_string(), "");
     assert_eq!(
-        Table(map! {
+        map! {
         "test" => Integer(2),
-        "test2" => Integer(3) })
+        "test2" => Integer(3) }
         .to_string(),
         "test = 2\ntest2 = 3\n"
     );
     assert_eq!(
-        Table(map! {
+        map! {
              "test" => Integer(2),
              "test2" => Table(map! {
                  "test" => String("wut".to_string())
              })
-        })
+        }
         .to_string(),
         "test = 2\n\
          \n\
@@ -42,12 +42,12 @@ fn table() {
          test = \"wut\"\n"
     );
     assert_eq!(
-        Table(map! {
+        map! {
              "test" => Integer(2),
              "test2" => Table(map! {
                  "test" => String("wut".to_string())
              })
-        })
+        }
         .to_string(),
         "test = 2\n\
          \n\
@@ -55,12 +55,12 @@ fn table() {
          test = \"wut\"\n"
     );
     assert_eq!(
-        Table(map! {
+        map! {
              "test" => Integer(2),
              "test2" => Array(vec![Table(map! {
                  "test" => String("wut".to_string())
              })])
-        })
+        }
         .to_string(),
         "test = 2\n\
          \n\
@@ -69,34 +69,34 @@ fn table() {
     );
     #[cfg(feature = "preserve_order")]
     assert_eq!(
-        Table(map! {
+        map! {
              "foo.bar" => Integer(2),
              "foo\"bar" => Integer(2)
-        })
+        }
         .to_string(),
         "\"foo.bar\" = 2\n\
          \"foo\\\"bar\" = 2\n"
     );
     assert_eq!(
-        Table(map! {
+        map! {
              "test" => Integer(2),
              "test2" => Array(vec![Table(map! {
                  "test" => Array(vec![Integer(2)])
              })])
-        })
+        }
         .to_string(),
         "test = 2\n\
          \n\
          [[test2]]\n\
          test = [2]\n"
     );
-    let table = Table(map! {
+    let table = map! {
         "test" => Integer(2),
         "test2" => Array(vec![Table(map! {
             "test" => Array(vec![Array(vec![Integer(2), Integer(3)]),
             Array(vec![String("foo".to_string()), String("bar".to_string())])])
         })])
-    });
+    };
     assert_eq!(
         table.to_string(),
         "test = 2\n\
@@ -105,10 +105,10 @@ fn table() {
          test = [[2, 3], [\"foo\", \"bar\"]]\n"
     );
     assert_eq!(
-        Table(map! {
+        map! {
              "test" => Array(vec![Integer(2)]),
              "test2" => Integer(2)
-        })
+        }
         .to_string(),
         "test = [2]\n\
          test2 = 2\n"
diff --git a/crates/toml/tests/testsuite/serde.rs b/crates/toml/tests/testsuite/serde.rs
index e8de6b2e..bb5ec8cb 100644
--- a/crates/toml/tests/testsuite/serde.rs
+++ b/crates/toml/tests/testsuite/serde.rs
@@ -4,8 +4,8 @@ use serde::Serialize;
 use std::collections::BTreeMap;
 
 use toml::map::Map;
+use toml::Table;
 use toml::Value;
-use toml::Value::{Array, Float, Integer, Table};
 
 macro_rules! t {
     ($e:expr) => {
@@ -23,7 +23,7 @@ macro_rules! equivalent {
 
         // In/out of Value is equivalent
         println!("try_from");
-        assert_eq!(t!(Value::try_from(literal.clone())), toml);
+        assert_eq!(t!(Table::try_from(literal.clone())), toml);
         println!("try_into");
         assert_eq!(literal, t!(toml.clone().try_into()));
 
@@ -68,7 +68,7 @@ fn smoke() {
         a: isize,
     }
 
-    equivalent!(Foo { a: 2 }, Table(map! { a: Integer(2) }),);
+    equivalent!(Foo { a: 2 }, map! { a: Value::Integer(2) },);
 }
 
 #[test]
@@ -80,7 +80,7 @@ fn smoke_hyphen() {
 
     equivalent! {
         Foo { a_b: 2 },
-        Table(map! { a_b: Integer(2) }),
+        map! { a_b: Value::Integer(2)},
     }
 
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
@@ -90,10 +90,10 @@ fn smoke_hyphen() {
     }
 
     let mut m = Map::new();
-    m.insert("a-b".to_string(), Integer(2));
+    m.insert("a-b".to_string(), Value::Integer(2));
     equivalent! {
         Foo2 { a_b: 2 },
-        Table(m),
+        m,
     }
 }
 
@@ -111,12 +111,12 @@ fn nested() {
 
     equivalent! {
         Foo { a: 2, b: Bar { a: "test".to_string() } },
-        Table(map! {
-            a: Integer(2),
-            b: Table(map! {
+        map! {
+            a: Value::Integer(2),
+            b: map! {
                 a: Value::String("test".to_string())
-            })
-        }),
+            }
+        },
     }
 }
 
@@ -134,9 +134,9 @@ fn application_decode_error() {
             }
         }
     }
-    let d_good = Integer(5);
+    let d_good = Value::Integer(5);
     let d_bad1 = Value::String("not an isize".to_string());
-    let d_bad2 = Integer(11);
+    let d_bad2 = Value::Integer(11);
 
     assert_eq!(Range10(5), d_good.try_into().unwrap());
 
@@ -155,14 +155,14 @@ fn array() {
 
     equivalent! {
         Foo { a: vec![1, 2, 3, 4] },
-        Table(map! {
-            a: Array(vec![
-                Integer(1),
-                Integer(2),
-                Integer(3),
-                Integer(4)
+        map! {
+            a: Value::Array(vec![
+                Value::Integer(1),
+                Value::Integer(2),
+                Value::Integer(3),
+                Value::Integer(4)
             ])
-        }),
+        },
     };
 }
 
@@ -187,18 +187,18 @@ fn inner_structs_with_options() {
             })),
             b: Bar { a: "bar".to_string(), b: 1.0 },
         },
-        Table(map! {
-            a: Table(map! {
-                b: Table(map! {
+        map! {
+            a: map! {
+                b: map! {
                     a: Value::String("foo".to_string()),
-                    b: Float(4.5)
-                })
-            }),
-            b: Table(map! {
+                    b: Value::Float(4.5)
+                }
+            },
+            b: map! {
                 a: Value::String("bar".to_string()),
-                b: Float(1.0)
-            })
-        }),
+                b: Value::Float(1.0)
+            }
+        },
     }
 }
 
@@ -215,25 +215,25 @@ fn hashmap() {
 
     equivalent! {
         Foo {
-            map: {
-                let mut m = BTreeMap::new();
-                m.insert("bar".to_string(), 4);
-                m.insert("foo".to_string(), 10);
-                m
-            },
             set: {
                 let mut s = HashSet::new();
                 s.insert('a');
                 s
             },
+            map: {
+                let mut m = BTreeMap::new();
+                m.insert("bar".to_string(), 4);
+                m.insert("foo".to_string(), 10);
+                m
+            }
+        },
+        map! {
+            set: Value::Array(vec![Value::String("a".to_string())]),
+            map: map! {
+                bar: Value::Integer(4),
+                foo: Value::Integer(10)
+            }
         },
-        Table(map! {
-            map: Table(map! {
-                bar: Integer(4),
-                foo: Integer(10)
-            }),
-            set: Array(vec![Value::String("a".to_string())])
-        }),
     }
 }
 
@@ -250,12 +250,12 @@ fn table_array() {
 
     equivalent! {
         Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
-        Table(map! {
-            a: Array(vec![
-                Table(map!{ a: Integer(1) }),
-                Table(map!{ a: Integer(2) }),
+        map! {
+            a: Value::Array(vec![
+                Value::Table(map!{ a: Value::Integer(1) }),
+                Value::Table(map!{ a: Value::Integer(2) }),
             ])
-        }),
+        },
     }
 }
 
@@ -269,9 +269,9 @@ fn type_errors() {
 
     error! {
         Foo,
-        Table(map! {
+        map! {
             bar: Value::String("a".to_string())
-        }),
+        },
         r#"TOML parse error at line 1, column 7
   |
 1 | bar = "a"
@@ -289,11 +289,11 @@ invalid type: string "a", expected isize
 
     error! {
         Bar,
-        Table(map! {
-            foo: Table(map! {
+        map! {
+            foo: map! {
                 bar: Value::String("a".to_string())
-            })
-        }),
+            }
+        },
         r#"TOML parse error at line 2, column 7
   |
 2 | bar = "a"
@@ -313,7 +313,7 @@ fn missing_errors() {
 
     error! {
         Foo,
-        Table(map! { }),
+        map! { },
         r#"TOML parse error at line 1, column 1
   |
 1 | 
@@ -344,17 +344,17 @@ fn parse_enum() {
 
     equivalent! {
         Foo { a: E::Bar(10) },
-        Table(map! { a: Integer(10) }),
+        map! { a: Value::Integer(10) },
     }
 
     equivalent! {
         Foo { a: E::Baz("foo".to_string()) },
-        Table(map! { a: Value::String("foo".to_string()) }),
+        map! { a: Value::String("foo".to_string()) },
     }
 
     equivalent! {
         Foo { a: E::Last(Foo2 { test: "test".to_string() }) },
-        Table(map! { a: Table(map! { test: Value::String("test".to_string()) }) }),
+        map! { a: map! { test: Value::String("test".to_string()) } },
     }
 }
 
@@ -374,7 +374,7 @@ fn parse_enum_string() {
 
     equivalent! {
         Foo { a: Sort::Desc },
-        Table(map! { a: Value::String("desc".to_string()) }),
+        map! { a: Value::String("desc".to_string()) },
     }
 }
 
@@ -514,7 +514,7 @@ fn empty_arrays() {
 
     equivalent! {
         Foo { a: vec![] },
-        Table(map! {a: Array(Vec::new())}),
+        map! {a: Value::Array(Vec::new())},
     }
 }
 
@@ -529,12 +529,12 @@ fn empty_arrays2() {
 
     equivalent! {
         Foo { a: None },
-        Table(map! {}),
+        map! {},
     }
 
     equivalent! {
         Foo { a: Some(vec![]) },
-        Table(map! { a: Array(vec![]) }),
+        map! { a: Value::Array(vec![]) },
     }
 }
 
@@ -545,7 +545,7 @@ fn extra_keys() {
         a: isize,
     }
 
-    let toml = Table(map! { a: Integer(2), b: Integer(2) });
+    let toml = map! { a: Value::Integer(2), b: Value::Integer(2) };
     assert!(toml.clone().try_into::<Foo>().is_ok());
     assert!(toml::from_str::<Foo>(&toml.to_string()).is_ok());
 }
@@ -562,7 +562,7 @@ fn newtypes() {
 
     equivalent! {
         A { b: B(2) },
-        Table(map! { b: Integer(2) }),
+        map! { b: Value::Integer(2) },
     }
 }
 
@@ -585,13 +585,13 @@ fn newtypes2() {
 
     equivalent! {
         A { b: B(Some(C { x: 0, y: 1, z: 2 })) },
-        Table(map! {
-            b: Table(map! {
-                x: Integer(0),
-                y: Integer(1),
-                z: Integer(2)
-            })
-        }),
+        map! {
+            b: map! {
+                x: Value::Integer(0),
+                y: Value::Integer(1),
+                z: Value::Integer(2)
+            }
+        },
     }
 }
 
@@ -629,12 +629,12 @@ fn fixed_size_array() {
 
     equivalent! {
         Entity { pos: [1, 2] },
-        Table(map! {
-            pos: Array(vec![
-                Integer(1),
-                Integer(2),
+        map! {
+            pos: Value::Array(vec![
+                Value::Integer(1),
+                Value::Integer(2),
             ])
-        }),
+        },
     }
 }
 
@@ -647,13 +647,13 @@ fn homogeneous_tuple() {
 
     equivalent! {
         Collection { elems: (0, 1, 2) },
-        Table(map! {
-            elems: Array(vec![
-                Integer(0),
-                Integer(1),
-                Integer(2),
+        map! {
+            elems: Value::Array(vec![
+                Value::Integer(0),
+                Value::Integer(1),
+                Value::Integer(2),
             ])
-        }),
+        },
     }
 }
 
@@ -666,18 +666,18 @@ fn homogeneous_tuple_struct() {
         map! {
             obj: Object(vec!["foo".to_string()], vec![], vec!["bar".to_string(), "baz".to_string()])
         },
-        Table(map! {
-            obj: Array(vec![
-                Array(vec![
+        map! {
+            obj: Value::Array(vec![
+                Value::Array(vec![
                     Value::String("foo".to_string()),
                 ]),
-                Array(vec![]),
-                Array(vec![
+                Value::Array(vec![]),
+                Value::Array(vec![
                     Value::String("bar".to_string()),
                     Value::String("baz".to_string()),
                 ]),
             ])
-        }),
+        },
     }
 }