Repository: ron-rs/ron
Pull request #228 (2020-05-08 18:06:16)

Fix parsing of borrowed strings
The implementation of `deserialize_str` would incorrectly call `Visitor::visit_str` when it should have called `Visitor::visit_borrowed_str`. As per https://serde.rs/lifetimes.html#transient-borrowed-and-owned-data, `visit_borrowed_str` should be called when the lifetime of the deserialized string is that of the input.

This should not be a breaking change, because it only extends the lifetime of the deserialized string. The default implementation of `Visitor::visit_borrowed_str` forwards to `visit_str`, meaning that this commit only enables more flexibility.

I added a test in `tests/borrowed_str.rs` which demonstrates this behavior. Prior to this change, the test would fail.


Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
deleted file mode 100644
index 889fa719..00000000
--- a/.github/workflows/ci.yaml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: CI
-on: [push, pull_request]
-
-jobs:
-
-  tests:
-    name: Tests
-    runs-on: ubuntu-latest
-
-    strategy:
-      matrix:
-        rust: [stable, nightly]
-
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions-rs/toolchain@v1
-        with:
-          toolchain: ${{ matrix.rust }}
-          profile: minimal
-          override: true
-      - run: cargo test
-      - run: cargo test --all-features
-
-  clippy:
-    name: "Clippy: stable"
-    runs-on: ubuntu-latest
-    continue-on-error: true
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions-rs/toolchain@v1
-        with:
-          toolchain: stable
-          profile: minimal
-          components: clippy
-          override: true
-      - uses: actions-rs/clippy-check@v1
-        with:
-          token: ${{ github.token }}
-  
-  rustfmt:
-    name: "Format: stable"
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - uses: actions-rs/toolchain@v1
-        with:
-          toolchain: stable
-          profile: minimal
-          components: rustfmt
-          override: true
-      - run: cargo fmt -- --check
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..177f0224
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,33 @@
+language: rust
+
+rust:
+  - stable
+  - nightly
+
+branches:
+  only:
+    - staging
+    - trying
+    - master
+
+matrix:
+  allow_failures:
+    - name: "Clippy: stable"
+  include:
+    - rust: stable
+      name: "Format: stable"
+      script:
+        - rustup component add rustfmt
+        - cargo fmt -- --check
+    - rust: stable
+      name: "Clippy: stable"
+      script:
+        - rustup component add clippy
+        - cargo clippy
+
+cache: cargo
+
+script:
+  - cargo test
+  - cargo test --all-features
+
diff --git a/Cargo.toml b/Cargo.toml
index 45ef2774..1c8d753b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,6 @@ version = "0.5.2"
 license = "MIT/Apache-2.0"
 keywords = ["parser", "serde", "serialization"]
 authors = [
-	"Christopher Durham <cad97@cad97.com>",
 	"Dzmitry Malyshau <kvarkus@gmail.com>",
 	"Thomas Schaller <torkleyy@gmail.com>",
 ]
@@ -22,9 +21,9 @@ name = "ron"
 
 [dependencies]
 base64 = "0.12"
-bitflags = "1.0.4"
+bitflags = "1"
 indexmap = { version = "1.0.2", features = ["serde-1"], optional = true }
-serde = { version = "1.0.60", features = ["serde_derive"] }
+serde = { version = "1", features = ["serde_derive"] }
 
 [dev-dependencies]
 serde_bytes = "0.11"
diff --git a/bors.toml b/bors.toml
index c7a9625f..5c15d322 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,7 +1,5 @@
 status = [
-  "Tests (stable)",
-  "Tests (nightly)",
-  "Format: stable",
+  "continuous-integration/travis-ci/push",
 ]
 
 block_labels = [
diff --git a/src/de/error.rs b/src/de/error.rs
new file mode 100644
index 00000000..3794cc4d
--- /dev/null
+++ b/src/de/error.rs
@@ -0,0 +1,100 @@
+use serde::de;
+use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
+
+use crate::parse::Position;
+
+/// Deserialization result.
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum Error {
+    IoError(String),
+    Message(String),
+    Parser(ParseError, Position),
+}
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum ParseError {
+    Base64Error(base64::DecodeError),
+    Eof,
+    ExpectedArray,
+    ExpectedArrayEnd,
+    ExpectedAttribute,
+    ExpectedAttributeEnd,
+    ExpectedBoolean,
+    ExpectedComma,
+    ExpectedEnum,
+    ExpectedChar,
+    ExpectedFloat,
+    ExpectedInteger,
+    ExpectedOption,
+    ExpectedOptionEnd,
+    ExpectedMap,
+    ExpectedMapColon,
+    ExpectedMapEnd,
+    ExpectedStruct,
+    ExpectedStructEnd,
+    ExpectedUnit,
+    ExpectedStructName,
+    ExpectedString,
+    ExpectedStringEnd,
+    ExpectedIdentifier,
+
+    InvalidEscape(&'static str),
+
+    IntegerOutOfBounds,
+
+    NoSuchExtension(String),
+
+    UnclosedBlockComment,
+    UnderscoreAtBeginning,
+    UnexpectedByte(char),
+
+    Utf8Error(Utf8Error),
+    TrailingCharacters,
+
+    #[doc(hidden)]
+    __NonExhaustive,
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            Error::IoError(ref s) => write!(f, "{}", s),
+            Error::Message(ref s) => write!(f, "{}", s),
+            Error::Parser(_, pos) => write!(f, "{}: {}", pos, self),
+        }
+    }
+}
+
+impl de::Error for Error {
+    fn custom<T: fmt::Display>(msg: T) -> Self {
+        Error::Message(msg.to_string())
+    }
+}
+
+impl StdError for Error {}
+
+impl From<Utf8Error> for ParseError {
+    fn from(e: Utf8Error) -> Self {
+        ParseError::Utf8Error(e)
+    }
+}
+
+impl From<FromUtf8Error> for ParseError {
+    fn from(e: FromUtf8Error) -> Self {
+        ParseError::Utf8Error(e.utf8_error())
+    }
+}
+
+impl From<Utf8Error> for Error {
+    fn from(e: Utf8Error) -> Self {
+        Error::Parser(ParseError::Utf8Error(e), Position { line: 0, col: 0 })
+    }
+}
+
+impl From<io::Error> for Error {
+    fn from(e: io::Error) -> Self {
+        Error::IoError(e.to_string())
+    }
+}
diff --git a/src/de/id.rs b/src/de/id.rs
index b8d7d59f..d7e242c8 100644
--- a/src/de/id.rs
+++ b/src/de/id.rs
@@ -71,13 +71,6 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> {
         unimplemented!("IdDeserializer may only be used for identifiers")
     }
 
-    fn deserialize_i128<V>(self, _: V) -> Result<V::Value>
-    where
-        V: Visitor<'b>,
-    {
-        unimplemented!("IdDeserializer may only be used for identifiers")
-    }
-
     fn deserialize_u8<V>(self, _: V) -> Result<V::Value>
     where
         V: Visitor<'b>,
@@ -106,13 +99,6 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> {
         unimplemented!("IdDeserializer may only be used for identifiers")
     }
 
-    fn deserialize_u128<V>(self, _: V) -> Result<V::Value>
-    where
-        V: Visitor<'b>,
-    {
-        unimplemented!("IdDeserializer may only be used for identifiers")
-    }
-
     fn deserialize_f32<V>(self, _: V) -> Result<V::Value>
     where
         V: Visitor<'b>,
diff --git a/src/de/mod.rs b/src/de/mod.rs
index 14cd9af6..96b730ee 100644
--- a/src/de/mod.rs
+++ b/src/de/mod.rs
@@ -1,16 +1,16 @@
 /// Deserialization module.
-pub use crate::error::{Error, ErrorCode, Result};
+pub use self::error::{Error, ParseError, Result};
 pub use crate::parse::Position;
 
 use serde::de::{self, DeserializeSeed, Deserializer as SerdeError, Visitor};
 use std::{borrow::Cow, io, str};
 
-use self::{id::IdDeserializer, tag::TagDeserializer};
-use crate::{
-    extensions::Extensions,
-    parse::{AnyNum, Bytes, ParsedStr},
-};
+use self::id::IdDeserializer;
+use self::tag::TagDeserializer;
+use crate::extensions::Extensions;
+use crate::parse::{AnyNum, Bytes, ParsedStr};
 
+mod error;
 mod id;
 mod tag;
 #[cfg(test)]
@@ -88,7 +88,7 @@ impl<'de> Deserializer<'de> {
         if self.bytes.bytes().is_empty() {
             Ok(())
         } else {
-            self.bytes.err(ErrorCode::TrailingCharacters)
+            self.bytes.err(ParseError::TrailingCharacters)
         }
     }
 
@@ -172,14 +172,12 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
                     AnyNum::U32(x) => visitor.visit_u32(x),
                     AnyNum::I64(x) => visitor.visit_i64(x),
                     AnyNum::U64(x) => visitor.visit_u64(x),
-                    AnyNum::I128(x) => visitor.visit_i128(x),
-                    AnyNum::U128(x) => visitor.visit_u128(x),
                 }
             }
             b'.' => self.deserialize_f64(visitor),
             b'"' | b'r' => self.deserialize_string(visitor),
             b'\'' => self.deserialize_char(visitor),
-            other => self.bytes.err(ErrorCode::UnexpectedByte(other as char)),
+            other => self.bytes.err(ParseError::UnexpectedByte(other as char)),
         }
     }
 
@@ -218,13 +216,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
         visitor.visit_i64(self.bytes.signed_integer()?)
     }
 
-    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
-    where
-        V: Visitor<'de>,
-    {
-        visitor.visit_i128(self.bytes.signed_integer()?)
-    }
-
     fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
     where
         V: Visitor<'de>,
@@ -253,13 +244,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
         visitor.visit_u64(self.bytes.unsigned_integer()?)
     }
 
-    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
-    where
-        V: Visitor<'de>,
-    {
-        visitor.visit_u128(self.bytes.unsigned_integer()?)
-    }
-
     fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
     where
         V: Visitor<'de>,
@@ -287,7 +271,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
     {
         match self.bytes.string()? {
             ParsedStr::Allocated(s) => visitor.visit_string(s),
-            ParsedStr::Slice(s) => visitor.visit_str(s),
+            ParsedStr::Slice(s) => visitor.visit_borrowed_str(s),
         }
     }
 
@@ -320,7 +304,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
 
         match res {
             Ok(byte_buf) => visitor.visit_byte_buf(byte_buf),
-            Err(err) => self.bytes.err(ErrorCode::Base64Error(err)),
+            Err(err) => self.bytes.err(ParseError::Base64Error(err)),
         }
     }
 
@@ -345,10 +329,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume(")") {
                 Ok(v)
             } else {
-                self.bytes.err(ErrorCode::ExpectedOptionEnd)
+                self.bytes.err(ParseError::ExpectedOptionEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedOption)
+            self.bytes.err(ParseError::ExpectedOption)
         }
     }
 
@@ -360,7 +344,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
         if self.bytes.consume("()") {
             visitor.visit_unit()
         } else {
-            self.bytes.err(ErrorCode::ExpectedUnit)
+            self.bytes.err(ParseError::ExpectedUnit)
         }
     }
 
@@ -395,10 +379,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume(")") {
                 Ok(value)
             } else {
-                self.bytes.err(ErrorCode::ExpectedStructEnd)
+                self.bytes.err(ParseError::ExpectedStructEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedStruct)
+            self.bytes.err(ParseError::ExpectedStruct)
         }
     }
 
@@ -413,10 +397,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume("]") {
                 Ok(value)
             } else {
-                self.bytes.err(ErrorCode::ExpectedArrayEnd)
+                self.bytes.err(ParseError::ExpectedArrayEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedArray)
+            self.bytes.err(ParseError::ExpectedArray)
         }
     }
 
