Repository: pyfisch/cbor
Pull request #115 (2019-06-08 19:15:51)

Update re-exports and improve value
Only export the [recommended items](https://serde.rs/conventions.html) from the crate root. Are there enough `to_*` and `from_*` functions exported? I think it is ok that the functions for no-std are found in the `ser` and `de` modules.

Rename all the variant names of the CBOR value to reflect the naming from the RFC more closely. Remove the distinction between I64 and U64. Always store values in canonical order. (serializing CBOR in canonical form should work now :tada: ) I removed the value test and access methods like `is_object` and `get_object`. Are they used in real projects? If this is the case I can add them back in.

What do you think?


Patch:
diff --git a/src/lib.rs b/src/lib.rs
index a809f0e..b47f5ad 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -105,7 +105,8 @@
 //! Read a general CBOR value with an unknown content.
 //!
 //! ```rust
-//! use serde_cbor::{from_slice, Value};
+//! use serde_cbor::from_slice;
+//! use serde_cbor::value::Value;
 //!
 //! let slice = b"\x82\x01\xa1aaab";
 //! let value: Value = from_slice(slice).unwrap();
@@ -184,16 +185,22 @@ mod write;
 #[cfg(feature = "std")]
 pub mod value;
 
+// Re-export the [items recommended by serde](https://serde.rs/conventions.html).
+#[doc(inline)]
+pub use crate::de::{Deserializer, StreamDeserializer};
 #[doc(inline)]
-pub use crate::de::{from_mut_slice, from_slice_with_scratch, Deserializer, StreamDeserializer};
+pub use crate::error::{Error, Result};
 #[doc(inline)]
+pub use crate::ser::Serializer;
+// Convenience functions for serialization and deserialization.
+// These functions are only available in `std` mode.
 #[cfg(feature = "std")]
-pub use crate::de::{from_reader, from_slice};
-
 #[doc(inline)]
+pub use crate::de::{from_reader, from_slice};
 #[cfg(feature = "std")]
-pub use crate::ser::{to_vec, to_vec_with_options, to_writer};
-pub use crate::ser::{Serializer, SerializerOptions};
 #[doc(inline)]
+pub use crate::ser::{to_vec, to_writer};
+// Re-export the value type like serde_json
 #[cfg(feature = "std")]
-pub use crate::value::{from_value, to_value, ObjectKey, Value};
+#[doc(inline)]
+pub use crate::value::Value;
diff --git a/src/value/de.rs b/src/value/de.rs
new file mode 100644
index 0000000..2905f3b
--- /dev/null
+++ b/src/value/de.rs
@@ -0,0 +1,155 @@
+use std::collections::BTreeMap;
+use std::fmt;
+
+use serde::de;
+
+use crate::value::Value;
+
+impl<'de> de::Deserialize<'de> for Value {
+    #[inline]
+    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
+    where
+        D: de::Deserializer<'de>,
+    {
+        struct ValueVisitor;
+
+        impl<'de> de::Visitor<'de> for ValueVisitor {
+            type Value = Value;
+
+            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.write_str("any valid CBOR value")
+            }
+
+            #[inline]
+            fn visit_str<E>(self, value: &str) -> Result<Value, E>
+            where
+                E: de::Error,
+            {
+                self.visit_string(String::from(value))
+            }
+
+            #[inline]
+            fn visit_string<E>(self, value: String) -> Result<Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Text(value))
+            }
+            #[inline]
+            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                self.visit_byte_buf(v.to_owned())
+            }
+
+            #[inline]
+            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Bytes(v))
+            }
+
+            #[inline]
+            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Integer(v.into()))
+            }
+
+            #[inline]
+            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Integer(v.into()))
+            }
+
+            #[inline]
+            fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Integer(v))
+            }
+
+            #[inline]
+            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Bool(v))
+            }
+
+            #[inline]
+            fn visit_none<E>(self) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                self.visit_unit()
+            }
+
+            #[inline]
+            fn visit_unit<E>(self) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Null)
+            }
+
+            #[inline]
+            fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+            where
+                V: de::SeqAccess<'de>,
+            {
+                let mut vec = Vec::new();
+
+                while let Some(elem) = visitor.next_element()? {
+                    vec.push(elem);
+                }
+
+                Ok(Value::Array(vec))
+            }
+
+            #[inline]
+            fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+            where
+                V: de::MapAccess<'de>,
+            {
+                let mut values = BTreeMap::new();
+
+                while let Some((key, value)) = visitor.next_entry()? {
+                    values.insert(key, value);
+                }
+
+                Ok(Value::Map(values))
+            }
+
+            #[inline]
+            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok(Value::Float(v))
+            }
+        }
+
+        deserializer.deserialize_any(ValueVisitor)
+    }
+}
+
+/// Convert a `serde_cbor::Value` into a type `T`
+#[allow(clippy::needless_pass_by_value)]
+pub fn from_value<T>(value: Value) -> Result<T, crate::error::Error>
+where
+    T: de::DeserializeOwned,
+{
+    // TODO implement in a way that doesn't require
+    // roundtrip through buffer (i.e. by implementing
+    // `serde::de::Deserializer` for `Value` and then doing
+    // `T::deserialize(value)`).
+    let buf = crate::to_vec(&value)?;
+    crate::from_slice(buf.as_slice())
+}
diff --git a/src/value/mod.rs b/src/value/mod.rs
index fa1598f..3e83c46 100644
--- a/src/value/mod.rs
+++ b/src/value/mod.rs
@@ -1,7 +1,153 @@
 //! CBOR values, keys and serialization routines.
 
-pub mod ser;
-pub mod value;
+mod de;
+mod ser;
 
+use std::cmp::{Ord, Ordering, PartialOrd};
+use std::collections::BTreeMap;
+
+#[doc(inline)]
+pub use self::de::from_value;
+#[doc(inline)]
 pub use self::ser::to_value;