@@ -431,10 +415,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume(")") {
                 Ok(value)
             } else {
-                self.bytes.err(ErrorCode::ExpectedArrayEnd)
+                self.bytes.err(ParseError::ExpectedArrayEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedArray)
+            self.bytes.err(ParseError::ExpectedArray)
         }
     }
 
@@ -462,10 +446,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume("}") {
                 Ok(value)
             } else {
-                self.bytes.err(ErrorCode::ExpectedMapEnd)
+                self.bytes.err(ParseError::ExpectedMapEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedMap)
+            self.bytes.err(ParseError::ExpectedMap)
         }
     }
 
@@ -489,10 +473,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
             if self.bytes.consume(")") {
                 Ok(value)
             } else {
-                self.bytes.err(ErrorCode::ExpectedStructEnd)
+                self.bytes.err(ParseError::ExpectedStructEnd)
             }
         } else {
-            self.bytes.err(ErrorCode::ExpectedStruct)
+            self.bytes.err(ParseError::ExpectedStruct)
         }
     }
 
@@ -540,7 +524,7 @@ impl<'a, 'de> CommaSeparated<'a, 'de> {
         }
     }
 
-    fn err<T>(&self, kind: ErrorCode) -> Result<T> {
+    fn err<T>(&self, kind: ParseError) -> Result<T> {
         self.de.bytes.err(kind)
     }
 
@@ -604,7 +588,7 @@ impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> {
 
             Ok(res)
         } else {
-            self.err(ErrorCode::ExpectedMapColon)
+            self.err(ParseError::ExpectedMapColon)
         }
     }
 }
@@ -658,10 +642,10 @@ impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
             if self.de.bytes.consume(")") {
                 Ok(val)
             } else {
-                self.de.bytes.err(ErrorCode::ExpectedStructEnd)
+                self.de.bytes.err(ParseError::ExpectedStructEnd)
             }
         } else {
-            self.de.bytes.err(ErrorCode::ExpectedStruct)
+            self.de.bytes.err(ParseError::ExpectedStruct)
         }
     }
 
diff --git a/src/de/tag.rs b/src/de/tag.rs
index 76a8bb79..08086671 100644
--- a/src/de/tag.rs
+++ b/src/de/tag.rs
@@ -71,13 +71,6 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> {
         self.d.deserialize_i64(visitor)
     }
 
-    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
-    where
-        V: Visitor<'b>,
-    {
-        self.d.deserialize_i128(visitor)
-    }
-
     fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
     where
         V: Visitor<'b>,
@@ -106,13 +99,6 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> {
         self.d.deserialize_u64(visitor)
     }
 
-    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
-    where
-        V: Visitor<'b>,
-    {
-        self.d.deserialize_u128(visitor)
-    }
-
     fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
     where
         V: Visitor<'b>,
diff --git a/src/de/value.rs b/src/de/value.rs
index 92acca20..da4c6176 100644
--- a/src/de/value.rs
+++ b/src/de/value.rs
@@ -50,13 +50,6 @@ impl<'de> Visitor<'de> for ValueVisitor {
     }
 
     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
-    where
-        E: Error,
-    {
-        Ok(Value::Number(Number::new(v)))
-    }
-
-    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
     where
         E: Error,
     {
@@ -64,13 +57,6 @@ impl<'de> Visitor<'de> for ValueVisitor {
     }
 
     fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
-    where
-        E: Error,
-    {
-        Ok(Value::Number(Number::new(v)))
-    }
-
-    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
     where
         E: Error,
     {
@@ -205,9 +191,9 @@ mod tests {
     #[test]
     fn test_tuples_basic() {
         assert_eq!(
-            eval("(3, 4.0, 5.0)"),
+            eval("(3, 4, 5)"),
             Value::Seq(vec![
-                Value::Number(Number::new(3)),
+                Value::Number(Number::new(3.0)),
                 Value::Number(Number::new(4.0)),
                 Value::Number(Number::new(5.0)),
             ],),
@@ -217,11 +203,11 @@ mod tests {
     #[test]
     fn test_tuples_ident() {
         assert_eq!(
-            eval("(true, 3, 4, 5.0)"),
+            eval("(true, 3, 4, 5)"),
             Value::Seq(vec![
                 Value::Bool(true),
-                Value::Number(Number::new(3)),
-                Value::Number(Number::new(4)),
+                Value::Number(Number::new(3.0)),
+                Value::Number(Number::new(4.0)),
                 Value::Number(Number::new(5.0)),
             ]),
         );
@@ -229,14 +215,11 @@ mod tests {
 
     #[test]
     fn test_tuples_error() {
-        use crate::de::{Error, ErrorCode, Position};
+        use crate::de::{Error, ParseError, Position};
 
         assert_eq!(
             Value::from_str("Foo:").unwrap_err(),
-            Error {
-                code: ErrorCode::TrailingCharacters,
-                position: Position { col: 4, line: 1 }
-            },
+            Error::Parser(ParseError::TrailingCharacters, Position { col: 4, line: 1 }),
         );
     }
 
@@ -260,8 +243,8 @@ mod tests {
     Room ( width: 20, height: 5, name: \"The Room\" ),
 
     (
-        width: 10.0,
-        height: 10.0,
+        width: 10,
+        height: 10,
         name: \"Another room\",
         enemy_levels: {
             \"Enemy1\": 3,
@@ -276,11 +259,11 @@ mod tests {
                     vec![
                         (
                             Value::String("width".to_owned()),
-                            Value::Number(Number::new(20)),
+                            Value::Number(Number::new(20.0)),
                         ),
                         (
                             Value::String("height".to_owned()),
-                            Value::Number(Number::new(5)),
+                            Value::Number(Number::new(5.0)),
                         ),
                         (
                             Value::String("name".to_owned()),
@@ -310,15 +293,15 @@ mod tests {
                                 vec![
                                     (
                                         Value::String("Enemy1".to_owned()),
-                                        Value::Number(Number::new(3)),
+                                        Value::Number(Number::new(3.0)),
                                     ),
                                     (
                                         Value::String("Enemy2".to_owned()),
-                                        Value::Number(Number::new(5)),
+                                        Value::Number(Number::new(5.0)),
                                     ),
                                     (
                                         Value::String("Enemy3".to_owned()),
-                                        Value::Number(Number::new(7)),
+                                        Value::Number(Number::new(7.0)),
                                     ),
                                 ]
                                 .into_iter()
diff --git a/src/error.rs b/src/error.rs
deleted file mode 100644
index 494561df..00000000
--- a/src/error.rs
+++ /dev/null
@@ -1,161 +0,0 @@
-use serde::{de, ser};
-use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
-
-pub use crate::parse::Position;
-
-/// This type represents all possible errors that can occur when
-/// serializing or deserializing RON data.
-#[derive(Clone, Debug, PartialEq)]
-pub struct Error {
-    pub code: ErrorCode,
-    pub position: Position,
-}
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[non_exhaustive]
-#[derive(Clone, Debug, PartialEq)]
-pub enum ErrorCode {
-    Io(String),
-    Message(String),
-    Base64Error(base64::DecodeError),
-    Eof,
-    ExpectedArray,
-    ExpectedArrayEnd,
-    ExpectedAttribute,
-    ExpectedAttributeEnd,
-    ExpectedBoolean,
-    ExpectedComma,
-    // ExpectedEnum,
-    ExpectedChar,
-    ExpectedFloat,
-    ExpectedInteger,
-    ExpectedOption,
-    ExpectedOptionEnd,
-    ExpectedMap,
-    ExpectedMapColon,
-    ExpectedMapEnd,
-    ExpectedStruct,
-    ExpectedStructEnd,
-    ExpectedUnit,
-    // ExpectedStructName,
-    ExpectedString,
-    ExpectedStringEnd,
-    ExpectedIdentifier,
-
-    InvalidEscape(&'static str),
-
-    IntegerOutOfBounds,
-
-    NoSuchExtension(String),
-
-    UnclosedBlockComment,
-    UnderscoreAtBeginning,
-    UnexpectedByte(char),
-
-    Utf8Error(Utf8Error),
-    TrailingCharacters,
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if (self.position == Position { line: 0, col: 0 }) {
-            write!(f, "{}", self.code)
-        } else {
-            write!(f, "{}: {}", self.position, self.code)
-        }
-    }
-}
-
-impl fmt::Display for ErrorCode {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ErrorCode::Io(ref s) => f.write_str(s),
-            ErrorCode::Message(ref s) => f.write_str(s),
-            ErrorCode::Base64Error(ref e) => fmt::Display::fmt(e, f),
-            ErrorCode::Eof => f.write_str("Unexpected end of file"),
-            ErrorCode::ExpectedArray => f.write_str("Expected array"),
-            ErrorCode::ExpectedArrayEnd => f.write_str("Expected end of array"),
-            ErrorCode::ExpectedAttribute => f.write_str("Expected an enable attribute"),
-            ErrorCode::ExpectedAttributeEnd => {
-                f.write_str("Expected closing `)` and `]` after the attribute")
-            }
-            ErrorCode::ExpectedBoolean => f.write_str("Expected boolean"),
-            ErrorCode::ExpectedComma => f.write_str("Expected comma"),
-            // ErrorCode::ExpectedEnum => f.write_str("Expected enum"),
-            ErrorCode::ExpectedChar => f.write_str("Expected char"),
-            ErrorCode::ExpectedFloat => f.write_str("Expected float"),
-            ErrorCode::ExpectedInteger => f.write_str("Expected integer"),
-            ErrorCode::ExpectedOption => f.write_str("Expected option"),
-            ErrorCode::ExpectedOptionEnd => f.write_str("Expected end of option"),
-            ErrorCode::ExpectedMap => f.write_str("Expected map"),
-            ErrorCode::ExpectedMapColon => f.write_str("Expected colon"),
-            ErrorCode::ExpectedMapEnd => f.write_str("Expected end of map"),
-            ErrorCode::ExpectedStruct => f.write_str("Expected struct"),
-            ErrorCode::ExpectedStructEnd => f.write_str("Expected end of struct"),
-            ErrorCode::ExpectedUnit => f.write_str("Expected unit"),
-            // ErrorCode::ExpectedStructName => f.write_str("Expected struct name"),
-            ErrorCode::ExpectedString => f.write_str("Expected string"),
-            ErrorCode::ExpectedStringEnd => f.write_str("Expected string end"),
-            ErrorCode::ExpectedIdentifier => f.write_str("Expected identifier"),
-            ErrorCode::InvalidEscape(_) => f.write_str("Invalid escape sequence"),
-            ErrorCode::IntegerOutOfBounds => f.write_str("Integer is out of bounds"),
-            ErrorCode::NoSuchExtension(_) => f.write_str("No such RON extension"),
-            ErrorCode::Utf8Error(ref e) => fmt::Display::fmt(e, f),
-            ErrorCode::UnclosedBlockComment => f.write_str("Unclosed block comment"),
-            ErrorCode::UnderscoreAtBeginning => f.write_str("Found underscore at the beginning"),
-            ErrorCode::UnexpectedByte(_) => f.write_str("Unexpected byte"),
-            ErrorCode::TrailingCharacters => f.write_str("Non-whitespace trailing characters"),
-        }
-    }
-}
-
-impl de::Error for Error {
-    fn custom<T: fmt::Display>(msg: T) -> Self {
-        Error {
-            code: ErrorCode::Message(msg.to_string()),
-            position: Position { line: 0, col: 0 },
-        }
-    }
-}
-
-impl ser::Error for Error {
-    fn custom<T: fmt::Display>(msg: T) -> Self {
-        Error {
-            code: ErrorCode::Message(msg.to_string()),
-            position: Position { line: 0, col: 0 },
-        }
-    }
-}
-
-impl StdError for Error {}
-
-impl From<Utf8Error> for ErrorCode {
-    fn from(e: Utf8Error) -> Self {
-        ErrorCode::Utf8Error(e)
-    }
-}
-
-impl From<FromUtf8Error> for ErrorCode {
-    fn from(e: FromUtf8Error) -> Self {
-        ErrorCode::Utf8Error(e.utf8_error())
-    }
-}
-
-impl From<Utf8Error> for Error {
-    fn from(e: Utf8Error) -> Self {
-        Error {
-            code: ErrorCode::Utf8Error(e),
-            position: Position { line: 0, col: 0 },
-        }
-    }
-}
-
-impl From<io::Error> for Error {
-    fn from(e: io::Error) -> Self {
-        Error {
-            code: ErrorCode::Io(e.to_string()),
-            position: Position { line: 0, col: 0 },
-        }
-    }
-}
diff --git a/src/extensions.rs b/src/extensions.rs
index 5f3906c6..0c12330a 100644
--- a/src/extensions.rs
+++ b/src/extensions.rs
@@ -1,6 +1,7 @@
+use bitflags::bitflags;
 use serde::{Deserialize, Serialize};
 
-bitflags::bitflags! {
+bitflags! {
     #[derive(Serialize, Deserialize)]
     pub struct Extensions: usize {
         const UNWRAP_NEWTYPES = 0x1;
diff --git a/src/lib.rs b/src/lib.rs
index 9d2d176b..d5fed6d2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -58,16 +58,9 @@ Serializing / Deserializing is as simple as calling `to_string` / `from_str`.
 !*/
 
 pub mod de;
+pub mod extensions;
 pub mod ser;
-
-pub mod error;
 pub mod value;
-
-pub mod extensions;
-
-pub use de::{from_str, Deserializer};
-pub use error::{Error, Result};
-pub use ser::{to_string, Serializer};
-pub use value::{Map, Number, Value};
+pub use crate::value::Value;
 
 mod parse;
diff --git a/src/parse.rs b/src/parse.rs
index 96b8f666..7c42e910 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -4,10 +4,8 @@ use std::{
     str::{from_utf8, from_utf8_unchecked, FromStr},
 };
 
-use crate::{
-    error::{Error, ErrorCode, Result},
-    extensions::Extensions,
-};
+use crate::de::{Error, ParseError, Result};
+use crate::extensions::Extensions;
 
 const DIGITS: &[u8] = b"0123456789ABCDEFabcdef_";
 const FLOAT_CHARS: &[u8] = b"0123456789.+-eE";
@@ -27,8 +25,6 @@ pub enum AnyNum {
     U32(u32),
     I64(i64),
     U64(u64),
-    I128(i128),
-    U128(u128),
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -107,13 +103,13 @@ impl<'a> Bytes<'a> {
         let num_bytes = self.next_bytes_contained_in(DIGITS);
 
         if num_bytes == 0 {
-            return self.err(ErrorCode::ExpectedInteger);
+            return self.err(ParseError::ExpectedInteger);
         }
 
         let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) };
 
         if s.as_bytes()[0] == b'_' {
-            return self.err(ErrorCode::UnderscoreAtBeginning);
+            return self.err(ParseError::UnderscoreAtBeginning);
         }
 
         fn calc_num<T: Num>(
@@ -130,17 +126,17 @@ impl<'a> Bytes<'a> {
                 }
 
                 if num_acc.checked_mul_ext(base) {
-                    return bytes.err(ErrorCode::IntegerOutOfBounds);
+                    return bytes.err(ParseError::IntegerOutOfBounds);
                 }
 
                 let digit = bytes.decode_hex(byte)?;
 
                 if digit >= base {
-                    return bytes.err(ErrorCode::ExpectedInteger);
+                    return bytes.err(ParseError::ExpectedInteger);
                 }
 
                 if f(&mut num_acc, digit) {
-                    return bytes.err(ErrorCode::IntegerOutOfBounds);
+                    return bytes.err(ParseError::IntegerOutOfBounds);
                 }
             }
 
@@ -181,22 +177,19 @@ impl<'a> Bytes<'a> {
 
             any_float(f)
         } else {
-            let max_u8 = std::u8::MAX as u128;
-            let max_u16 = std::u16::MAX as u128;
-            let max_u32 = std::u32::MAX as u128;
-            let max_u64 = std::u64::MAX as u128;
-
-            let min_i8 = std::i8::MIN as i128;
-            let max_i8 = std::i8::MAX as i128;
-            let min_i16 = std::i16::MIN as i128;
-            let max_i16 = std::i16::MAX as i128;
-            let min_i32 = std::i32::MIN as i128;
-            let max_i32 = std::i32::MAX as i128;
-            let min_i64 = std::i64::MIN as i128;
-            let max_i64 = std::i64::MAX as i128;
+            let max_u8 = std::u8::MAX as u64;
+            let max_u16 = std::u16::MAX as u64;
+            let max_u32 = std::u32::MAX as u64;
+
+            let min_i8 = std::i8::MIN as i64;
+            let max_i8 = std::i8::MAX as i64;
+            let min_i16 = std::i16::MIN as i64;
+            let max_i16 = std::i16::MAX as i64;
+            let min_i32 = std::i32::MIN as i64;
+            let max_i32 = std::i32::MAX as i64;
 
             if is_signed {
-                match self.signed_integer::<i128>() {
+                match self.signed_integer::<i64>() {
                     Ok(x) => {
                         if x >= min_i8 && x <= max_i8 {
                             Ok(AnyNum::I8(x as i8))
@@ -204,10 +197,8 @@ impl<'a> Bytes<'a> {
                             Ok(AnyNum::I16(x as i16))
                         } else if x >= min_i32 && x <= max_i32 {
                             Ok(AnyNum::I32(x as i32))
-                        } else if x >= min_i64 && x <= max_i64 {
-                            Ok(AnyNum::I64(x as i64))
                         } else {
-                            Ok(AnyNum::I128(x))
+                            Ok(AnyNum::I64(x))
                         }
                     }
                     Err(_) => {
@@ -217,7 +208,7 @@ impl<'a> Bytes<'a> {
                     }
                 }
             } else {
-                match self.unsigned_integer::<u128>() {
+                match self.unsigned_integer::<u64>() {
                     Ok(x) => {
                         if x <= max_u8 {
                             Ok(AnyNum::U8(x as u8))
@@ -225,10 +216,8 @@ impl<'a> Bytes<'a> {
                             Ok(AnyNum::U16(x as u16))
                         } else if x <= max_u32 {
                             Ok(AnyNum::U32(x as u32))
-                        } else if x <= max_u64 {
-                            Ok(AnyNum::U64(x as u64))
                         } else {
-                            Ok(AnyNum::U128(x))
+                            Ok(AnyNum::U64(x))
                         }
                     }
                     Err(_) => {
@@ -247,7 +236,7 @@ impl<'a> Bytes<'a> {
         } else if self.consume("false") {
             Ok(false)
         } else {
-            self.err(ErrorCode::ExpectedBoolean)
+            self.err(ParseError::ExpectedBoolean)
         }
     }
 
@@ -257,7 +246,7 @@ impl<'a> Bytes<'a> {
 
     pub fn char(&mut self) -> Result<char> {
         if !self.consume("'") {
-            return self.err(ErrorCode::ExpectedChar);
+            return self.err(ParseError::ExpectedChar);
         }
 
         let c = self.peek_or_eof()?;
@@ -274,15 +263,15 @@ impl<'a> Bytes<'a> {
             let pos: usize = self.bytes[..max]
                 .iter()
                 .position(|&x| x == b'\'')
-                .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?;
+                .ok_or_else(|| self.error(ParseError::ExpectedChar))?;
             let s = from_utf8(&self.bytes[0..pos]).map_err(|e| self.error(e.into()))?;
             let mut chars = s.chars();
 
             let first = chars
                 .next()
-                .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?;
+                .ok_or_else(|| self.error(ParseError::ExpectedChar))?;
             if chars.next().is_some() {
-                return self.err(ErrorCode::ExpectedChar);
+                return self.err(ParseError::ExpectedChar);
             }
 
             let _ = self.advance(pos);
@@ -291,7 +280,7 @@ impl<'a> Bytes<'a> {
         };
 
         if !self.consume("'") {
-            return self.err(ErrorCode::ExpectedChar);
+            return self.err(ParseError::ExpectedChar);
         }
 
         Ok(c)
@@ -377,21 +366,21 @@ impl<'a> Bytes<'a> {
         Ok(peek)
     }
 
-    pub fn err<T>(&self, kind: ErrorCode) -> Result<T> {
+    pub fn err<T>(&self, kind: ParseError) -> Result<T> {
         Err(self.error(kind))
     }
 
-    pub fn error(&self, kind: ErrorCode) -> Error {
-        Error {
-            code: kind,
-            position: Position {
+    pub fn error(&self, kind: ParseError) -> Error {
+        Error::Parser(
+            kind,
+            Position {
                 line: self.line,
                 col: self.column,
             },
-        }
+        )
     }
 
-    pub fn expect_byte(&mut self, byte: u8, error: ErrorCode) -> Result<()> {
+    pub fn expect_byte(&mut self, byte: u8, error: ParseError) -> Result<()> {
         self.eat_byte()
             .and_then(|b| if b == byte { Ok(()) } else { self.err(error) })
     }
@@ -403,7 +392,7 @@ impl<'a> Bytes<'a> {
         }
 
         if !self.consume_all(&["#", "!", "[", "enable", "("])? {
-            return self.err(ErrorCode::ExpectedAttribute);
+            return self.err(ParseError::ExpectedAttribute);
         }
 
         self.skip_ws()?;
@@ -412,7 +401,7 @@ impl<'a> Bytes<'a> {
         loop {
             let ident = self.identifier()?;
             let extension = Extensions::from_ident(ident).ok_or_else(|| {
-                self.error(ErrorCode::NoSuchExtension(
+                self.error(ParseError::NoSuchExtension(
                     from_utf8(ident).unwrap().to_owned(),
                 ))
             })?;
@@ -423,7 +412,7 @@ impl<'a> Bytes<'a> {
 
             // If we have no comma but another item, return an error
             if !comma && self.check_ident_char(0) {
-                return self.err(ErrorCode::ExpectedComma);
+                return self.err(ParseError::ExpectedComma);
             }
 
             // If there's no comma, assume the list ended.
@@ -439,7 +428,7 @@ impl<'a> Bytes<'a> {
         if self.consume_all(&[")", "]"])? {
             Ok(extensions)
         } else {
-            Err(self.error(ErrorCode::ExpectedAttributeEnd))
+            Err(self.error(ParseError::ExpectedAttributeEnd))
         }
     }
 
@@ -456,7 +445,7 @@ impl<'a> Bytes<'a> {
         let num_bytes = self.next_bytes_contained_in(FLOAT_CHARS);
 
         let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) };
-        let res = FromStr::from_str(s).map_err(|_| self.error(ErrorCode::ExpectedFloat));
+        let res = FromStr::from_str(s).map_err(|_| self.error(ParseError::ExpectedFloat));
 
         let _ = self.advance(num_bytes);
 
@@ -480,9 +469,9 @@ impl<'a> Bytes<'a> {
                 let second = self
                     .bytes
                     .get(1)
-                    .ok_or_else(|| self.error(ErrorCode::Eof))?;
+                    .ok_or_else(|| self.error(ParseError::Eof))?;
                 if *second == b'"' || *second == b'#' {
-                    return self.err(ErrorCode::ExpectedIdentifier);
+                    return self.err(ParseError::ExpectedIdentifier);
                 }
             }
 
@@ -490,7 +479,7 @@ impl<'a> Bytes<'a> {
 
             Ok(bytes)
         } else {
-            self.err(ErrorCode::ExpectedIdentifier)
+            self.err(ParseError::ExpectedIdentifier)
         }
     }
 
@@ -545,7 +534,7 @@ impl<'a> Bytes<'a> {
         self.bytes
             .get(0)
             .cloned()
-            .ok_or_else(|| self.error(ErrorCode::Eof))
+            .ok_or_else(|| self.error(ParseError::Eof))
     }
 
     pub fn signed_integer<T>(&mut self) -> Result<T>
@@ -567,17 +556,17 @@ impl<'a> Bytes<'a> {
         }
     }
 
-    pub fn string(&mut self) -> Result<ParsedStr<'_>> {
+    pub fn string(&mut self) -> Result<ParsedStr<'a>> {
         if self.consume("\"") {
             self.escaped_string()
         } else if self.consume("r") {
             self.raw_string()
         } else {
-            self.err(ErrorCode::ExpectedString)
+            self.err(ParseError::ExpectedString)
         }
     }
 
-    fn escaped_string(&mut self) -> Result<ParsedStr<'_>> {
+    fn escaped_string(&mut self) -> Result<ParsedStr<'a>> {
         use std::iter::repeat;
 
         let (i, end_or_escape) = self
@@ -585,7 +574,7 @@ impl<'a> Bytes<'a> {
             .iter()
             .enumerate()
             .find(|&(_, &b)| b == b'\\' || b == b'"')
-            .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?;
+            .ok_or_else(|| self.error(ParseError::ExpectedStringEnd))?;
 
         if *end_or_escape == b'"' {
             let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?;
@@ -616,7 +605,7 @@ impl<'a> Bytes<'a> {
                     .iter()
                     .enumerate()
                     .find(|&(_, &b)| b == b'\\' || b == b'"')
-                    .ok_or(ErrorCode::Eof)
+                    .ok_or(ParseError::Eof)
                     .map_err(|e| self.error(e))?;
 
                 i = new_i;
@@ -632,13 +621,13 @@ impl<'a> Bytes<'a> {
         }
     }
 
-    fn raw_string(&mut self) -> Result<ParsedStr<'_>> {
+    fn raw_string(&mut self) -> Result<ParsedStr<'a>> {
         let num_hashes = self.bytes.iter().take_while(|&&b| b == b'#').count();
         let hashes = &self.bytes[..num_hashes];
         let _ = self.advance(num_hashes);
 
         if !self.consume("\"") {
-            return self.err(ErrorCode::ExpectedString);
+            return self.err(ParseError::ExpectedString);
         }
 
         let ending = [&[b'"'], hashes].concat();
@@ -646,7 +635,7 @@ impl<'a> Bytes<'a> {
             .bytes
             .windows(num_hashes + 1)
             .position(|window| window == ending.as_slice())
-            .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?;
+            .ok_or_else(|| self.error(ParseError::ExpectedStringEnd))?;
 
         let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?;
 
@@ -685,7 +674,7 @@ impl<'a> Bytes<'a> {
             c @ b'0'..=b'9' => Ok(c - b'0'),
             c @ b'a'..=b'f' => Ok(10 + c - b'a'),
             c @ b'A'..=b'F' => Ok(10 + c - b'A'),
-            _ => self.err(ErrorCode::InvalidEscape("Non-hex digit found")),
+            _ => self.err(ParseError::InvalidEscape("Non-hex digit found")),
         }
     }
 
@@ -699,7 +688,7 @@ impl<'a> Bytes<'a> {
             b't' => '\t',
             b'x' => self.decode_ascii_escape()? as char,
             b'u' => {
-                self.expect_byte(b'{', ErrorCode::InvalidEscape("Missing {"))?;
+                self.expect_byte(b'{', ParseError::InvalidEscape("Missing {"))?;
 
                 let mut bytes: u32 = 0;
                 let mut num_digits = 0;
@@ -721,17 +710,17 @@ impl<'a> Bytes<'a> {
                 }
 
                 if num_digits == 0 {
-                    return self.err(ErrorCode::InvalidEscape(
+                    return self.err(ParseError::InvalidEscape(
                         "Expected 1-6 digits, got 0 digits",
                     ));
                 }
 
-                self.expect_byte(b'}', ErrorCode::InvalidEscape("No } at the end"))?;
+                self.expect_byte(b'}', ParseError::InvalidEscape("No } at the end"))?;
                 char_from_u32(bytes)
-                    .ok_or_else(|| self.error(ErrorCode::InvalidEscape("Not a valid char")))?
+                    .ok_or_else(|| self.error(ParseError::InvalidEscape("Not a valid char")))?
             }
             _ => {
-                return self.err(ErrorCode::InvalidEscape("Unknown escape character"));
+                return self.err(ParseError::InvalidEscape("Unknown escape character"));
             }
         };
 
@@ -757,7 +746,7 @@ impl<'a> Bytes<'a> {
                             .count();
 
                         if self.bytes.is_empty() {
-                            return self.err(ErrorCode::UnclosedBlockComment);
+                            return self.err(ParseError::UnclosedBlockComment);
                         }
 
                         let _ = self.advance(bytes);
@@ -769,11 +758,11 @@ impl<'a> Bytes<'a> {
                             level -= 1;
                         } else {
                             self.eat_byte()
-                                .map_err(|_| self.error(ErrorCode::UnclosedBlockComment))?;
+                                .map_err(|_| self.error(ParseError::UnclosedBlockComment))?;
                         }
                     }
                 }
-                b => return self.err(ErrorCode::UnexpectedByte(b as char)),
+                b => return self.err(ParseError::UnexpectedByte(b as char)),
             }
 
             Ok(true)
@@ -839,7 +828,7 @@ macro_rules! impl_num {
     };
 }
 
-impl_num!(u8 u16 u32 u64 u128 i8 i16 i32 i64 i128);
+impl_num!(u8 u16 u32 u64 i8 i16 i32 i64);
 
 #[derive(Clone, Debug)]
 pub enum ParsedStr<'a> {
diff --git a/src/ser/mod.rs b/src/ser/mod.rs
index 53e11f65..f0403a10 100644
--- a/src/ser/mod.rs
+++ b/src/ser/mod.rs
@@ -1,21 +1,13 @@
 use serde::{ser, Deserialize, Serialize};
-use std::io;
+use std::{
+    error::Error as StdError,
+    fmt::{Display, Formatter, Result as FmtResult, Write},
+};
 
-use crate::error::{Error, Result};
 use crate::extensions::Extensions;
 
 mod value;
 
-/// Serializes `value` into `writer`
-pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
-where
-    W: io::Write,
-    T: Serialize,
-{
-    let mut s = Serializer::new(writer, None, false)?;
-    value.serialize(&mut s)
-}
-
 /// Serializes `value` and returns it as string.
 ///
 /// This function does not generate any newlines or nice formatting;
@@ -24,10 +16,9 @@ pub fn to_string<T>(value: &T) -> Result<String>
 where
     T: Serialize,
 {
-    let buf = Vec::new();
-    let mut s = Serializer::new(buf, None, false)?;
+    let mut s = Serializer::new(None, false);
     value.serialize(&mut s)?;
-    Ok(String::from_utf8(s.output).expect("Ron should be utf-8"))
+    Ok(s.output)
 }
 
 /// Serializes `value` in the recommended RON layout in a pretty way.
@@ -35,10 +26,41 @@ pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String>
 where
     T: Serialize,
 {
-    let buf = Vec::new();
-    let mut s = Serializer::new(buf, Some(config), false)?;
+    let mut s = Serializer::new(Some(config), false);
     value.serialize(&mut s)?;
-    Ok(String::from_utf8(s.output).expect("Ron should be utf-8"))
+    Ok(s.output)
+}
+
+/// Serialization result.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Serialization error.
+#[derive(Clone, Debug, PartialEq)]
+pub enum Error {
+    /// A custom error emitted by a serialized value.
+    Message(String),
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
+        match *self {
+            Error::Message(ref e) => write!(f, "Custom message: {}", e),
+        }
+    }
+}
+
+impl ser::Error for Error {
+    fn custom<T: Display>(msg: T) -> Self {
+        Error::Message(msg.to_string())
+    }
+}
+
+impl StdError for Error {
+    fn description(&self) -> &str {
+        match *self {
+            Error::Message(ref e) => e,
+        }
+    }
 }
 
 /// Pretty serializer state
@@ -90,9 +112,8 @@ impl PrettyConfig {
     }
 
     /// Limits the pretty-formatting based on the number of indentations.
-    /// I.e., with a depth limit of 5, starting with an element of depth
-    /// (indentation level) 6, everything will be put into the same line,
-    /// without pretty formatting.
+    /// I.e., with a depth limit of 5, starting with an element of depth (indentation level) 6,
+    /// everything will be put into the same line, without pretty formatting.
     ///
     /// Default: [std::usize::MAX]
     pub fn with_depth_limit(mut self, depth_limit: usize) -> Self {
@@ -120,9 +141,8 @@ impl PrettyConfig {
     }
 
     /// Configures whether tuples are single- or multi-line.
-    /// If set to `true`, tuples will have their fields indented and in new
-    /// lines. If set to `false`, tuples will be serialized without any
-    /// newlines or indentations.
+    /// If set to `true`, tuples will have their fields indented and in new lines.
+    /// If set to `false`, tuples will be serialized without any newlines or indentations.
     ///
     /// Default: `false`
     pub fn with_separate_tuple_members(mut self, separate_tuple_members: bool) -> Self {
@@ -131,8 +151,8 @@ impl PrettyConfig {
         self
     }
 
-    /// Configures whether a comment shall be added to every array element,
-    /// indicating the index.
+    /// Configures whether a comment shall be added to every array element, indicating
+    /// the index.
     ///
     /// Default: `false`
     pub fn with_enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
@@ -194,26 +214,29 @@ impl Default for PrettyConfig {
 ///
 /// You can just use `to_string` for deserializing a value.
 /// If you want it pretty-printed, take a look at the `pretty` module.
-pub struct Serializer<W: io::Write> {
-    output: W,
+pub struct Serializer {
+    output: String,
     pretty: Option<(PrettyConfig, Pretty)>,
     struct_names: bool,
     is_empty: Option<bool>,
 }
 
-impl<W: io::Write> Serializer<W> {
+impl Serializer {
     /// Creates a new `Serializer`.
     ///
     /// Most of the time you can just use `to_string` or `to_string_pretty`.
-    pub fn new(mut writer: W, config: Option<PrettyConfig>, struct_names: bool) -> Result<Self> {
-        if let Some(conf) = &config {
+    pub fn new(config: Option<PrettyConfig>, struct_names: bool) -> Self {
+        let initial_output = if let Some(conf) = &config {
             if conf.extensions.contains(Extensions::IMPLICIT_SOME) {
-                writer.write_all(b"#![enable(implicit_some)]")?;
-                writer.write_all(conf.new_line.as_bytes())?;
-            };
+                "#![enable(implicit_some)]".to_string() + &conf.new_line
+            } else {
+                String::new()
+            }
+        } else {
+            String::new()
         };
-        Ok(Serializer {
-            output: writer,
+        Serializer {
+            output: initial_output,
             pretty: config.map(|conf| {
                 (
                     conf,
@@ -225,12 +248,17 @@ impl<W: io::Write> Serializer<W> {
             }),
             struct_names,
             is_empty: None,
-        })
+        }
+    }
+
+    /// Consumes `self` and returns the built `String`.
+    pub fn into_output_string(self) -> String {
+        self.output
     }
 
     fn is_pretty(&self) -> bool {
         match self.pretty {
-            Some((ref config, ref pretty)) => pretty.indent <= config.depth_limit,
+            Some((ref config, ref pretty)) => pretty.indent < config.depth_limit,
             None => false,
         }
     }
@@ -247,142 +275,125 @@ impl<W: io::Write> Serializer<W> {
             .map_or(Extensions::empty(), |&(ref config, _)| config.extensions)
     }
 
-    fn start_indent(&mut self) -> Result<()> {
+    fn start_indent(&mut self) {
         if let Some((ref config, ref mut pretty)) = self.pretty {
             pretty.indent += 1;
-            if pretty.indent <= config.depth_limit {
+            if pretty.indent < config.depth_limit {
                 let is_empty = self.is_empty.unwrap_or(false);
 
                 if !is_empty {
-                    self.output.write_all(config.new_line.as_bytes())?;
+                    self.output += &config.new_line;
                 }
             }
         }
-        Ok(())
     }
 
-    fn indent(&mut self) -> io::Result<()> {
+    fn indent(&mut self) {
         if let Some((ref config, ref pretty)) = self.pretty {
-            if pretty.indent <= config.depth_limit {
-                for _ in 0..pretty.indent {
-                    self.output.write_all(config.indentor.as_bytes())?;
-                }
+            if pretty.indent < config.depth_limit {
+                self.output
+                    .extend((0..pretty.indent).map(|_| config.indentor.as_str()));
             }
         }
-        Ok(())
     }
 
-    fn end_indent(&mut self) -> io::Result<()> {
+    fn end_indent(&mut self) {
         if let Some((ref config, ref mut pretty)) = self.pretty {
-            if pretty.indent <= config.depth_limit {
+            if pretty.indent < config.depth_limit {
                 let is_empty = self.is_empty.unwrap_or(false);
 
                 if !is_empty {
-                    for _ in 1..pretty.indent {
-                        self.output.write_all(config.indentor.as_bytes())?;
-                    }
+                    self.output
+                        .extend((1..pretty.indent).map(|_| config.indentor.as_str()));
                 }
             }
             pretty.indent -= 1;
 
             self.is_empty = None;
         }
-        Ok(())
     }
 
-    fn serialize_escaped_str(&mut self, value: &str) -> io::Result<()> {
-        self.output.write_all(b"\"")?;
-        let mut scalar = [0u8; 4];
-        for c in value.chars().flat_map(|c| c.escape_debug()) {
-            self.output
-                .write_all(c.encode_utf8(&mut scalar).as_bytes())?;
-        }
-        self.output.write_all(b"\"")?;
-        Ok(())
+    fn serialize_escaped_str(&mut self, value: &str) {
+        let value = value.chars().flat_map(|c| c.escape_debug());
+        self.output += "\"";
+        self.output.extend(value);
+        self.output += "\"";
     }
 }
 
-impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
+impl<'a> ser::Serializer for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
-    type SerializeMap = Compound<'a, W>;
-    type SerializeSeq = Compound<'a, W>;
-    type SerializeStruct = Compound<'a, W>;
-    type SerializeStructVariant = Compound<'a, W>;
-    type SerializeTuple = Compound<'a, W>;
-    type SerializeTupleStruct = Compound<'a, W>;
-    type SerializeTupleVariant = Compound<'a, W>;
+    type SerializeMap = Self;
+    type SerializeSeq = Self;
+    type SerializeStruct = Self;
+    type SerializeStructVariant = Self;
+    type SerializeTuple = Self;
+    type SerializeTupleStruct = Self;
+    type SerializeTupleVariant = Self;
 
     fn serialize_bool(self, v: bool) -> Result<()> {
-        self.output.write_all(if v { b"true" } else { b"false" })?;
+        self.output += if v { "true" } else { "false" };
         Ok(())
     }
 
     fn serialize_i8(self, v: i8) -> Result<()> {
-        self.serialize_i128(v as i128)
+        self.serialize_i64(v as i64)
     }
 
     fn serialize_i16(self, v: i16) -> Result<()> {
-        self.serialize_i128(v as i128)
+        self.serialize_i64(v as i64)
     }
 
     fn serialize_i32(self, v: i32) -> Result<()> {
-        self.serialize_i128(v as i128)
+        self.serialize_i64(v as i64)
     }
 
     fn serialize_i64(self, v: i64) -> Result<()> {
-        self.serialize_i128(v as i128)
-    }
-
-    fn serialize_i128(self, v: i128) -> Result<()> {
         // TODO optimize
-        write!(self.output, "{}", v)?;
+        self.output += &v.to_string();
         Ok(())
     }
 
     fn serialize_u8(self, v: u8) -> Result<()> {
-        self.serialize_u128(v as u128)
+        self.serialize_u64(v as u64)
     }
 
     fn serialize_u16(self, v: u16) -> Result<()> {
-        self.serialize_u128(v as u128)
+        self.serialize_u64(v as u64)
     }
 
     fn serialize_u32(self, v: u32) -> Result<()> {
-        self.serialize_u128(v as u128)
+        self.serialize_u64(v as u64)
     }
 
     fn serialize_u64(self, v: u64) -> Result<()> {
-        self.serialize_u128(v as u128)
-    }
-
-    fn serialize_u128(self, v: u128) -> Result<()> {
-        write!(self.output, "{}", v)?;
+        self.output += &v.to_string();
         Ok(())
     }
 
     fn serialize_f32(self, v: f32) -> Result<()> {
-        write!(self.output, "{}", v)?;
+        self.output += &v.to_string();
         Ok(())
     }
 
     fn serialize_f64(self, v: f64) -> Result<()> {
-        write!(self.output, "{}", v)?;
+        self.output += &v.to_string();
         Ok(())
     }
 
     fn serialize_char(self, v: char) -> Result<()> {
-        self.output.write_all(b"'")?;
+        self.output += "'";
         if v == '\\' || v == '\'' {
-            self.output.write_all(b"\\")?;
+            self.output.push('\\');
         }
-        write!(self.output, "{}", v)?;
-        self.output.write_all(b"'")?;
+        self.output.push(v);
+        self.output += "'";
         Ok(())
     }
 
     fn serialize_str(self, v: &str) -> Result<()> {
-        self.serialize_escaped_str(v)?;
+        self.serialize_escaped_str(v);
 
         Ok(())
     }
@@ -392,7 +403,7 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
     }
 
     fn serialize_none(self) -> Result<()> {
-        self.output.write_all(b"None")?;
+        self.output += "None";
 
         Ok(())
     }
@@ -403,25 +414,25 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
     {
         let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME);
         if !implicit_some {
-            self.output.write_all(b"Some(")?;
+            self.output += "Some(";
         }
         value.serialize(&mut *self)?;
         if !implicit_some {
-            self.output.write_all(b")")?;
+            self.output += ")";
         }
 
         Ok(())
     }
 
     fn serialize_unit(self) -> Result<()> {
-        self.output.write_all(b"()")?;
+        self.output += "()";
 
         Ok(())
     }
 
     fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
         if self.struct_names {
-            self.output.write_all(name.as_bytes())?;
+            self.output += name;
 
             Ok(())
         } else {
@@ -430,7 +441,7 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
     }
 
     fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
-        self.output.write_all(variant.as_bytes())?;
+        self.output += variant;
 
         Ok(())
     }
@@ -440,12 +451,12 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
         T: ?Sized + Serialize,
     {
         if self.struct_names {
-            self.output.write_all(name.as_bytes())?;
+            self.output += name;
         }
 
-        self.output.write_all(b"(")?;
+        self.output += "(";
         value.serialize(&mut *self)?;
-        self.output.write_all(b")")?;
+        self.output += ")";
         Ok(())
     }
 
@@ -459,47 +470,41 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
     where
         T: ?Sized + Serialize,
     {
-        self.output.write_all(variant.as_bytes())?;
-        self.output.write_all(b"(")?;
+        self.output += variant;
+        self.output += "(";
 
         value.serialize(&mut *self)?;
 
-        self.output.write_all(b")")?;
+        self.output += ")";
         Ok(())
     }
 
     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
-        self.output.write_all(b"[")?;
+        self.output += "[";
 
         if let Some(len) = len {
             self.is_empty = Some(len == 0);
         }
 
-        self.start_indent()?;
+        self.start_indent();
 
         if let Some((_, ref mut pretty)) = self.pretty {
             pretty.sequence_index.push(0);
         }
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 
     fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
-        self.output.write_all(b"(")?;
+        self.output += "(";
 
         if self.separate_tuple_members() {
             self.is_empty = Some(len == 0);
 
-            self.start_indent()?;
+            self.start_indent();
         }
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 
     fn serialize_tuple_struct(
@@ -508,7 +513,7 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
         len: usize,
     ) -> Result<Self::SerializeTupleStruct> {
         if self.struct_names {
-            self.output.write_all(name.as_bytes())?;
+            self.output += name;
         }
 
         self.serialize_tuple(len)
@@ -521,49 +526,40 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
         variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeTupleVariant> {
-        self.output.write_all(variant.as_bytes())?;
-        self.output.write_all(b"(")?;
+        self.output += variant;
+        self.output += "(";
 
         if self.separate_tuple_members() {
             self.is_empty = Some(len == 0);
 
-            self.start_indent()?;
+            self.start_indent();
         }
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 
     fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
-        self.output.write_all(b"{")?;
+        self.output += "{";
 
         if let Some(len) = len {
             self.is_empty = Some(len == 0);
         }
 
-        self.start_indent()?;
+        self.start_indent();
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 
     fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
         if self.struct_names {
-            self.output.write_all(name.as_bytes())?;
+            self.output += name;
         }
-        self.output.write_all(b"(")?;
+        self.output += "(";
 
         self.is_empty = Some(len == 0);
-        self.start_indent()?;
+        self.start_indent();
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 
     fn serialize_struct_variant(
@@ -573,20 +569,17 @@ impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> {
         variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeStructVariant> {
-        self.output.write_all(variant.as_bytes())?;
-        self.output.write_all(b"(")?;
+        self.output += variant;
+        self.output += "(";
 
         self.is_empty = Some(len == 0);
-        self.start_indent()?;
+        self.start_indent();
 
-        Ok(Compound::Map {
-            ser: self,
-            state: State::First,
-        })
+        Ok(self)
     }
 }
 
-impl<'a, W: io::Write> ser::SerializeSeq for Compound<'a, W> {
+impl<'a> ser::SerializeSeq for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -594,78 +587,41 @@ impl<'a, W: io::Write> ser::SerializeSeq for Compound<'a, W> {
     where
         T: ?Sized + Serialize,
     {
-        let ser = match self {
-            Compound::Map {
-                state: ref mut s @ State::First,
-                ser,
-            } => {
-                *s = State::Rest;
-                ser
-            }
-            Compound::Map {
-                state: State::Rest,
-                ser,
-            } => {
-                ser.output.write_all(b",")?;
-                ser
-            }
-        };
-        if let Some((ref config, ref mut pretty)) = ser.pretty {
-            if pretty.indent <= config.depth_limit {
+        self.indent();
+
+        value.serialize(&mut **self)?;
+        self.output += ",";
+
+        if let Some((ref config, ref mut pretty)) = self.pretty {
+            if pretty.indent < config.depth_limit {
                 if config.enumerate_arrays {
                     assert!(config.new_line.contains('\n'));
                     let index = pretty.sequence_index.last_mut().unwrap();
                     //TODO: when /**/ comments are supported, prepend the index
                     // to an element instead of appending it.
-                    write!(ser.output, "// [{}]", index).unwrap();
+                    write!(self.output, "// [{}]", index).unwrap();
                     *index += 1;
                 }
-                ser.output.write_all(config.new_line.as_bytes())?;
+                self.output += &config.new_line;
             }
         }
-        ser.indent()?;
-
-        value.serialize(&mut **ser)?;
 
         Ok(())
     }
 
     fn end(self) -> Result<()> {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: State::Rest,
-            } => {
-                if let Some((ref config, ref mut pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(b",")?;
-                    }
-                }
-                ser
-            }
-            Compound::Map { ser, .. } => ser,
-        };
-        ser.end_indent()?;
+        self.end_indent();
 
-        if let Some((_, ref mut pretty)) = ser.pretty {
+        if let Some((_, ref mut pretty)) = self.pretty {
             pretty.sequence_index.pop();
         }
 
-        ser.output.write_all(b"]")?;
+        self.output += "]";
         Ok(())
     }
 }
-pub enum State {
-    First,
-    Rest,
-}
-pub enum Compound<'a, W: io::Write> {
-    Map {
-        ser: &'a mut Serializer<W>,
-        state: State,
-    },
-}
-impl<'a, W: io::Write> ser::SerializeTuple for Compound<'a, W> {
+
+impl<'a> ser::SerializeTuple for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -673,66 +629,42 @@ impl<'a, W: io::Write> ser::SerializeTuple for Compound<'a, W> {
     where
         T: ?Sized + Serialize,
     {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: ref mut s @ State::First,
-            } => {
-                *s = State::Rest;
-                ser
-            }
-            Compound::Map { ser, .. } => {
-                ser.output.write_all(b",")?;
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(if ser.separate_tuple_members() {
-                            config.new_line.as_bytes()
-                        } else {
-                            b" "
-                        })?;
-                    }
-                }
-                ser
-            }
-        };
-
-        if ser.separate_tuple_members() {
-            ser.indent()?;
+        if self.separate_tuple_members() {
+            self.indent();
         }
 
-        value.serialize(&mut **ser)?;
+        value.serialize(&mut **self)?;
+        self.output += ",";
+
+        if let Some((ref config, ref pretty)) = self.pretty {
+            if pretty.indent < config.depth_limit {
+                self.output += if self.separate_tuple_members() {
+                    &config.new_line
+                } else {
+                    " "
+                };
+            }
+        }
 
         Ok(())
     }
 
     fn end(self) -> Result<()> {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: State::Rest,
-            } => {
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
-                        ser.output.write_all(b",")?;
-                        ser.output.write_all(config.new_line.as_bytes())?;
-                    }
-                }
-                ser
-            }
-            Compound::Map { ser, .. } => ser,
-        };
-        if ser.separate_tuple_members() {
-            ser.end_indent()?;
+        if self.separate_tuple_members() {
+            self.end_indent();
+        } else if self.is_pretty() {
+            self.output.pop();
+            self.output.pop();
         }
 
-        ser.output.write_all(b")")?;
+        self.output += ")";
 
         Ok(())
     }
 }
 
 // Same thing but for tuple structs.
-impl<'a, W: io::Write> ser::SerializeTupleStruct for Compound<'a, W> {
+impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -748,7 +680,7 @@ impl<'a, W: io::Write> ser::SerializeTupleStruct for Compound<'a, W> {
     }
 }
 
-impl<'a, W: io::Write> ser::SerializeTupleVariant for Compound<'a, W> {
+impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -764,7 +696,7 @@ impl<'a, W: io::Write> ser::SerializeTupleVariant for Compound<'a, W> {
     }
 }
 
-impl<'a, W: io::Write> ser::SerializeMap for Compound<'a, W> {
+impl<'a> ser::SerializeMap for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -772,45 +704,27 @@ impl<'a, W: io::Write> ser::SerializeMap for Compound<'a, W> {
     where
         T: ?Sized + Serialize,
     {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: ref mut s @ State::First,
-            } => {
-                *s = State::Rest;
-                ser
-            }
-            Compound::Map {
-                ser,
-                state: State::Rest,
-            } => {
-                ser.output.write_all(b",")?;
-
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(config.new_line.as_bytes())?;
-                    }
-                }
-                ser
-            }
-        };
-        ser.indent()?;
-        key.serialize(&mut **ser)
+        self.indent();
+
+        key.serialize(&mut **self)
     }
 
     fn serialize_value<T>(&mut self, value: &T) -> Result<()>
     where
         T: ?Sized + Serialize,
     {
-        match self {
-            Compound::Map { ser, .. } => {
-                ser.output.write_all(b":")?;
+        self.output += ":";
 
-                if ser.is_pretty() {
-                    ser.output.write_all(b" ")?;
-                }
+        if self.is_pretty() {
+            self.output += " ";
+        }
+
+        value.serialize(&mut **self)?;
+        self.output += ",";
 
-                value.serialize(&mut **ser)?;
+        if let Some((ref config, ref pretty)) = self.pretty {
+            if pretty.indent < config.depth_limit {
+                self.output += &config.new_line;
             }
         }
 
@@ -818,29 +732,14 @@ impl<'a, W: io::Write> ser::SerializeMap for Compound<'a, W> {
     }
 
     fn end(self) -> Result<()> {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: State::Rest,
-            } => {
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(b",")?;
-                        ser.output.write_all(config.new_line.as_bytes())?;
-                    }
-                }
+        self.end_indent();
 
-                ser
-            }
-            Compound::Map { ser, .. } => ser,
-        };
-        ser.end_indent()?;
-        ser.output.write_all(b"}")?;
+        self.output += "}";
         Ok(())
     }
 }
 
-impl<'a, W: io::Write> ser::SerializeStruct for Compound<'a, W> {
+impl<'a> ser::SerializeStruct for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -848,61 +747,36 @@ impl<'a, W: io::Write> ser::SerializeStruct for Compound<'a, W> {
     where
         T: ?Sized + Serialize,
     {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: ref mut s @ State::First,
-            } => {
-                *s = State::Rest;
-                ser
-            }
-            Compound::Map { ser, .. } => {
-                ser.output.write_all(b",")?;
+        self.indent();
 
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(config.new_line.as_bytes())?;
-                    }
-                }
-                ser
-            }
-        };
-        ser.indent()?;
-        ser.output.write_all(key.as_bytes())?;
-        ser.output.write_all(b":")?;
+        self.output += key;
+        self.output += ":";
 
-        if ser.is_pretty() {
-            ser.output.write_all(b" ")?;
+        if self.is_pretty() {
+            self.output += " ";
         }
 
-        value.serialize(&mut **ser)?;
+        value.serialize(&mut **self)?;
+        self.output += ",";
+
+        if let Some((ref config, ref pretty)) = self.pretty {
+            if pretty.indent < config.depth_limit {
+                self.output += &config.new_line;
+            }
+        }
 
         Ok(())
     }
 
     fn end(self) -> Result<()> {
-        let ser = match self {
-            Compound::Map {
-                ser,
-                state: State::Rest,
-            } => {
-                if let Some((ref config, ref pretty)) = ser.pretty {
-                    if pretty.indent <= config.depth_limit {
-                        ser.output.write_all(b",")?;
-                        ser.output.write_all(config.new_line.as_bytes())?;
-                    }
-                }
-                ser
-            }
-            Compound::Map { ser, .. } => ser,
-        };
-        ser.end_indent()?;
-        ser.output.write_all(b")")?;
+        self.end_indent();
+
+        self.output += ")";
         Ok(())
     }
 }
 
-impl<'a, W: io::Write> ser::SerializeStructVariant for Compound<'a, W> {
+impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
     type Error = Error;
     type Ok = ();
 
@@ -952,7 +826,7 @@ mod tests {
     fn test_struct() {
         let my_struct = MyStruct { x: 4.0, y: 7.0 };
 
-        assert_eq!(to_string(&my_struct).unwrap(), "(x:4,y:7)");
+        assert_eq!(to_string(&my_struct).unwrap(), "(x:4,y:7,)");
 
         #[derive(Serialize)]
         struct NewType(i32);
@@ -962,7 +836,7 @@ mod tests {
         #[derive(Serialize)]
         struct TupleStruct(f32, f32);
 
-        assert_eq!(to_string(&TupleStruct(2.0, 5.0)).unwrap(), "(2,5)");
+        assert_eq!(to_string(&TupleStruct(2.0, 5.0)).unwrap(), "(2,5,)");
     }
 
     #[test]
@@ -975,8 +849,8 @@ mod tests {
     fn test_enum() {
         assert_eq!(to_string(&MyEnum::A).unwrap(), "A");
         assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true)");
-        assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5)");
-        assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3)");
+        assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5,)");
+        assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3,)");
     }
 
     #[test]
@@ -986,8 +860,8 @@ mod tests {
         let empty_ref: &[i32] = &empty;
         assert_eq!(to_string(&empty_ref).unwrap(), "[]");
 
-        assert_eq!(to_string(&[2, 3, 4i32]).unwrap(), "(2,3,4)");
-        assert_eq!(to_string(&(&[2, 3, 4i32] as &[i32])).unwrap(), "[2,3,4]");
+        assert_eq!(to_string(&[2, 3, 4i32]).unwrap(), "(2,3,4,)");
+        assert_eq!(to_string(&(&[2, 3, 4i32] as &[i32])).unwrap(), "[2,3,4,]");
     }
 
     #[test]
@@ -1000,8 +874,8 @@ mod tests {
 
         let s = to_string(&map).unwrap();
         s.starts_with("{");
-        s.contains("(true,false):4");
-        s.contains("(false,false):123");
+        s.contains("(true,false,):4");
+        s.contains("(false,false,):123");
         s.ends_with("}");
     }
 
@@ -1027,7 +901,7 @@ mod tests {
         let small: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
         assert_eq!(
             to_string(&small).unwrap(),
-            "(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)"
+            "(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,)"
         );
 
         let large = vec![255u8; 64];
diff --git a/src/ser/value.rs b/src/ser/value.rs
index 1a477589..d3109ec3 100644
--- a/src/ser/value.rs
+++ b/src/ser/value.rs
@@ -1,6 +1,6 @@
 use serde::ser::{Serialize, Serializer};
 
-use crate::value::{Number, Value};
+use crate::value::Value;
 
 impl Serialize for Value {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -11,8 +11,7 @@ impl Serialize for Value {
             Value::Bool(b) => serializer.serialize_bool(b),
             Value::Char(c) => serializer.serialize_char(c),
             Value::Map(ref m) => Serialize::serialize(m, serializer),
-            Value::Number(Number::Float(ref f)) => serializer.serialize_f64(f.get()),
-            Value::Number(Number::Integer(i)) => serializer.serialize_i64(i),
+            Value::Number(ref n) => serializer.serialize_f64(n.get()),
             Value::Option(Some(ref o)) => serializer.serialize_some(o.as_ref()),
             Value::Option(None) => serializer.serialize_none(),
             Value::String(ref s) => serializer.serialize_str(s),
diff --git a/src/value.rs b/src/value.rs
index e5387df0..a848c9f2 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -131,22 +131,14 @@ type MapInner = std::collections::BTreeMap<Value, Value>;
 #[cfg(feature = "indexmap")]
 type MapInner = indexmap::IndexMap<Value, Value>;
 
-/// A wrapper for a number, which can be either `f64` or `i64`.
-#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)]
-pub enum Number {
-    Integer(i64),
-    Float(Float),
-}
-
-/// A wrapper for `f64`, which guarantees that the inner value
+/// A wrapper for `f64` which guarantees that the inner value
 /// is finite and thus implements `Eq`, `Hash` and `Ord`.
 #[derive(Copy, Clone, Debug)]
-pub struct Float(f64);
+pub struct Number(f64);
 
-impl Float {
-    /// Construct a new `Float`.
+impl Number {
     pub fn new(v: f64) -> Self {
-        Float(v)
+        Number(v)
     }
 
     /// Returns the wrapped float.
@@ -155,129 +147,23 @@ impl Float {
     }
 }
 
-impl Number {
-    /// Construct a new number.
-    pub fn new(v: impl Into<Number>) -> Self {
-        v.into()
-    }
-
-    /// Returns the `f64` representation of the number regardless of whether the number is stored
-    /// as a float or integer.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// # use ron::value::Number;
-    /// let i = Number::new(5);
-    /// let f = Number::new(2.0);
-    /// assert_eq!(i.into_f64(), 5.0);
-    /// assert_eq!(f.into_f64(), 2.0);
-    /// ```
-    pub fn into_f64(self) -> f64 {
-        self.map_to(|i| i as f64, |f| f)
-    }
-
-    /// If the `Number` is a float, return it. Otherwise return `None`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// # use ron::value::Number;
-    /// let i = Number::new(5);
-    /// let f = Number::new(2.0);
-    /// assert_eq!(i.as_f64(), None);
-    /// assert_eq!(f.as_f64(), Some(2.0));
-    /// ```
-    pub fn as_f64(self) -> Option<f64> {
-        self.map_to(|_| None, Some)
-    }
-
-    /// If the `Number` is an integer, return it. Otherwise return `None`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// # use ron::value::Number;
-    /// let i = Number::new(5);
-    /// let f = Number::new(2.0);
-    /// assert_eq!(i.as_i64(), Some(5));
-    /// assert_eq!(f.as_i64(), None);
-    /// ```
-    pub fn as_i64(self) -> Option<i64> {
-        self.map_to(Some, |_| None)
-    }
-
-    /// Map this number to a single type using the appropriate closure.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// # use ron::value::Number;
-    /// let i = Number::new(5);
-    /// let f = Number::new(2.0);
-    /// assert!(i.map_to(|i| i > 3, |f| f > 3.0));
-    /// assert!(!f.map_to(|i| i > 3, |f| f > 3.0));
-    /// ```
-    pub fn map_to<T>(
-        self,
-        integer_fn: impl FnOnce(i64) -> T,
-        float_fn: impl FnOnce(f64) -> T,
-    ) -> T {
-        match self {
-            Number::Integer(i) => integer_fn(i),
-            Number::Float(Float(f)) => float_fn(f),
-        }
-    }
-}
-
-impl From<f64> for Number {
-    fn from(f: f64) -> Number {
-        Number::Float(Float(f))
-    }
-}
-
-impl From<i64> for Number {
-    fn from(i: i64) -> Number {
-        Number::Integer(i)
-    }
-}
-
-impl From<i32> for Number {
-    fn from(i: i32) -> Number {
-        Number::Integer(i as i64)
-    }
-}
-
-// The following number conversion checks if the integer fits losslessly into an i64, before
-// constructing a Number::Integer variant. If not, the conversion defaults to float.
-
-impl From<u64> for Number {
-    fn from(i: u64) -> Number {
-        if i as i64 as u64 == i {
-            Number::Integer(i as i64)
-        } else {
-            Number::new(i as f64)
-        }
-    }
-}
-
 /// Partial equality comparison
 /// In order to be able to use `Number` as a mapping key, NaN floating values
-/// wrapped in `Float` are equals to each other. It is not the case for
+/// wrapped in `Number` are equals to each other. It is not the case for
 /// underlying `f64` values itself.
-impl PartialEq for Float {
+impl PartialEq for Number {
     fn eq(&self, other: &Self) -> bool {
         self.0.is_nan() && other.0.is_nan() || self.0 == other.0
     }
 }
 
 /// Equality comparison
-/// In order to be able to use `Float` as a mapping key, NaN floating values
-/// wrapped in `Float` are equals to each other. It is not the case for
+/// In order to be able to use `Number` as a mapping key, NaN floating values
+/// wrapped in `Number` are equals to each other. It is not the case for
 /// underlying `f64` values itself.
-impl Eq for Float {}
+impl Eq for Number {}
 
-impl Hash for Float {
+impl Hash for Number {
     fn hash<H: Hasher>(&self, state: &mut H) {
         state.write_u64(self.0 as u64);
     }
@@ -286,13 +172,13 @@ impl Hash for Float {
 /// Partial ordering comparison
 /// In order to be able to use `Number` as a mapping key, NaN floating values
 /// wrapped in `Number` are equals to each other and are less then any other
-/// floating value. It is not the case for the underlying `f64` values themselves.
+/// floating value. It is not the case for underlying `f64` values itself.
 /// ```
 /// use ron::value::Number;
 /// assert!(Number::new(std::f64::NAN) < Number::new(std::f64::NEG_INFINITY));
 /// assert_eq!(Number::new(std::f64::NAN), Number::new(std::f64::NAN));
 /// ```
-impl PartialOrd for Float {
+impl PartialOrd for Number {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         match (self.0.is_nan(), other.0.is_nan()) {
             (true, true) => Some(Ordering::Equal),
@@ -304,11 +190,11 @@ impl PartialOrd for Float {
 }
 
 /// Ordering comparison
-/// In order to be able to use `Float` as a mapping key, NaN floating values
-/// wrapped in `Float` are equals to each other and are less then any other
+/// In order to be able to use `Number` as a mapping key, NaN floating values
+/// wrapped in `Number` are equals to each other and are less then any other
 /// floating value. It is not the case for underlying `f64` values itself. See
 /// the `PartialEq` implementation.
-impl Ord for Float {
+impl Ord for Number {
     fn cmp(&self, other: &Self) -> Ordering {
         self.partial_cmp(other).expect("Bug: Contract violation")
     }
@@ -358,8 +244,7 @@ impl<'de> Deserializer<'de> for Value {
                 keys: m.keys().cloned().rev().collect(),
                 values: m.values().cloned().rev().collect(),
             }),
-            Value::Number(Number::Float(ref f)) => visitor.visit_f64(f.get()),
-            Value::Number(Number::Integer(i)) => visitor.visit_i64(i),
+            Value::Number(n) => visitor.visit_f64(n.get()),
             Value::Option(Some(o)) => visitor.visit_some(*o),
             Value::Option(None) => visitor.visit_none(),
             Value::String(s) => visitor.visit_string(s),
@@ -397,7 +282,7 @@ impl<'de> Deserializer<'de> for Value {
         V: Visitor<'de>,
     {
         match self {
-            Value::Number(Number::Integer(i)) => visitor.visit_i64(i),
+            Value::Number(n) => visitor.visit_i64(n.get() as i64),
             v => Err(RonError::custom(format!("Expected a number, got {:?}", v))),
         }
     }
@@ -428,7 +313,7 @@ impl<'de> Deserializer<'de> for Value {
         V: Visitor<'de>,
     {
         match self {
-            Value::Number(Number::Integer(i)) => visitor.visit_u64(i as u64),
+            Value::Number(n) => visitor.visit_u64(n.get() as u64),
             v => Err(RonError::custom(format!("Expected a number, got {:?}", v))),
         }
     }
@@ -486,7 +371,8 @@ impl<'de> SeqAccess<'de> for Seq {
 mod tests {
     use super::*;
     use serde::Deserialize;
-    use std::{collections::BTreeMap, fmt::Debug};
+    use std::collections::BTreeMap;
+    use std::fmt::Debug;
 
     fn assert_same<'de, T>(s: &'de str)
     where


Test patch:
diff --git a/src/de/tests.rs b/src/de/tests.rs
index f74b87b6..de302849 100644
--- a/src/de/tests.rs
+++ b/src/de/tests.rs
@@ -149,16 +149,13 @@ y: 2.0 // 2!
     );
 }
 
-fn err<T>(kind: ErrorCode, line: usize, col: usize) -> Result<T> {
-    Err(Error {
-        code: kind,
-        position: Position { line, col },
-    })
+fn err<T>(kind: ParseError, line: usize, col: usize) -> Result<T> {
+    Err(Error::Parser(kind, Position { line, col }))
 }
 
 #[test]
 fn test_err_wrong_value() {
-    use self::ErrorCode::*;
+    use self::ParseError::*;
     use std::collections::HashMap;
 
     assert_eq!(from_str::<f32>("'c'"), err(ExpectedFloat, 1, 1));
@@ -207,10 +204,7 @@ fn forgot_apostrophes() {
     let de: Result<(i32, String)> = from_str("(4, \"Hello)");
 
     assert!(match de {
-        Err(Error {
-            code: ErrorCode::ExpectedStringEnd,
-            position: _,
-        }) => true,
+        Err(Error::Parser(ParseError::ExpectedStringEnd, _)) => true,
         _ => false,
     });
 }
@@ -219,14 +213,14 @@ fn forgot_apostrophes() {
 fn expected_attribute() {
     let de: Result<String> = from_str("#\"Hello\"");
 
-    assert_eq!(de, err(ErrorCode::ExpectedAttribute, 1, 2));
+    assert_eq!(de, err(ParseError::ExpectedAttribute, 1, 2));
 }
 
 #[test]
 fn expected_attribute_end() {
     let de: Result<String> = from_str("#![enable(unwrap_newtypes) \"Hello\"");
 
-    assert_eq!(de, err(ErrorCode::ExpectedAttributeEnd, 1, 28));
+    assert_eq!(de, err(ParseError::ExpectedAttributeEnd, 1, 28));
 }
 
 #[test]
@@ -235,7 +229,7 @@ fn invalid_attribute() {
 
     assert_eq!(
         de,
-        err(ErrorCode::NoSuchExtension("invalid".to_string()), 1, 18)
+        err(ParseError::NoSuchExtension("invalid".to_string()), 1, 18)
     );
 }
 
diff --git a/tests/117_untagged_tuple_variant.rs b/tests/117_untagged_tuple_variant.rs
index 6d98deb6..a11654e5 100644
--- a/tests/117_untagged_tuple_variant.rs
+++ b/tests/117_untagged_tuple_variant.rs
@@ -54,6 +54,6 @@ enum Foo {
 fn test_vessd_case() {
     let foo_vec = vec![Foo::Bar(0); 5];
     let foo_str = to_string(&foo_vec).unwrap();
-    assert_eq!(foo_str.as_str(), "[0,0,0,0,0]");
+    assert_eq!(foo_str.as_str(), "[0,0,0,0,0,]");
     assert_eq!(from_str::<Vec<Foo>>(&foo_str).unwrap(), foo_vec);
 }
diff --git a/tests/123_enum_representation.rs b/tests/123_enum_representation.rs
index 3f82b08c..8b0ac4eb 100644
--- a/tests/123_enum_representation.rs
+++ b/tests/123_enum_representation.rs
@@ -1,6 +1,8 @@
-use ron::{de::from_str, ser::to_string};
+use ron::de::from_str;
+use ron::ser::to_string;
 use serde::{Deserialize, Serialize};
-use std::{cmp::PartialEq, fmt::Debug};
+use std::cmp::PartialEq;
+use std::fmt::Debug;
 
 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
 enum Inner {
@@ -71,14 +73,14 @@ fn test_externally_a_ser() {
         bar: 2,
         different: 3,
     };
-    let e = "VariantA(foo:1,bar:2,different:3)";
+    let e = "VariantA(foo:1,bar:2,different:3,)";
     test_ser(&v, e);
 }
 
 #[test]
 fn test_externally_b_ser() {
     let v = EnumStructExternally::VariantB { foo: 1, bar: 2 };
-    let e = "VariantB(foo:1,bar:2)";
+    let e = "VariantB(foo:1,bar:2,)";
     test_ser(&v, e);
 }
 
@@ -89,14 +91,14 @@ fn test_internally_a_ser() {
         bar: 2,
         different: 3,
     };
-    let e = "(type:\"VariantA\",foo:1,bar:2,different:3)";
+    let e = "(type:\"VariantA\",foo:1,bar:2,different:3,)";
     test_ser(&v, e);
 }
 
 #[test]
 fn test_internally_b_ser() {
     let v = EnumStructInternally::VariantB { foo: 1, bar: 2 };
-    let e = "(type:\"VariantB\",foo:1,bar:2)";
+    let e = "(type:\"VariantB\",foo:1,bar:2,)";
     test_ser(&v, e);
 }
 
@@ -107,14 +109,14 @@ fn test_adjacently_a_ser() {
         bar: 2,
         different: Inner::Foo,
     };
-    let e = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo))";
+    let e = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo,),)";
     test_ser(&v, e);
 }
 
 #[test]
 fn test_adjacently_b_ser() {
     let v = EnumStructAdjacently::VariantB { foo: 1, bar: 2 };
-    let e = "(type:\"VariantB\",content:(foo:1,bar:2))";
+    let e = "(type:\"VariantB\",content:(foo:1,bar:2,),)";
     test_ser(&v, e);
 }
 
@@ -125,20 +127,20 @@ fn test_untagged_a_ser() {
         bar: 2,
         different: 3,
     };
-    let e = "(foo:1,bar:2,different:3)";
+    let e = "(foo:1,bar:2,different:3,)";
     test_ser(&v, e);
 }
 
 #[test]
 fn test_untagged_b_ser() {
     let v = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
-    let e = "(foo:1,bar:2)";
+    let e = "(foo:1,bar:2,)";
     test_ser(&v, e);
 }
 
 #[test]
 fn test_externally_a_de() {
-    let s = "VariantA(foo:1,bar:2,different:3)";
+    let s = "VariantA(foo:1,bar:2,different:3,)";
     let e = EnumStructExternally::VariantA {
         foo: 1,
         bar: 2,
@@ -149,14 +151,14 @@ fn test_externally_a_de() {
 
 #[test]
 fn test_externally_b_de() {
-    let s = "VariantB(foo:1,bar:2)";
+    let s = "VariantB(foo:1,bar:2,)";
     let e = EnumStructExternally::VariantB { foo: 1, bar: 2 };
     test_de(s, e);
 }
 
 #[test]
 fn test_internally_a_de() {
-    let s = "(type:\"VariantA\",foo:1,bar:2,different:3)";
+    let s = "(type:\"VariantA\",foo:1,bar:2,different:3,)";
     let e = EnumStructInternally::VariantA {
         foo: 1,
         bar: 2,
@@ -167,14 +169,14 @@ fn test_internally_a_de() {
 
 #[test]
 fn test_internally_b_de() {
-    let s = "(type:\"VariantB\",foo:1,bar:2)";
+    let s = "(type:\"VariantB\",foo:1,bar:2,)";
     let e = EnumStructInternally::VariantB { foo: 1, bar: 2 };
     test_de(s, e);
 }
 
 #[test]
 fn test_adjacently_a_de() {
-    let s = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo))";
+    let s = "(type:\"VariantA\",content:(foo:1,bar:2,different:Foo,),)";
     let e = EnumStructAdjacently::VariantA {
         foo: 1,
         bar: 2,
@@ -185,14 +187,14 @@ fn test_adjacently_a_de() {
 
 #[test]
 fn test_adjacently_b_de() {
-    let s = "(type:\"VariantB\",content:(foo:1,bar:2))";
+    let s = "(type:\"VariantB\",content:(foo:1,bar:2,),)";
     let e = EnumStructAdjacently::VariantB { foo: 1, bar: 2 };
     test_de(s, e);
 }
 
 #[test]
 fn test_untagged_a_de() {
-    let s = "(foo:1,bar:2,different:3)";
+    let s = "(foo:1,bar:2,different:3,)";
     let e = EnumStructUntagged::VariantA {
         foo: 1,
         bar: 2,
@@ -203,7 +205,7 @@ fn test_untagged_a_de() {
 
 #[test]
 fn test_untagged_b_de() {
-    let s = "(foo:1,bar:2)";
+    let s = "(foo:1,bar:2,)";
     let e = EnumStructUntagged::VariantB { foo: 1, bar: 2 };
     test_de(s, e);
 }
diff --git a/tests/129_indexmap.rs b/tests/129_indexmap.rs
index a10a11e2..a19e351d 100644
--- a/tests/129_indexmap.rs
+++ b/tests/129_indexmap.rs
@@ -15,9 +15,9 @@ tasks: {
         "-l",
         "-h",
       ]),
-      ch_dir: Some("/"),
+      ch_dir: Some("/")
     ),
-},
+}
 )
 "#;
 
diff --git a/tests/borrowed_str.rs b/tests/borrowed_str.rs
new file mode 100644
index 00000000..f01eeb14
--- /dev/null
+++ b/tests/borrowed_str.rs
@@ -0,0 +1,16 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+struct Borrowed<'a> {
+    value: &'a str,
+}
+
+const BORROWED: &str = "Borrowed(value: \"test\")";
+
+#[test]
+fn borrowed_str() {
+    assert_eq!(
+        ron::de::from_str(BORROWED).ok(),
+        Some(Borrowed { value: "test" })
+    );
+}
diff --git a/tests/comments.rs b/tests/comments.rs
index f5d6f73c..d49ef73c 100644
--- a/tests/comments.rs
+++ b/tests/comments.rs
@@ -1,4 +1,4 @@
-use ron::de::{from_str, Error as RonErr, ErrorCode, Position};
+use ron::de::{from_str, Error as RonErr, ParseError, Position};
 
 #[test]
 fn test_simple() {
@@ -44,9 +44,9 @@ fn test_unclosed() {
 \"THE VALUE (which is invalid)\"
 "
         ),
-        Err(RonErr {
-            code: ErrorCode::UnclosedBlockComment,
-            position: Position { col: 1, line: 9 }
-        })
+        Err(RonErr::Parser(
+            ParseError::UnclosedBlockComment,
+            Position { col: 1, line: 9 }
+        ))
     );
 }
diff --git a/tests/depth_limit.rs b/tests/depth_limit.rs
index 5c74f282..41929a84 100644
--- a/tests/depth_limit.rs
+++ b/tests/depth_limit.rs
@@ -26,12 +26,12 @@ struct Nested {
 }
 
 const EXPECTED: &str = "(
-    float: (2.18,-1.1),
-    tuple: ((),false),
-    map: {8:'1'},
-    nested: (a:\"a\",b:'b'),
-    var: A(255,\"\"),
-    array: [(),(),()],
+    float: (2.18,-1.1,),
+    tuple: ((),false,),
+    map: {8:'1',},
+    nested: (a:\"a\",b:'b',),
+    var: A(255,\"\",),
+    array: [(),(),(),],
 )";
 
 #[test]
@@ -49,7 +49,7 @@ fn depth_limit() {
     };
 
     let pretty = ron::ser::PrettyConfig::new()
-        .with_depth_limit(1)
+        .with_depth_limit(2)
         .with_separate_tuple_members(true)
         .with_enumerate_arrays(true)
         .with_new_line("\n".to_string());
diff --git a/tests/min_max.rs b/tests/min_max.rs
index f53bcb2c..d878a950 100644
--- a/tests/min_max.rs
+++ b/tests/min_max.rs
@@ -31,35 +31,3 @@ fn test_i64_max() {
         from_str(&to_string(&std::i64::MAX).unwrap()).unwrap()
     );
 }
-
-#[test]
-fn test_i128_min() {
-    assert_eq!(
-        std::i128::MIN,
-        from_str(&to_string(&std::i128::MIN).unwrap()).unwrap()
-    );
-}
-
-#[test]
-fn test_i128_max() {
-    assert_eq!(
-        std::i128::MAX,
-        from_str(&to_string(&std::i128::MAX).unwrap()).unwrap()
-    );
-}
-
-#[test]
-fn test_u128_min() {
-    assert_eq!(
-        std::u128::MIN,
-        from_str(&to_string(&std::u128::MIN).unwrap()).unwrap()
-    );
-}
-
-#[test]
-fn test_u128_max() {
-    assert_eq!(
-        std::u128::MAX,
-        from_str(&to_string(&std::u128::MAX).unwrap()).unwrap()
-    );
-}
diff --git a/tests/preserve_sequence.rs b/tests/preserve_sequence.rs
index db34a1d3..0b040e83 100644
--- a/tests/preserve_sequence.rs
+++ b/tests/preserve_sequence.rs
@@ -1,8 +1,7 @@
-use ron::{
-    de::from_str,
-    ser::{to_string_pretty, PrettyConfig},
-};
-use serde::{Deserialize, Serialize};
+use ron::de::from_str;
+use ron::ser::{to_string_pretty, PrettyConfig};
+use serde::Deserialize;
+use serde::Serialize;
 use std::collections::BTreeMap;
 
 #[derive(Debug, Deserialize, Serialize)]
@@ -21,7 +20,7 @@ struct Nested {
 }
 
 fn read_original(source: &str) -> String {
-    source.to_string().replace("\r\n", "\n")
+    source.to_string()
 }
 
 fn make_roundtrip(source: &str) -> String {
@@ -35,8 +34,7 @@ fn make_roundtrip(source: &str) -> String {
     let pretty = PrettyConfig::new()
         .with_depth_limit(3)
         .with_separate_tuple_members(true)
-        .with_enumerate_arrays(true)
-        .with_new_line("\n".into());
+        .with_enumerate_arrays(true);
     to_string_pretty(&config, pretty).expect("Serialization failed")
 }
 
diff --git a/tests/struct_integers.rs b/tests/struct_integers.rs
deleted file mode 100644
index c7f80a0a..00000000
--- a/tests/struct_integers.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
-struct S {
-    a: i8,
-    b: i16,
-    c: i32,
-    d: i64,
-    e: i128,
-    f: u8,
-    g: u16,
-    h: u32,
-    i: u64,
-    j: u128,
-}
-
-#[test]
-fn roundtrip() {
-    let s = S {
-        a: std::i8::MIN,
-        b: std::i16::MIN,
-        c: std::i32::MIN,
-        d: std::i64::MIN,
-        e: std::i128::MIN,
-        f: std::u8::MAX,
-        g: std::u16::MAX,
-        h: std::u32::MAX,
-        i: std::u64::MAX,
-        j: std::u128::MAX,
-    };
-    let serialized = ron::ser::to_string(&s).unwrap();
-    dbg!(&serialized);
-    let deserialized = ron::de::from_str(&serialized).unwrap();
-    assert_eq!(s, deserialized,);
-}
diff --git a/tests/value.rs b/tests/value.rs
index 1e1ff5b9..05b155ff 100644
--- a/tests/value.rs
+++ b/tests/value.rs
@@ -15,14 +15,14 @@ fn char() {
 #[test]
 fn map() {
     let mut map = Map::new();
-    map.insert(Value::Char('a'), Value::Number(Number::new(1)));
+    map.insert(Value::Char('a'), Value::Number(Number::new(1f64)));
     map.insert(Value::Char('b'), Value::Number(Number::new(2f64)));
-    assert_eq!("{ 'a': 1, 'b': 2.0 }".parse(), Ok(Value::Map(map)));
+    assert_eq!("{ 'a': 1, 'b': 2 }".parse(), Ok(Value::Map(map)));
 }
 
 #[test]
 fn number() {
-    assert_eq!("42".parse(), Ok(Value::Number(Number::new(42))));
+    assert_eq!("42".parse(), Ok(Value::Number(Number::new(42f64))));
     assert_eq!("3.1415".parse(), Ok(Value::Number(Number::new(3.1415f64))));
 }
 
@@ -59,25 +59,22 @@ fn string() {
 #[test]
 fn seq() {
     let seq = vec![
-        Value::Number(Number::new(1)),
+        Value::Number(Number::new(1f64)),
         Value::Number(Number::new(2f64)),
     ];
-    assert_eq!("[1, 2.0]".parse(), Ok(Value::Seq(seq)));
+    assert_eq!("[1, 2]".parse(), Ok(Value::Seq(seq)));
 }
 
 #[test]
 fn unit() {
-    use ron::error::{Error, ErrorCode, Position};
+    use ron::de::{Error, ParseError, Position};
 
     assert_eq!("()".parse(), Ok(Value::Unit));
     assert_eq!("Foo".parse(), Ok(Value::Unit));
 
     assert_eq!(
         "".parse::<Value>(),
-        Err(Error {
-            code: ErrorCode::Eof,
-            position: Position { col: 1, line: 1 }
-        })
+        Err(Error::Parser(ParseError::Eof, Position { col: 1, line: 1 }))
     );
 }