-pub use self::value::{from_value, ObjectKey, Value};
+
+/// The `Value` enum, a loosely typed way of representing any valid CBOR value.
+///
+/// Maps are sorted according to the canonical ordering
+/// described in [RFC 7049 bis].
+/// Therefore values are unambiguously serialized
+/// to a canonical form of CBOR from the same RFC.
+///
+/// [RFC 7049 bis]: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-2
+#[derive(Clone, Debug)]
+pub enum Value {
+    /// Represents the absence of a value or the value undefined.
+    Null,
+    /// Represents a boolean value.
+    Bool(bool),
+    /// Integer CBOR numbers.
+    ///
+    /// The biggest value that can be represented is 2^64 - 1.
+    /// While the smallest value is -2^64.
+    /// Values outside this range can't be serialized
+    /// and will cause an error.
+    Integer(i128),
+    /// Represents a floating point value.
+    Float(f64),
+    /// Represents a byte string.
+    Bytes(Vec<u8>),
+    /// Represents an UTF-8 encoded string.
+    Text(String),
+    /// Represents an array of values.
+    Array(Vec<Value>),
+    /// Represents a map.
+    ///
+    /// Maps are also called tables, dictionaries, hashes, or objects (in JSON).
+    /// While any value can be used as a CBOR key
+    /// it is better to use only one type of key in a map
+    /// to avoid ambiguity.
+    /// If floating point values are used as keys they are compared bit-by-bit for equality.
+    /// If arrays or maps are used as keys the comparisons
+    /// to establish canonical order may be slow and therefore insertion
+    /// and retrieval of values will be slow too.
+    Map(BTreeMap<Value, Value>),
+    // The hidden variant allows the enum to be extended
+    // with variants for tags and simple values.
+    #[doc(hidden)]
+    __Hidden,
+}
+
+impl PartialEq for Value {
+    fn eq(&self, other: &Value) -> bool {
+        self.cmp(other) == Ordering::Equal
+    }
+}
+
+impl Eq for Value {}
+
+impl PartialOrd for Value {
+    fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Value {
+    fn cmp(&self, other: &Value) -> Ordering {
+        // Determine the canonical order of two values:
+        // 1. Smaller major type sorts first.
+        // 2. Shorter sequence sorts first.
+        // 3. Compare integers by magnitude.
+        // 4. Compare byte and text sequences lexically.
+        // 5. Compare the serializations of both types. (expensive)
+        use self::Value::*;
+        if self.major_type() != other.major_type() {
+            return self.major_type().cmp(&other.major_type());
+        }
+        match (self, other) {
+            (Integer(a), Integer(b)) => a.abs().cmp(&b.abs()),
+            (Bytes(a), Bytes(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+            (Text(a), Text(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+            (Array(a), Array(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+            (Map(a), Map(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+            (Bytes(a), Bytes(b)) => a.cmp(b),
+            (Text(a), Text(b)) => a.cmp(b),
+            (a, b) => {
+                let a = crate::to_vec(a).expect("self is serializable");
+                let b = crate::to_vec(b).expect("other is serializable");
+                a.cmp(&b)
+            }
+        }
+    }
+}
+
+macro_rules! impl_from {
+    ($variant:path, $for_type:ty) => {
+        impl From<$for_type> for Value {
+            fn from(v: $for_type) -> Value {
+                $variant(v.into())
+            }
+        }
+    };
+}
+
+impl_from!(Value::Bool, bool);
+impl_from!(Value::Integer, i8);
+impl_from!(Value::Integer, i16);
+impl_from!(Value::Integer, i32);
+impl_from!(Value::Integer, i64);
+// i128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Integer, u8);
+impl_from!(Value::Integer, u16);
+impl_from!(Value::Integer, u32);
+impl_from!(Value::Integer, u64);
+// u128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Float, f32);
+impl_from!(Value::Float, f64);
+impl_from!(Value::Bytes, Vec<u8>);
+impl_from!(Value::Text, String);
+// TODO: figure out if these impls should be more generic or removed.
+impl_from!(Value::Array, Vec<Value>);
+impl_from!(Value::Map, BTreeMap<Value, Value>);
+
+impl Value {
+    fn major_type(&self) -> u8 {
+        use self::Value::*;
+        match self {
+            Null => 7,
+            Bool(_) => 7,
+            Integer(v) => {
+                if *v >= 0 {
+                    0
+                } else {
+                    1
+                }
+            }
+            Float(_) => 7,
+            Bytes(_) => 2,
+            Text(_) => 3,
+            Array(_) => 4,
+            Map(_) => 5,
+            __Hidden => unreachable!(),
+        }
+    }
+}
diff --git a/src/value/ser.rs b/src/value/ser.rs
index 31db516..200c781 100644
--- a/src/value/ser.rs
+++ b/src/value/ser.rs
@@ -1,5 +1,3 @@
-//! Value serialization routines
-
 // Copyright 2017 Serde Developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
@@ -13,9 +11,28 @@ use std::collections::BTreeMap;
 use crate::error::Error;
 use serde::{self, Serialize};
 
-use crate::value::ObjectKey;
 use crate::value::Value;
 
+impl serde::Serialize for Value {
+    #[inline]
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        match *self {
+            Value::Integer(v) => serializer.serialize_i128(v),
+            Value::Bytes(ref v) => serializer.serialize_bytes(&v),
+            Value::Text(ref v) => serializer.serialize_str(&v),
+            Value::Array(ref v) => v.serialize(serializer),
+            Value::Map(ref v) => v.serialize(serializer),
+            Value::Float(v) => serializer.serialize_f64(v),
+            Value::Bool(v) => serializer.serialize_bool(v),
+            Value::Null => serializer.serialize_unit(),
+            Value::__Hidden => unreachable!(),
+        }
+    }
+}
+
 struct Serializer;
 
 impl serde::Serializer for Serializer {
@@ -50,8 +67,13 @@ impl serde::Serializer for Serializer {
         self.serialize_i64(i64::from(value))
     }
 
+    #[inline]
     fn serialize_i64(self, value: i64) -> Result<Value, Error> {
-        Ok(Value::I64(value))
+        self.serialize_i128(i128::from(value))
+    }
+
+    fn serialize_i128(self, value: i128) -> Result<Value, Error> {
+        Ok(Value::Integer(value))
     }
 
     #[inline]
@@ -71,7 +93,7 @@ impl serde::Serializer for Serializer {
 
     #[inline]
     fn serialize_u64(self, value: u64) -> Result<Value, Error> {
-        Ok(Value::U64(value))
+        Ok(Value::Integer(value.into()))
     }
 
     #[inline]
@@ -81,7 +103,7 @@ impl serde::Serializer for Serializer {
 
     #[inline]
     fn serialize_f64(self, value: f64) -> Result<Value, Error> {
-        Ok(Value::F64(value))
+        Ok(Value::Float(value))
     }
 
     #[inline]
@@ -93,7 +115,7 @@ impl serde::Serializer for Serializer {
 
     #[inline]
     fn serialize_str(self, value: &str) -> Result<Value, Error> {
-        Ok(Value::String(value.to_owned()))
+        Ok(Value::Text(value.to_owned()))
     }
 
     fn serialize_bytes(self, value: &[u8]) -> Result<Value, Error> {
@@ -143,8 +165,8 @@ impl serde::Serializer for Serializer {
         T: Serialize,
     {
         let mut values = BTreeMap::new();
-        values.insert(ObjectKey::from(variant.to_owned()), to_value(&value)?);
-        Ok(Value::Object(values))
+        values.insert(Value::from(variant.to_owned()), to_value(&value)?);
+        Ok(Value::Map(values))
     }
 
     #[inline]
@@ -220,27 +242,23 @@ impl serde::Serializer for Serializer {
     }
 }
 
-#[doc(hidden)]
 pub struct SerializeVec {
     vec: Vec<Value>,
 }
 
-#[doc(hidden)]
 pub struct SerializeTupleVariant {
     name: String,
     vec: Vec<Value>,
 }
 
-#[doc(hidden)]
 pub struct SerializeMap {
-    map: BTreeMap<ObjectKey, Value>,
-    next_key: Option<ObjectKey>,
+    map: BTreeMap<Value, Value>,
+    next_key: Option<Value>,
 }
 
-#[doc(hidden)]
 pub struct SerializeStructVariant {
     name: String,
-    map: BTreeMap<ObjectKey, Value>,
+    map: BTreeMap<Value, Value>,
 }
 
 impl serde::ser::SerializeSeq for SerializeVec {
@@ -307,9 +325,9 @@ impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
     fn end(self) -> Result<Value, Error> {
         let mut object = BTreeMap::new();
 
-        object.insert(ObjectKey::from(self.name), Value::Array(self.vec));
+        object.insert(Value::from(self.name), Value::Array(self.vec));
 
-        Ok(Value::Object(object))
+        Ok(Value::Map(object))
     }
 }
 
@@ -321,7 +339,7 @@ impl serde::ser::SerializeMap for SerializeMap {
     where
         T: Serialize,
     {
-        self.next_key = Some(ObjectKey::from(to_value(&key)?));
+        self.next_key = Some(Value::from(to_value(&key)?));
         Ok(())
     }
 
@@ -338,7 +356,7 @@ impl serde::ser::SerializeMap for SerializeMap {
     }
 
     fn end(self) -> Result<Value, Error> {
-        Ok(Value::Object(self.map))
+        Ok(Value::Map(self.map))
     }
 }
 
@@ -368,16 +386,16 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant {
         T: Serialize,
     {
         self.map
-            .insert(ObjectKey::from(String::from(key)), to_value(&value)?);
+            .insert(Value::from(String::from(key)), to_value(&value)?);
         Ok(())
     }
 
     fn end(self) -> Result<Value, Error> {
         let mut object = BTreeMap::new();
 
-        object.insert(ObjectKey::from(self.name), Value::Object(self.map));
+        object.insert(Value::from(self.name), Value::Map(self.map));
 
-        Ok(Value::Object(object))
+        Ok(Value::Map(object))
     }
 }
 
@@ -405,7 +423,7 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant {
 ///         location: "Menlo Park, CA".to_owned(),
 ///     };
 ///
-///     let v = serde_cbor::to_value(u).unwrap();
+///     let v = serde_cbor::value::to_value(u).unwrap();
 /// }
 /// ```
 #[allow(clippy::needless_pass_by_value)]
diff --git a/src/value/value.rs b/src/value/value.rs
deleted file mode 100644
index a299d2a..0000000
--- a/src/value/value.rs
+++ /dev/null
@@ -1,682 +0,0 @@
-//! CBOR values and keys.
-
-use std::cmp::{Ord, Ordering, PartialOrd};
-use std::collections::BTreeMap;
-use std::fmt;
-
-use serde::de;
-use serde::ser;
-
-/// An enum over all possible CBOR types.
-#[derive(Clone, Debug, PartialEq)]
-pub enum Value {
-    /// Represents an unsigned integer.
-    U64(u64),
-    /// Represents a signed integer.
-    I64(i64),
-    /// Represents a byte string.
-    Bytes(Vec<u8>),
-    /// Represents an UTF-8 string.
-    String(String),
-    /// Represents a list.
-    Array(Vec<Value>),
-    /// Represents a map.
-    Object(BTreeMap<ObjectKey, Value>),
-    /// Represents a floating point value.
-    F64(f64),
-    /// Represents a boolean value.
-    Bool(bool),
-    /// Represents the absence of a value or the value undefined.
-    Null,
-}
-
-impl Value {
-    /// Returns true if the value is an object.
-    pub fn is_object(&self) -> bool {
-        self.as_object().is_some()
-    }
-
-    /// If the value is an object, returns the associated BTreeMap. Returns None otherwise.
-    pub fn as_object(&self) -> Option<&BTreeMap<ObjectKey, Value>> {
-        if let Value::Object(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// If the value is an object, returns the associated mutable BTreeMap. Returns None otherwise.
-    pub fn as_object_mut(&mut self) -> Option<&mut BTreeMap<ObjectKey, Value>> {
-        if let Value::Object(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the value is an array.
-    pub fn is_array(&self) -> bool {
-        self.as_array().is_some()
-    }
-
-    /// If the value is an array, returns the associated Vec. Returns None otherwise.
-    pub fn as_array(&self) -> Option<&Vec<Value>> {
-        if let Value::Array(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// If the value is an array, returns the associated mutable Vec. Returns None otherwise.
-    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
-        if let Value::Array(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the value is a byte string.
-    pub fn is_bytes(&self) -> bool {
-        self.as_bytes().is_some()
-    }
-
-    /// Returns the associated byte string or `None` if the value has a different type.
-    pub fn as_bytes(&self) -> Option<&Vec<u8>> {
-        if let Value::Bytes(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns the associated mutable byte string or `None` if the value has a different type.
-    pub fn as_bytes_mut(&mut self) -> Option<&mut Vec<u8>> {
-        if let Value::Bytes(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the value is a string.
-    pub fn is_string(&self) -> bool {
-        self.as_string().is_some()
-    }
-
-    /// Returns the associated string or `None` if the value has a different type.
-    pub fn as_string(&self) -> Option<&String> {
-        if let Value::String(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns the associated mutable string or `None` if the value has a different type.
-    pub fn as_string_mut(&mut self) -> Option<&mut String> {
-        if let Value::String(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Retrns true if the value is a number.
-    pub fn is_number(&self) -> bool {
-        match *self {
-            Value::U64(_) | Value::I64(_) | Value::F64(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if the `Value` is a i64. Returns false otherwise.
-    pub fn is_i64(&self) -> bool {
-        match *self {
-            Value::I64(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if the `Value` is a u64. Returns false otherwise.
-    pub fn is_u64(&self) -> bool {
-        match *self {
-            Value::U64(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if the `Value` is a f64. Returns false otherwise.
-    pub fn is_f64(&self) -> bool {
-        match *self {
-            Value::F64(_) => true,
-            _ => false,
-        }
-    }
-
-    /// If the `Value` is a number, return or cast it to a i64. Returns None otherwise.
-    pub fn as_i64(&self) -> Option<i64> {
-        match *self {
-            Value::I64(n) => Some(n),
-            Value::U64(n) => Some(n as i64),
-            _ => None,
-        }
-    }
-
-    /// If the `Value` is a number, return or cast it to a u64. Returns None otherwise.
-    pub fn as_u64(&self) -> Option<u64> {
-        match *self {
-            Value::I64(n) => Some(n as u64),
-            Value::U64(n) => Some(n),
-            _ => None,
-        }
-    }
-
-    /// If the `Value` is a number, return or cast it to a f64. Returns None otherwise.
-    pub fn as_f64(&self) -> Option<f64> {
-        match *self {
-            Value::I64(n) => Some(n as f64),
-            Value::U64(n) => Some(n as f64),
-            Value::F64(n) => Some(n),
-            _ => None,
-        }
-    }
-
-    /// Returns true if the value is a boolean.
-    pub fn is_boolean(&self) -> bool {
-        self.as_boolean().is_some()
-    }
-
-    /// If the value is a Boolean, returns the associated bool. Returns None otherwise.
-    pub fn as_boolean(&self) -> Option<bool> {
-        if let Value::Bool(v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the value is a Null. Returns false otherwise.
-    pub fn is_null(&self) -> bool {
-        self.as_null().is_some()
-    }
-
-    /// If the value is a Null, returns (). Returns None otherwise.
-    pub fn as_null(&self) -> Option<()> {
-        if let Value::Null = *self {
-            Some(())
-        } else {
-            None
-        }
-    }
-}
-
-impl<'de> de::Deserialize<'de> for Value {
-    #[inline]
-    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
-    where
-        D: de::Deserializer<'de>,
-    {
-        struct ValueVisitor;
-
-        impl<'de> de::Visitor<'de> for ValueVisitor {
-            type Value = Value;
-
-            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-                fmt.write_str("any valid CBOR value")
-            }
-
-            #[inline]
-            fn visit_str<E>(self, value: &str) -> Result<Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_string(String::from(value))
-            }
-
-            #[inline]
-            fn visit_string<E>(self, value: String) -> Result<Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::String(value))
-            }
-            #[inline]
-            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_byte_buf(v.to_owned())
-            }
-
-            #[inline]
-            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::Bytes(v))
-            }
-
-            #[inline]
-            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::U64(v))
-            }
-
-            #[inline]
-            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::I64(v))
-            }
-
-            #[inline]
-            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::Bool(v))
-            }
-
-            #[inline]
-            fn visit_none<E>(self) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_unit()
-            }
-
-            #[inline]
-            fn visit_unit<E>(self) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::Null)
-            }
-
-            #[inline]
-            fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
-            where
-                V: de::SeqAccess<'de>,
-            {
-                let mut vec = Vec::new();
-
-                while let Some(elem) = visitor.next_element()? {
-                    vec.push(elem);
-                }
-
-                Ok(Value::Array(vec))
-            }
-
-            #[inline]
-            fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
-            where
-                V: de::MapAccess<'de>,
-            {
-                let mut values = BTreeMap::new();
-
-                while let Some((key, value)) = visitor.next_entry()? {
-                    values.insert(key, value);
-                }
-
-                Ok(Value::Object(values))
-            }
-
-            #[inline]
-            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(Value::F64(v))
-            }
-        }
-
-        deserializer.deserialize_any(ValueVisitor)
-    }
-}
-
-impl ser::Serialize for Value {
-    #[inline]
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: ser::Serializer,
-    {
-        match *self {
-            Value::U64(v) => serializer.serialize_u64(v),
-            Value::I64(v) => serializer.serialize_i64(v),
-            Value::Bytes(ref v) => serializer.serialize_bytes(&v),
-            Value::String(ref v) => serializer.serialize_str(&v),
-            Value::Array(ref v) => v.serialize(serializer),
-            Value::Object(ref v) => v.serialize(serializer),
-            Value::F64(v) => serializer.serialize_f64(v),
-            Value::Bool(v) => serializer.serialize_bool(v),
-            Value::Null => serializer.serialize_unit(),
-        }
-    }
-}
-
-/// A simplified CBOR value containing only types useful for keys.
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ObjectKey {
-    /// An integer.
-    Integer(i64),
-    /// A byte string.
-    Bytes(Vec<u8>),
-    /// An UTF-8 string.
-    String(String),
-    /// A boolean value.
-    Bool(bool),
-    /// No value.
-    Null,
-}
-
-impl Ord for ObjectKey {
-    fn cmp(&self, other: &ObjectKey) -> Ordering {
-        self.canonical_sort_key().cmp(&other.canonical_sort_key())
-    }
-}
-
-impl PartialOrd for ObjectKey {
-    fn partial_cmp(&self, other: &ObjectKey) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl ObjectKey {
-    // Returns a key to sort `ObjectKey`s by major type, then byte-length, then lexicographically
-    // by content. Equivalent to sorting `ObjectKey`s __lexicographically__ by their CBOR serialization.
-    //
-    // Note: the first guidelines regarding canonicalized CBOR
-    // [located here](https://tools.ietf.org/html/rfc7049#section-3.9) sorted keys by length
-    // before sorting by major type, but a [later draft](https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-4.10)
-    // has moved to a purely lexicographic ordering. This newer ordering is also used by the
-    // [WebAuthn standard](https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html#ctap2-canonical-cbor-encoding-form).
-    fn canonical_sort_key(&self) -> (u8, usize, Option<&[u8]>) {
-        use crate::ObjectKey::*;
-        match *self {
-            Integer(i) => {
-                let major_type = if i >= 0 { 0u8 } else { 1u8 };
-                let magnitude = if i >= 0 { i } else { -(i + 1) };
-                (major_type, magnitude as usize, None)
-            }
-            Bytes(ref v) => (2, v.len(), Some(v)),
-            String(ref s) => (3, s.len(), Some(s.as_bytes())),
-            Bool(b) => (7, if b { 21 } else { 20 }, None),
-            Null => (7, 22, None),
-        }
-    }
-    /// Returns true if the ObjectKey is a byte string.
-    pub fn is_bytes(&self) -> bool {
-        self.as_bytes().is_some()
-    }
-
-    /// Returns the associated byte string or `None` if the ObjectKey has a different type.
-    pub fn as_bytes(&self) -> Option<&Vec<u8>> {
-        if let ObjectKey::Bytes(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns the associated mutable byte string or `None` if the ObjectKey has a different type.
-    pub fn as_bytes_mut(&mut self) -> Option<&mut Vec<u8>> {
-        if let ObjectKey::Bytes(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the ObjectKey is a string.
-    pub fn is_string(&self) -> bool {
-        self.as_string().is_some()
-    }
-
-    /// Returns the associated string or `None` if the *ObjectKey` has a different type.
-    pub fn as_string(&self) -> Option<&String> {
-        if let ObjectKey::String(ref v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns the associated mutable string or `None` if the `ObjectKey` has a different type.
-    pub fn as_string_mut(&mut self) -> Option<&mut String> {
-        if let ObjectKey::String(ref mut v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Retrns true if the `ObjectKey` is a number.
-    pub fn is_number(&self) -> bool {
-        match *self {
-            ObjectKey::Integer(_) => true,
-            _ => false,
-        }
-    }
-
-    /// If the `ObjectKey` is a number, return or cast it to a i64. Returns None otherwise.
-    pub fn as_i64(&self) -> Option<i64> {
-        match *self {
-            ObjectKey::Integer(n) => Some(n),
-            _ => None,
-        }
-    }
-
-    /// If the `ObjectKey` is a number, return or cast it to a u64. Returns None otherwise.
-    pub fn as_u64(&self) -> Option<u64> {
-        match *self {
-            ObjectKey::Integer(n) => Some(n as u64),
-            _ => None,
-        }
-    }
-
-    /// Returns true if the ObjectKey is a boolean.
-    pub fn is_boolean(&self) -> bool {
-        self.as_boolean().is_some()
-    }
-
-    /// If the ObjectKey is a Boolean, returns the associated bool. Returns None otherwise.
-    pub fn as_boolean(&self) -> Option<bool> {
-        if let ObjectKey::Bool(v) = *self {
-            Some(v)
-        } else {
-            None
-        }
-    }
-
-    /// Returns true if the ObjectKey is a Null. Returns false otherwise.
-    pub fn is_null(&self) -> bool {
-        self.as_null().is_some()
-    }
-
-    /// If the ObjectKey is a Null, returns (). Returns None otherwise.
-    pub fn as_null(&self) -> Option<()> {
-        if let ObjectKey::Null = *self {
-            Some(())
-        } else {
-            None
-        }
-    }
-}
-
-impl<'de> de::Deserialize<'de> for ObjectKey {
-    #[inline]
-    fn deserialize<D>(deserializer: D) -> Result<ObjectKey, D::Error>
-    where
-        D: de::Deserializer<'de>,
-    {
-        struct ObjectKeyVisitor;
-
-        impl<'de> de::Visitor<'de> for ObjectKeyVisitor {
-            type Value = ObjectKey;
-
-            fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-                fmt.write_str("any valid CBOR key")
-            }
-
-            #[inline]
-            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_string(String::from(value))
-            }
-
-            #[inline]
-            fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::String(value))
-            }
-            #[inline]
-            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_byte_buf(v.to_owned())
-            }
-
-            #[inline]
-            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::Bytes(v))
-            }
-
-            #[inline]
-            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::Integer(v as i64))
-            }
-
-            #[inline]
-            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::Integer(v))
-            }
-
-            #[inline]
-            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::Bool(v))
-            }
-
-            #[inline]
-            fn visit_none<E>(self) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                self.visit_unit()
-            }
-
-            #[inline]
-            fn visit_unit<E>(self) -> Result<Self::Value, E>
-            where
-                E: de::Error,
-            {
-                Ok(ObjectKey::Null)
-            }
-        }
-
-        deserializer.deserialize_any(ObjectKeyVisitor)
-    }
-}
-
-impl ser::Serialize for ObjectKey {
-    #[inline]
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: ser::Serializer,
-    {
-        match *self {
-            ObjectKey::Integer(v) => serializer.serialize_i64(v),
-            ObjectKey::Bytes(ref v) => serializer.serialize_bytes(&v),
-            ObjectKey::String(ref v) => serializer.serialize_str(&v),
-            ObjectKey::Bool(v) => serializer.serialize_bool(v),
-            ObjectKey::Null => serializer.serialize_unit(),
-        }
-    }
-}
-
-impl From<ObjectKey> for Value {
-    fn from(key: ObjectKey) -> Value {
-        match key {
-            ObjectKey::Integer(v) => Value::I64(v),
-            ObjectKey::Bytes(v) => Value::Bytes(v),
-            ObjectKey::String(v) => Value::String(v),
-            ObjectKey::Bool(v) => Value::Bool(v),
-            ObjectKey::Null => Value::Null,
-        }
-    }
-}
-
-impl From<Value> for ObjectKey {
-    fn from(value: Value) -> ObjectKey {
-        match value {
-            Value::U64(v) => ObjectKey::Integer(v as i64),
-            Value::I64(v) => ObjectKey::Integer(v),
-            Value::Bytes(v) => ObjectKey::Bytes(v),
-            Value::String(v) => ObjectKey::String(v),
-            Value::Bool(v) => ObjectKey::Bool(v),
-            Value::Null => ObjectKey::Null,
-            _ => panic!("invalid value type for key"),
-        }
-    }
-}
-
-macro_rules! impl_from {
-    ($for_enum:ident, $variant:ident, $for_type:ty) => {
-        impl From<$for_type> for $for_enum {
-            fn from(v: $for_type) -> $for_enum {
-                $for_enum::$variant(v)
-            }
-        }
-    };
-}
-
-// All except &'a str and Cow<'a, str>
-impl_from!(ObjectKey, Integer, i64);
-impl_from!(ObjectKey, Bytes, Vec<u8>);
-impl_from!(ObjectKey, String, String);
-impl_from!(ObjectKey, Bool, bool);
-
-// All except &'a str and Cow<'a, str>
-impl_from!(Value, U64, u64);
-impl_from!(Value, I64, i64);
-impl_from!(Value, Bytes, Vec<u8>);
-impl_from!(Value, String, String);
-impl_from!(Value, Array, Vec<Value>);
-impl_from!(Value, Object, BTreeMap<ObjectKey, Value>);
-impl_from!(Value, F64, f64);
-impl_from!(Value, Bool, bool);
-
-/// Convert a `serde_cbor::Value` into a type `T`
-#[allow(clippy::needless_pass_by_value)]
-pub fn from_value<T>(value: Value) -> Result<T, crate::error::Error>
-where
-    T: de::DeserializeOwned,
-{
-    // TODO implement in a way that doesn't require
-    // roundtrip through buffer (i.e. by implementing
-    // `serde::de::Deserializer` for `Value` and then doing
-    // `T::deserialize(value)`).
-    let buf = crate::to_vec(&value)?;
-    crate::from_slice(buf.as_slice())
-}


Test patch:
diff --git a/tests/bennofs.rs b/tests/bennofs.rs
index 93ce525..3ada587 100644
--- a/tests/bennofs.rs
+++ b/tests/bennofs.rs
@@ -54,6 +54,6 @@ fn test() {
     let end = writer.bytes_written();
     let slice = writer.into_inner();
     let deserialized: Example =
-        serde_cbor::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+        serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
     assert_eq!(EXAMPLE, deserialized);
 }
diff --git a/tests/canonical.rs b/tests/canonical.rs
index 2ad9287..578aa02 100644
--- a/tests/canonical.rs
+++ b/tests/canonical.rs
@@ -1,6 +1,6 @@
 #[cfg(feature = "std")]
 mod std_tests {
-    use serde_cbor::ObjectKey;
+    use serde_cbor::value::Value;
 
     #[test]
     fn integer_canonical_sort_order() {
@@ -23,7 +23,7 @@ mod std_tests {
             -4294967296,
         ]
         .into_iter()
-        .map(|i| ObjectKey::Integer(*i))
+        .map(|i| Value::Integer(*i))
         .collect::<Vec<_>>();
 
         let mut sorted = expected.clone();
@@ -36,7 +36,7 @@ mod std_tests {
     fn string_canonical_sort_order() {
         let expected = ["", "a", "b", "aa"]
             .into_iter()
-            .map(|s| ObjectKey::String(s.to_string()))
+            .map(|s| Value::Text(s.to_string()))
             .collect::<Vec<_>>();
 
         let mut sorted = expected.clone();
@@ -49,7 +49,7 @@ mod std_tests {
     fn bytes_canonical_sort_order() {
         let expected = vec![vec![], vec![0u8], vec![1u8], vec![0u8, 0u8]]
             .into_iter()
-            .map(|v| ObjectKey::Bytes(v))
+            .map(|v| Value::Bytes(v))
             .collect::<Vec<_>>();
 
         let mut sorted = expected.clone();
@@ -60,11 +60,7 @@ mod std_tests {
 
     #[test]
     fn simple_data_canonical_sort_order() {
-        let expected = vec![
-            ObjectKey::Bool(false),
-            ObjectKey::Bool(true),
-            ObjectKey::Null,
-        ];
+        let expected = vec![Value::Bool(false), Value::Bool(true), Value::Null];
 
         let mut sorted = expected.clone();
         sorted.sort();
@@ -75,18 +71,34 @@ mod std_tests {
     #[test]
     fn major_type_canonical_sort_order() {
         let expected = vec![
-            ObjectKey::Integer(0),
-            ObjectKey::Integer(-1),
-            ObjectKey::Bytes(vec![]),
-            ObjectKey::String("".to_string()),
-            ObjectKey::Null,
-        ]
-        .into_iter()
-        .collect::<Vec<_>>();
+            Value::Integer(0),
+            Value::Integer(-1),
+            Value::Bytes(vec![]),
+            Value::Text("".to_string()),
+            Value::Null,
+        ];
 
         let mut sorted = expected.clone();
         sorted.sort();
 
         assert_eq!(expected, sorted);
     }
+
+    #[test]
+    fn test_rfc_example() {
+        // See: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-4.10
+        let expected = vec![
+            Value::Integer(10),
+            Value::Integer(100),
+            Value::Integer(-1),
+            Value::Text("z".to_owned()),
+            Value::Text("aa".to_owned()),
+            Value::Array(vec![Value::Integer(100)]),
+            Value::Array(vec![Value::Integer(-1)]),
+            Value::Bool(false),
+        ];
+        let mut sorted = expected.clone();
+        sorted.sort();
+        assert_eq!(expected, sorted);
+    }
 }
diff --git a/tests/de.rs b/tests/de.rs
index 5066593..6d5d6b8 100644
--- a/tests/de.rs
+++ b/tests/de.rs
@@ -48,13 +48,14 @@ mod std_tests {
     use std::collections::BTreeMap;
 
     use serde::de as serde_de;
-    use serde_cbor::{de, error, to_vec, Deserializer, ObjectKey, Value};
+    use serde_cbor::value::Value;
+    use serde_cbor::{de, error, to_vec, Deserializer};
 
     #[test]
     fn test_string1() {
         let value: error::Result<Value> =
             de::from_slice(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
-        assert_eq!(value.unwrap(), Value::String("foobar".to_owned()));
+        assert_eq!(value.unwrap(), Value::Text("foobar".to_owned()));
     }
 
     #[test]
@@ -63,10 +64,7 @@ mod std_tests {
             0x71, 0x49, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x76, 0x65,
             0x6c, 0x6c, 0x65, 0x72,
         ]);
-        assert_eq!(
-            value.unwrap(),
-            Value::String("I met a traveller".to_owned())
-        );
+        assert_eq!(value.unwrap(), Value::Text("I met a traveller".to_owned()));
     }
 
     #[test]
@@ -75,7 +73,7 @@ mod std_tests {
         let value: error::Result<Value> = de::from_slice(slice);
         assert_eq!(
             value.unwrap(),
-            Value::String("I met a traveller from an antique land who said".to_owned())
+            Value::Text("I met a traveller from an antique land who said".to_owned())
         );
     }
 
@@ -89,19 +87,19 @@ mod std_tests {
     #[test]
     fn test_numbers1() {
         let value: error::Result<Value> = de::from_slice(&[0x00]);
-        assert_eq!(value.unwrap(), Value::U64(0));
+        assert_eq!(value.unwrap(), Value::Integer(0));
     }
 
     #[test]
     fn test_numbers2() {
         let value: error::Result<Value> = de::from_slice(&[0x1a, 0x00, 0xbc, 0x61, 0x4e]);
-        assert_eq!(value.unwrap(), Value::U64(12345678));
+        assert_eq!(value.unwrap(), Value::Integer(12345678));
     }
 
     #[test]
     fn test_numbers3() {
         let value: error::Result<Value> = de::from_slice(&[0x39, 0x07, 0xde]);
-        assert_eq!(value.unwrap(), Value::I64(-2015));
+        assert_eq!(value.unwrap(), Value::Integer(-2015));
     }
 
     #[test]
@@ -121,7 +119,11 @@ mod std_tests {
         let value: error::Result<Value> = de::from_slice(b"\x83\x01\x02\x03");
         assert_eq!(
             value.unwrap(),
-            Value::Array(vec![Value::U64(1), Value::U64(2), Value::U64(3)])
+            Value::Array(vec![
+                Value::Integer(1),
+                Value::Integer(2),
+                Value::Integer(3)
+            ])
         );
     }
 
@@ -131,8 +133,11 @@ mod std_tests {
         assert_eq!(
             value.unwrap(),
             Value::Array(vec![
-                Value::U64(1),
-                Value::Array(vec![Value::U64(2), Value::Array(vec![Value::U64(3)])])
+                Value::Integer(1),
+                Value::Array(vec![
+                    Value::Integer(2),
+                    Value::Array(vec![Value::Integer(3)])
+                ])
             ])
         );
     }
@@ -141,39 +146,24 @@ mod std_tests {
     fn test_object() {
         let value: error::Result<Value> = de::from_slice(b"\xa5aaaAabaBacaCadaDaeaE");
         let mut object = BTreeMap::new();
-        object.insert(
-            ObjectKey::String("a".to_owned()),
-            Value::String("A".to_owned()),
-        );
-        object.insert(
-            ObjectKey::String("b".to_owned()),
-            Value::String("B".to_owned()),
-        );
-        object.insert(
-            ObjectKey::String("c".to_owned()),
-            Value::String("C".to_owned()),
-        );
-        object.insert(
-            ObjectKey::String("d".to_owned()),
-            Value::String("D".to_owned()),
-        );
-        object.insert(
-            ObjectKey::String("e".to_owned()),
-            Value::String("E".to_owned()),
-        );
-        assert_eq!(value.unwrap(), Value::Object(object));
+        object.insert(Value::Text("a".to_owned()), Value::Text("A".to_owned()));
+        object.insert(Value::Text("b".to_owned()), Value::Text("B".to_owned()));
+        object.insert(Value::Text("c".to_owned()), Value::Text("C".to_owned()));
+        object.insert(Value::Text("d".to_owned()), Value::Text("D".to_owned()));
+        object.insert(Value::Text("e".to_owned()), Value::Text("E".to_owned()));
+        assert_eq!(value.unwrap(), Value::Map(object));
     }
 
     #[test]
     fn test_indefinite_object() {
         let value: error::Result<Value> = de::from_slice(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff");
         let mut object = BTreeMap::new();
-        object.insert(ObjectKey::String("a".to_owned()), Value::U64(1));
+        object.insert(Value::Text("a".to_owned()), Value::Integer(1));
         object.insert(
-            ObjectKey::String("b".to_owned()),
-            Value::Array(vec![Value::U64(2), Value::U64(3)]),
+            Value::Text("b".to_owned()),
+            Value::Array(vec![Value::Integer(2), Value::Integer(3)]),
         );
-        assert_eq!(value.unwrap(), Value::Object(object));
+        assert_eq!(value.unwrap(), Value::Map(object));
     }
 
     #[test]
@@ -181,7 +171,11 @@ mod std_tests {
         let value: error::Result<Value> = de::from_slice(b"\x9f\x01\x02\x03\xff");
         assert_eq!(
             value.unwrap(),
-            Value::Array(vec![Value::U64(1), Value::U64(2), Value::U64(3)])
+            Value::Array(vec![
+                Value::Integer(1),
+                Value::Integer(2),
+                Value::Integer(3)
+            ])
         );
     }
 
@@ -191,7 +185,7 @@ mod std_tests {
             de::from_slice(b"\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff");
         assert_eq!(
             value.unwrap(),
-            Value::String("Mary Had a Little Lamb".to_owned())
+            Value::Text("Mary Had a Little Lamb".to_owned())
         );
     }
 
@@ -214,7 +208,7 @@ mod std_tests {
         assert_eq!(
             value.unwrap(),
             Value::Array(vec![
-                Value::String("Mary Had a Little Lamb".to_owned()),
+                Value::Text("Mary Had a Little Lamb".to_owned()),
                 Value::Bytes(b"\x01#Eg".to_vec())
             ])
         );
@@ -223,26 +217,26 @@ mod std_tests {
     #[test]
     fn test_float() {
         let value: error::Result<Value> = de::from_slice(b"\xfa\x47\xc3\x50\x00");
-        assert_eq!(value.unwrap(), Value::F64(100000.0));
+        assert_eq!(value.unwrap(), Value::Float(100000.0));
     }
 
     #[test]
     fn test_self_describing() {
         let value: error::Result<Value> =
             de::from_slice(&[0xd9, 0xd9, 0xf7, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
-        assert_eq!(value.unwrap(), Value::String("foobar".to_owned()));
+        assert_eq!(value.unwrap(), Value::Text("foobar".to_owned()));
     }
 
     #[test]
     fn test_f16() {
         let mut x: Value = de::from_slice(&[0xf9, 0x41, 0x00]).unwrap();
-        assert_eq!(x, Value::F64(2.5));
+        assert_eq!(x, Value::Float(2.5));
         x = de::from_slice(&[0xf9, 0x41, 0x90]).unwrap();
-        assert_eq!(x, Value::F64(2.78125));
+        assert_eq!(x, Value::Float(2.78125));
         x = de::from_slice(&[0xf9, 0x50, 0x90]).unwrap();
-        assert_eq!(x, Value::F64(36.5));
+        assert_eq!(x, Value::Float(36.5));
         x = de::from_slice(&[0xf9, 0xd0, 0x90]).unwrap();
-        assert_eq!(x, Value::F64(-36.5));
+        assert_eq!(x, Value::Float(-36.5));
     }
 
     #[test]
@@ -252,14 +246,14 @@ mod std_tests {
         assert_eq!(
             value,
             vec![
-                Value::U64(123456789959),
-                Value::I64(-34567897654325468),
-                Value::I64(-456787678),
+                Value::Integer(123456789959),
+                Value::Integer(-34567897654325468),
+                Value::Integer(-456787678),
                 Value::Bool(true),
                 Value::Null,
                 Value::Null,
-                Value::F64(23456543.5),
-                Value::F64(::std::f64::INFINITY)
+                Value::Float(23456543.5),
+                Value::Float(::std::f64::INFINITY)
             ]
         );
     }
@@ -313,10 +307,10 @@ mod std_tests {
         let value: Value = de::from_slice(slice).unwrap();
         let mut map = BTreeMap::new();
         map.insert(
-            ObjectKey::String("message".to_string()),
-            Value::String("pong".to_string()),
+            Value::Text("message".to_string()),
+            Value::Text("pong".to_string()),
         );
-        assert_eq!(value, Value::Object(map))
+        assert_eq!(value, Value::Map(map))
     }
 
     #[test]
@@ -336,9 +330,9 @@ mod std_tests {
     fn stream_deserializer() {
         let slice = b"\x01\x66foobar";
         let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
-        assert_eq!(Value::U64(1), it.next().unwrap().unwrap());
+        assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
         assert_eq!(
-            Value::String("foobar".to_string()),
+            Value::Text("foobar".to_string()),
             it.next().unwrap().unwrap()
         );
         assert!(it.next().is_none());
@@ -348,7 +342,7 @@ mod std_tests {
     fn stream_deserializer_eof() {
         let slice = b"\x01\x66foob";
         let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
-        assert_eq!(Value::U64(1), it.next().unwrap().unwrap());
+        assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
         assert!(it.next().unwrap().unwrap_err().is_eof());
     }
 
diff --git a/tests/enum.rs b/tests/enum.rs
index ed8bdfa..36a0b09 100644
--- a/tests/enum.rs
+++ b/tests/enum.rs
@@ -23,7 +23,7 @@ fn test_simple_data_enum_roundtrip() {
     let end = writer.bytes_written();
     let slice = writer.into_inner();
     let deserialized: DataEnum =
-        serde_cbor::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+        serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
     assert_eq!(a, deserialized);
 }
 
@@ -31,7 +31,8 @@ fn test_simple_data_enum_roundtrip() {
 mod std_tests {
     use std::collections::BTreeMap;
 
-    use serde_cbor::{from_slice, to_vec, ObjectKey, Value};
+    use serde_cbor::value::Value;
+    use serde_cbor::{from_slice, to_vec};
 
     #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
     enum Enum {
@@ -145,14 +146,14 @@ mod std_tests {
 
         // tuple-variants serialize like ["<variant>", values..]
         let number_s = to_vec(&Bar::Number(42)).unwrap();
-        let number_vec = vec![Value::String("Number".to_string()), Value::I64(42)];
+        let number_vec = vec![Value::Text("Number".to_string()), Value::Integer(42)];
         let number_vec_s = to_vec(&number_vec).unwrap();
         assert_eq!(number_s, number_vec_s);
 
         let flag_s = to_vec(&Bar::Flag("foo".to_string(), true)).unwrap();
         let flag_vec = vec![
-            Value::String("Flag".to_string()),
-            Value::String("foo".to_string()),
+            Value::Text("Flag".to_string()),
+            Value::Text("foo".to_string()),
             Value::Bool(true),
         ];
         let flag_vec_s = to_vec(&flag_vec).unwrap();
@@ -161,17 +162,17 @@ mod std_tests {
         // struct-variants serialize like ["<variant>", {struct..}]
         let point_s = to_vec(&Bar::Point { x: 5, y: -5 }).unwrap();
         let mut struct_map = BTreeMap::new();
-        struct_map.insert(ObjectKey::String("x".to_string()), Value::I64(5));
-        struct_map.insert(ObjectKey::String("y".to_string()), Value::I64(-5));
+        struct_map.insert(Value::Text("x".to_string()), Value::Integer(5));
+        struct_map.insert(Value::Text("y".to_string()), Value::Integer(-5));
         let point_vec = vec![
-            Value::String("Point".to_string()),
-            Value::Object(struct_map.clone()),
+            Value::Text("Point".to_string()),
+            Value::Map(struct_map.clone()),
         ];
         let point_vec_s = to_vec(&point_vec).unwrap();
         assert_eq!(point_s, point_vec_s);
 
         // enum_as_map matches serde_json's default serialization for enums.
-        let opts = serde_cbor::SerializerOptions {
+        let opts = serde_cbor::ser::SerializerOptions {
             enum_as_map: true,
             ..Default::default()
         };
@@ -192,7 +193,7 @@ mod std_tests {
         let mut flag_map = BTreeMap::new();
         flag_map.insert(
             "Flag",
-            vec![Value::String("foo".to_string()), Value::Bool(true)],
+            vec![Value::Text("foo".to_string()), Value::Bool(true)],
         );
         let flag_map_s = to_vec(&flag_map).unwrap();
         assert_eq!(flag_s, flag_map_s);
@@ -200,7 +201,7 @@ mod std_tests {
         // struct-variants serialize like {"<variant>", {struct..}}
         let point_s = opts.to_vec(&Bar::Point { x: 5, y: -5 }).unwrap();
         let mut point_map = BTreeMap::new();
-        point_map.insert("Point", Value::Object(struct_map));
+        point_map.insert("Point", Value::Map(struct_map));
         let point_map_s = to_vec(&point_map).unwrap();
         assert_eq!(point_s, point_map_s);
 
diff --git a/tests/std_types.rs b/tests/std_types.rs
index 3f61727..d226836 100644
--- a/tests/std_types.rs
+++ b/tests/std_types.rs
@@ -5,8 +5,9 @@ extern crate serde_derive;
 mod std_tests {
     use std::u8;
 
+    use serde_cbor::de::from_mut_slice;
     use serde_cbor::ser::{to_vec, to_vec_packed};
-    use serde_cbor::{from_mut_slice, from_reader, from_slice};
+    use serde_cbor::{from_reader, from_slice};
 
     fn to_binary(s: &'static str) -> Vec<u8> {
         assert!(s.len() % 2 == 0);
diff --git a/tests/value.rs b/tests/value.rs
index 9d46f38..6714069 100644
--- a/tests/value.rs
+++ b/tests/value.rs
@@ -23,7 +23,7 @@ mod std_tests {
         unit_array: Vec<UnitStruct>,
     }
 
-    use serde_cbor::Value;
+    use serde_cbor::value::Value;
     use std::iter::FromIterator;
 
     #[test]
@@ -57,17 +57,22 @@ mod std_tests {
             unit_array,
         };
 
-        let value = serde_cbor::to_value(data.clone()).unwrap();
+        let value = serde_cbor::value::to_value(data.clone()).unwrap();
         println!("{:?}", value);
 
         let data_ser = serde_cbor::to_vec(&value).unwrap();
         let data_de_value: Value = serde_cbor::from_slice(&data_ser).unwrap();
 
-        for ((k1, v1), (k2, v2)) in value
-            .as_object()
-            .unwrap()
+        fn as_object(value: &Value) -> &BTreeMap<Value, Value> {
+            if let Value::Map(ref v) = value {
+                return v;
+            }
+            panic!()
+        }
+
+        for ((k1, v1), (k2, v2)) in as_object(&value)
             .iter()
-            .zip(data_de_value.as_object().unwrap().iter())
+            .zip(as_object(&data_de_value).iter())
         {
             assert_eq!(k1, k2);
             assert_eq!(v1, v2);