Merge pull request #3 from adetaylor/merge-serde-json-1.0.45

Merge upstream serde_json 1.0.45
diff --git a/.travis.yml b/.travis.yml
index 5b40c48..fc5a566 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,21 +10,12 @@
         - cargo test --features raw_value
         - cargo test --features unbounded_depth
 
-    - rust: 1.15.0
-      script:
-        # preserve_order is not supported on 1.15.0
-        - cargo build --manifest-path tests/crate/Cargo.toml
-        - cargo build --manifest-path tests/crate/Cargo.toml --features arbitrary_precision
-
-    - rust: 1.18.0
-      script:
-        - cargo build --manifest-path tests/crate/Cargo.toml
-        - cargo build --manifest-path tests/crate/Cargo.toml --features preserve_order
-        - cargo build --manifest-path tests/crate/Cargo.toml --features arbitrary_precision
-
     - rust: stable
     - rust: beta
     - rust: 1.31.0
+    - rust: 1.36.0
+      script:
+        - cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc
 
     - rust: nightly
       name: Clippy
diff --git a/Cargo.toml b/Cargo.toml
index 20a6b76..3571a71 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "serde_jsonrc"
-version = "0.1.1" # remember to update html_root_url
+version = "0.1.2" # remember to update html_root_url
 authors = [
     "Michael Bolin <bolinfest@gmail.com>",
     "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
@@ -14,11 +14,12 @@
 categories = ["encoding"]
 readme = "README.md"
 include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+edition = "2018"
 
 [dependencies]
-serde = "1.0.60"
+serde = { version = "1.0.60", default-features = false }
 indexmap = { version = "1.2", optional = true }
-itoa = "0.4.3"
+itoa = { version = "0.4.3", default-features = false }
 ryu = "1.0"
 
 [dev-dependencies]
@@ -27,7 +28,7 @@
 serde_bytes = "0.11"
 serde_derive = "1.0"
 serde_stacker = "0.1"
-trybuild = "1.0"
+trybuild = { version = "1.0.19", features = ["diff"] }
 
 [workspace]
 members = ["tests/crate"]
@@ -42,7 +43,15 @@
 ### FEATURES #################################################################
 
 [features]
-default = []
+default = ["std"]
+
+std = ["serde/std"]
+
+# Provide integration for heap-allocated collections without depending on the
+# rest of the Rust standard library.
+# NOTE: Disabling both `std` *and* `alloc` features is not supported yet.
+# Available on Rust 1.36+.
+alloc = ["serde/alloc"]
 
 # Use a different representation for the map type of serde_jsonrc::Value.
 # This allows data to be read into a Value and written back to a JSON string
diff --git a/src/de.rs b/src/de.rs
index ffae118..de5507b 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -1,22 +1,20 @@
 //! Deserialize JSON data to a Rust data structure.
 
-use std::io;
-use std::marker::PhantomData;
-use std::result;
-use std::str::FromStr;
-use std::{i32, u64};
-
+use crate::error::{Error, ErrorCode, Result};
+use crate::lib::str::FromStr;
+use crate::lib::*;
+use crate::number::Number;
+use crate::read::{self, Reference};
 use serde::de::{self, Expected, Unexpected};
+use serde::{forward_to_deserialize_any, serde_if_integer128};
 
-use super::error::{Error, ErrorCode, Result};
-
-use read::{self, Reference};
-
-pub use read::{IoRead, Read, SliceRead, StrRead};
-
-use number::Number;
 #[cfg(feature = "arbitrary_precision")]
-use number::NumberDeserializer;
+use crate::number::NumberDeserializer;
+
+pub use crate::read::{Read, SliceRead, StrRead};
+
+#[cfg(feature = "std")]
+pub use crate::read::IoRead;
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -63,9 +61,10 @@
     }
 }
 
+#[cfg(feature = "std")]
 impl<R> Deserializer<read::IoRead<R>>
 where
-    R: io::Read,
+    R: crate::io::Read,
 {
     /// Creates a JSON deserializer from an `io::Read`.
     ///
@@ -97,9 +96,7 @@
     };
 }
 
-// Not public API. Should be pub(crate).
-#[doc(hidden)]
-pub enum ParserNumber {
+pub(crate) enum ParserNumber {
     F64(f64),
     U64(u64),
     I64(i64),
@@ -121,7 +118,7 @@
         }
     }
 
-    fn invalid_type(self, exp: &Expected) -> Error {
+    fn invalid_type(self, exp: &dyn Expected) -> Error {
         match self {
             ParserNumber::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp),
             ParserNumber::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp),
@@ -137,7 +134,7 @@
     /// This allows the `Deserializer` to validate that the input stream is at the end or that it
     /// only has trailing whitespace.
     pub fn end(&mut self) -> Result<()> {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
             None => Ok(()),
         }
@@ -175,7 +172,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde::Deserialize;
     /// use serde_jsonrc::Value;
     ///
@@ -212,7 +209,7 @@
     }
 
     fn peek_or_null(&mut self) -> Result<u8> {
-        Ok(try!(self.peek()).unwrap_or(b'\x00'))
+        Ok(tri!(self.peek()).unwrap_or(b'\x00'))
     }
 
     fn eat_char(&mut self) {
@@ -224,7 +221,7 @@
     }
 
     fn next_char_or_null(&mut self) -> Result<u8> {
-        Ok(try!(self.next_char()).unwrap_or(b'\x00'))
+        Ok(tri!(self.next_char()).unwrap_or(b'\x00'))
     }
 
     /// Error caused by a byte from next_char().
@@ -246,17 +243,17 @@
     fn parse_whitespace(&mut self) -> Result<Option<u8>> {
         // Consume comments as if they were whitespace.
         loop {
-            match try!(self.peek()) {
+            match tri!(self.peek()) {
                 Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
                     self.eat_char();
                 }
                 Some(b'/') => {
                     self.eat_char();
-                    match try!(self.peek()) {
+                    match tri!(self.peek()) {
                         Some(b'/') => {
                             // TODO: Read until newline.
                             loop {
-                                match try!(self.peek()) {
+                                match tri!(self.peek()) {
                                     Some(b'\n') => {
                                         self.eat_char();
                                         break;
@@ -271,10 +268,10 @@
                             }
                         }
                         Some(b'*') => loop {
-                            match try!(self.peek()) {
+                            match tri!(self.peek()) {
                                 Some(b'*') => {
                                     self.eat_char();
-                                    match try!(self.peek()) {
+                                    match tri!(self.peek()) {
                                         Some(b'/') => {
                                             self.eat_char();
                                             break;
@@ -310,7 +307,7 @@
     }
 
     #[cold]
-    fn peek_invalid_type(&mut self, exp: &Expected) -> Error {
+    fn peek_invalid_type(&mut self, exp: &dyn Expected) -> Error {
         let err = match self.peek_or_null().unwrap_or(b'\x00') {
             b'n' => {
                 self.eat_char();
@@ -340,7 +337,7 @@
                     Err(err) => return err,
                 }
             }
-            b'0'...b'9' => match self.parse_any_number(true) {
+            b'0'..=b'9' => match self.parse_any_number(true) {
                 Ok(n) => n.invalid_type(exp),
                 Err(err) => return err,
             },
@@ -364,7 +361,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -374,9 +371,9 @@
         let value = match peek {
             b'-' => {
                 self.eat_char();
-                try!(self.parse_integer(false)).visit(visitor)
+                tri!(self.parse_integer(false)).visit(visitor)
             }
-            b'0'...b'9' => try!(self.parse_integer(true)).visit(visitor),
+            b'0'..=b'9' => tri!(self.parse_integer(true)).visit(visitor),
             _ => Err(self.peek_invalid_type(&visitor)),
         };
 
@@ -388,20 +385,20 @@
 
     serde_if_integer128! {
         fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
-            match try!(self.next_char_or_null()) {
+            match tri!(self.next_char_or_null()) {
                 b'0' => {
                     buf.push('0');
                     // There can be only one leading '0'.
-                    match try!(self.peek_or_null()) {
-                        b'0'...b'9' => {
+                    match tri!(self.peek_or_null()) {
+                        b'0'..=b'9' => {
                             Err(self.peek_error(ErrorCode::InvalidNumber))
                         }
                         _ => Ok(()),
                     }
                 }
-                c @ b'1'...b'9' => {
+                c @ b'1'..=b'9' => {
                     buf.push(c as char);
-                    while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
+                    while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
                         self.eat_char();
                         buf.push(c as char);
                     }
@@ -421,7 +418,7 @@
 
     fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
         for expected in ident {
-            match try!(self.next_char()) {
+            match tri!(self.next_char()) {
                 None => {
                     return Err(self.error(ErrorCode::EofWhileParsingValue));
                 }
@@ -437,7 +434,7 @@
     }
 
     fn parse_integer(&mut self, positive: bool) -> Result<ParserNumber> {
-        let next = match try!(self.next_char()) {
+        let next = match tri!(self.next_char()) {
             Some(b) => b,
             None => {
                 return Err(self.error(ErrorCode::EofWhileParsingValue));
@@ -447,17 +444,17 @@
         match next {
             b'0' => {
                 // There can be only one leading '0'.
-                match try!(self.peek_or_null()) {
-                    b'0'...b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+                match tri!(self.peek_or_null()) {
+                    b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
                     _ => self.parse_number(positive, 0),
                 }
             }
-            c @ b'1'...b'9' => {
+            c @ b'1'..=b'9' => {
                 let mut res = (c - b'0') as u64;
 
                 loop {
-                    match try!(self.peek_or_null()) {
-                        c @ b'0'...b'9' => {
+                    match tri!(self.peek_or_null()) {
+                        c @ b'0'..=b'9' => {
                             self.eat_char();
                             let digit = (c - b'0') as u64;
 
@@ -465,7 +462,7 @@
                             // number as a `u64` until we grow too large. At that point, switch to
                             // parsing the value as a `f64`.
                             if overflow!(res * 10 + digit, u64::max_value()) {
-                                return Ok(ParserNumber::F64(try!(
+                                return Ok(ParserNumber::F64(tri!(
                                     self.parse_long_integer(
                                     positive,
                                     res,
@@ -493,8 +490,8 @@
         mut exponent: i32,
     ) -> Result<f64> {
         loop {
-            match try!(self.peek_or_null()) {
-                b'0'...b'9' => {
+            match tri!(self.peek_or_null()) {
+                b'0'..=b'9' => {
                     self.eat_char();
                     // This could overflow... if your integer is gigabytes long.
                     // Ignore that possibility.
@@ -514,9 +511,9 @@
     }
 
     fn parse_number(&mut self, positive: bool, significand: u64) -> Result<ParserNumber> {
-        Ok(match try!(self.peek_or_null()) {
-            b'.' => ParserNumber::F64(try!(self.parse_decimal(positive, significand, 0))),
-            b'e' | b'E' => ParserNumber::F64(try!(self.parse_exponent(positive, significand, 0))),
+        Ok(match tri!(self.peek_or_null()) {
+            b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0))),
+            b'e' | b'E' => ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0))),
             _ => {
                 if positive {
                     ParserNumber::U64(significand)
@@ -543,7 +540,7 @@
         self.eat_char();
 
         let mut at_least_one_digit = false;
-        while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
+        while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
             let digit = (c - b'0') as u64;
             at_least_one_digit = true;
@@ -551,7 +548,7 @@
             if overflow!(significand * 10 + digit, u64::max_value()) {
                 // The next multiply/add would overflow, so just ignore all
                 // further digits.
-                while let b'0'...b'9' = try!(self.peek_or_null()) {
+                while let b'0'..=b'9' = tri!(self.peek_or_null()) {
                     self.eat_char();
                 }
                 break;
@@ -562,13 +559,13 @@
         }
 
         if !at_least_one_digit {
-            match try!(self.peek()) {
+            match tri!(self.peek()) {
                 Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
                 None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
             }
         }
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'e' | b'E' => self.parse_exponent(positive, significand, exponent),
             _ => self.f64_from_parts(positive, significand, exponent),
         }
@@ -582,7 +579,7 @@
     ) -> Result<f64> {
         self.eat_char();
 
-        let positive_exp = match try!(self.peek_or_null()) {
+        let positive_exp = match tri!(self.peek_or_null()) {
             b'+' => {
                 self.eat_char();
                 true
@@ -594,7 +591,7 @@
             _ => true,
         };
 
-        let next = match try!(self.next_char()) {
+        let next = match tri!(self.next_char()) {
             Some(b) => b,
             None => {
                 return Err(self.error(ErrorCode::EofWhileParsingValue));
@@ -603,13 +600,13 @@
 
         // Make sure a digit follows the exponent place.
         let mut exp = match next {
-            c @ b'0'...b'9' => (c - b'0') as i32,
+            c @ b'0'..=b'9' => (c - b'0') as i32,
             _ => {
                 return Err(self.error(ErrorCode::InvalidNumber));
             }
         };
 
-        while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
+        while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
             let digit = (c - b'0') as i32;
 
@@ -644,14 +641,14 @@
             return Err(self.error(ErrorCode::NumberOutOfRange));
         }
 
-        while let b'0'...b'9' = try!(self.peek_or_null()) {
+        while let b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
         }
         Ok(if positive { 0.0 } else { -0.0 })
     }
 
     fn parse_any_signed_number(&mut self) -> Result<ParserNumber> {
-        let peek = match try!(self.peek()) {
+        let peek = match tri!(self.peek()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -663,11 +660,11 @@
                 self.eat_char();
                 self.parse_any_number(false)
             }
-            b'0'...b'9' => self.parse_any_number(true),
+            b'0'..=b'9' => self.parse_any_number(true),
             _ => Err(self.peek_error(ErrorCode::InvalidNumber)),
         };
 
-        let value = match try!(self.peek()) {
+        let value = match tri!(self.peek()) {
             Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)),
             None => value,
         };
@@ -700,7 +697,7 @@
 
     #[cfg(feature = "arbitrary_precision")]
     fn scan_or_eof(&mut self, buf: &mut String) -> Result<u8> {
-        match try!(self.next_char()) {
+        match tri!(self.next_char()) {
             Some(b) => {
                 buf.push(b as char);
                 Ok(b)
@@ -711,17 +708,17 @@
 
     #[cfg(feature = "arbitrary_precision")]
     fn scan_integer(&mut self, buf: &mut String) -> Result<()> {
-        match try!(self.scan_or_eof(buf)) {
+        match tri!(self.scan_or_eof(buf)) {
             b'0' => {
                 // There can be only one leading '0'.
-                match try!(self.peek_or_null()) {
-                    b'0'...b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+                match tri!(self.peek_or_null()) {
+                    b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
                     _ => self.scan_number(buf),
                 }
             }
-            b'1'...b'9' => loop {
-                match try!(self.peek_or_null()) {
-                    c @ b'0'...b'9' => {
+            b'1'..=b'9' => loop {
+                match tri!(self.peek_or_null()) {
+                    c @ b'0'..=b'9' => {
                         self.eat_char();
                         buf.push(c as char);
                     }
@@ -736,7 +733,7 @@
 
     #[cfg(feature = "arbitrary_precision")]
     fn scan_number(&mut self, buf: &mut String) -> Result<()> {
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'.' => self.scan_decimal(buf),
             b'e' | b'E' => self.scan_exponent(buf),
             _ => Ok(()),
@@ -749,20 +746,20 @@
         buf.push('.');
 
         let mut at_least_one_digit = false;
-        while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
+        while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
             buf.push(c as char);
             at_least_one_digit = true;
         }
 
         if !at_least_one_digit {
-            match try!(self.peek()) {
+            match tri!(self.peek()) {
                 Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
                 None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
             }
         }
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'e' | b'E' => self.scan_exponent(buf),
             _ => Ok(()),
         }
@@ -773,7 +770,7 @@
         self.eat_char();
         buf.push('e');
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'+' => {
                 self.eat_char();
             }
@@ -785,14 +782,14 @@
         }
 
         // Make sure a digit follows the exponent place.
-        match try!(self.scan_or_eof(buf)) {
-            b'0'...b'9' => {}
+        match tri!(self.scan_or_eof(buf)) {
+            b'0'..=b'9' => {}
             _ => {
                 return Err(self.error(ErrorCode::InvalidNumber));
             }
         }
 
-        while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
+        while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
             buf.push(c as char);
         }
@@ -836,7 +833,7 @@
     }
 
     fn parse_object_colon(&mut self) -> Result<()> {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(b':') => {
                 self.eat_char();
                 Ok(())
@@ -847,7 +844,7 @@
     }
 
     fn end_seq(&mut self) -> Result<()> {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(b']') => {
                 self.eat_char();
                 Ok(())
@@ -865,7 +862,7 @@
     }
 
     fn end_map(&mut self) -> Result<()> {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(b'}') => {
                 self.eat_char();
                 Ok(())
@@ -881,7 +878,7 @@
         let mut enclosing = None;
 
         loop {
-            let peek = match try!(self.parse_whitespace()) {
+            let peek = match tri!(self.parse_whitespace()) {
                 Some(b) => b,
                 None => {
                     return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -891,31 +888,31 @@
             let frame = match peek {
                 b'n' => {
                     self.eat_char();
-                    try!(self.parse_ident(b"ull"));
+                    tri!(self.parse_ident(b"ull"));
                     None
                 }
                 b't' => {
                     self.eat_char();
-                    try!(self.parse_ident(b"rue"));
+                    tri!(self.parse_ident(b"rue"));
                     None
                 }
                 b'f' => {
                     self.eat_char();
-                    try!(self.parse_ident(b"alse"));
+                    tri!(self.parse_ident(b"alse"));
                     None
                 }
                 b'-' => {
                     self.eat_char();
-                    try!(self.ignore_integer());
+                    tri!(self.ignore_integer());
                     None
                 }
-                b'0'...b'9' => {
-                    try!(self.ignore_integer());
+                b'0'..=b'9' => {
+                    tri!(self.ignore_integer());
                     None
                 }
                 b'"' => {
                     self.eat_char();
-                    try!(self.read.ignore_str());
+                    tri!(self.read.ignore_str());
                     None
                 }
                 frame @ b'[' | frame @ b'{' => {
@@ -938,7 +935,7 @@
             };
 
             loop {
-                match try!(self.parse_whitespace()) {
+                match tri!(self.parse_whitespace()) {
                     Some(b',') if accept_comma => {
                         self.eat_char();
                         break;
@@ -974,13 +971,13 @@
             }
 
             if frame == b'{' {
-                match try!(self.parse_whitespace()) {
+                match tri!(self.parse_whitespace()) {
                     Some(b'"') => self.eat_char(),
                     Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)),
                     None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
                 }
-                try!(self.read.ignore_str());
-                match try!(self.parse_whitespace()) {
+                tri!(self.read.ignore_str());
+                match tri!(self.parse_whitespace()) {
                     Some(b':') => self.eat_char(),
                     Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)),
                     None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
@@ -992,15 +989,15 @@
     }
 
     fn ignore_integer(&mut self) -> Result<()> {
-        match try!(self.next_char_or_null()) {
+        match tri!(self.next_char_or_null()) {
             b'0' => {
                 // There can be only one leading '0'.
-                if let b'0'...b'9' = try!(self.peek_or_null()) {
+                if let b'0'..=b'9' = tri!(self.peek_or_null()) {
                     return Err(self.peek_error(ErrorCode::InvalidNumber));
                 }
             }
-            b'1'...b'9' => {
-                while let b'0'...b'9' = try!(self.peek_or_null()) {
+            b'1'..=b'9' => {
+                while let b'0'..=b'9' = tri!(self.peek_or_null()) {
                     self.eat_char();
                 }
             }
@@ -1009,7 +1006,7 @@
             }
         }
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'.' => self.ignore_decimal(),
             b'e' | b'E' => self.ignore_exponent(),
             _ => Ok(()),
@@ -1020,7 +1017,7 @@
         self.eat_char();
 
         let mut at_least_one_digit = false;
-        while let b'0'...b'9' = try!(self.peek_or_null()) {
+        while let b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
             at_least_one_digit = true;
         }
@@ -1029,7 +1026,7 @@
             return Err(self.peek_error(ErrorCode::InvalidNumber));
         }
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'e' | b'E' => self.ignore_exponent(),
             _ => Ok(()),
         }
@@ -1038,20 +1035,20 @@
     fn ignore_exponent(&mut self) -> Result<()> {
         self.eat_char();
 
-        match try!(self.peek_or_null()) {
+        match tri!(self.peek_or_null()) {
             b'+' | b'-' => self.eat_char(),
             _ => {}
         }
 
         // Make sure a digit follows the exponent place.
-        match try!(self.next_char_or_null()) {
-            b'0'...b'9' => {}
+        match tri!(self.next_char_or_null()) {
+            b'0'..=b'9' => {}
             _ => {
                 return Err(self.error(ErrorCode::InvalidNumber));
             }
         }
 
-        while let b'0'...b'9' = try!(self.peek_or_null()) {
+        while let b'0'..=b'9' = tri!(self.peek_or_null()) {
             self.eat_char();
         }
 
@@ -1166,7 +1163,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1176,28 +1173,28 @@
         let value = match peek {
             b'n' => {
                 self.eat_char();
-                try!(self.parse_ident(b"ull"));
+                tri!(self.parse_ident(b"ull"));
                 visitor.visit_unit()
             }
             b't' => {
                 self.eat_char();
-                try!(self.parse_ident(b"rue"));
+                tri!(self.parse_ident(b"rue"));
                 visitor.visit_bool(true)
             }
             b'f' => {
                 self.eat_char();
-                try!(self.parse_ident(b"alse"));
+                tri!(self.parse_ident(b"alse"));
                 visitor.visit_bool(false)
             }
             b'-' => {
                 self.eat_char();
-                try!(self.parse_any_number(false)).visit(visitor)
+                tri!(self.parse_any_number(false)).visit(visitor)
             }
-            b'0'...b'9' => try!(self.parse_any_number(true)).visit(visitor),
+            b'0'..=b'9' => tri!(self.parse_any_number(true)).visit(visitor),
             b'"' => {
                 self.eat_char();
                 self.scratch.clear();
-                match try!(self.read.parse_str(&mut self.scratch)) {
+                match tri!(self.read.parse_str(&mut self.scratch)) {
                     Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
                     Reference::Copied(s) => visitor.visit_str(s),
                 }
@@ -1242,7 +1239,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1252,12 +1249,12 @@
         let value = match peek {
             b't' => {
                 self.eat_char();
-                try!(self.parse_ident(b"rue"));
+                tri!(self.parse_ident(b"rue"));
                 visitor.visit_bool(true)
             }
             b'f' => {
                 self.eat_char();
-                try!(self.parse_ident(b"alse"));
+                tri!(self.parse_ident(b"alse"));
                 visitor.visit_bool(false)
             }
             _ => Err(self.peek_invalid_type(&visitor)),
@@ -1287,7 +1284,7 @@
         {
             let mut buf = String::new();
 
-            match try!(self.parse_whitespace()) {
+            match tri!(self.parse_whitespace()) {
                 Some(b'-') => {
                     self.eat_char();
                     buf.push('-');
@@ -1298,7 +1295,7 @@
                 }
             };
 
-            try!(self.scan_integer128(&mut buf));
+            tri!(self.scan_integer128(&mut buf));
 
             let value = match buf.parse() {
                 Ok(int) => visitor.visit_i128(int),
@@ -1317,7 +1314,7 @@
         where
             V: de::Visitor<'de>,
         {
-            match try!(self.parse_whitespace()) {
+            match tri!(self.parse_whitespace()) {
                 Some(b'-') => {
                     return Err(self.peek_error(ErrorCode::NumberOutOfRange));
                 }
@@ -1328,7 +1325,7 @@
             }
 
             let mut buf = String::new();
-            try!(self.scan_integer128(&mut buf));
+            tri!(self.scan_integer128(&mut buf));
 
             let value = match buf.parse() {
                 Ok(int) => visitor.visit_u128(int),
@@ -1355,7 +1352,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1366,7 +1363,7 @@
             b'"' => {
                 self.eat_char();
                 self.scratch.clear();
-                match try!(self.read.parse_str(&mut self.scratch)) {
+                match tri!(self.read.parse_str(&mut self.scratch)) {
                     Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
                     Reference::Copied(s) => visitor.visit_str(s),
                 }
@@ -1422,7 +1419,7 @@
     ///
     /// You can use this to parse JSON strings containing invalid UTF-8 bytes.
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_bytes::ByteBuf;
     ///
     /// fn look_at_bytes() -> Result<(), serde_jsonrc::Error> {
@@ -1443,7 +1440,7 @@
     /// to be valid, and `\u` escape sequences are required to represent valid
     /// Unicode code points.
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_bytes::ByteBuf;
     ///
     /// fn look_at_bytes() {
@@ -1462,7 +1459,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1473,7 +1470,7 @@
             b'"' => {
                 self.eat_char();
                 self.scratch.clear();
-                match try!(self.read.parse_str_raw(&mut self.scratch)) {
+                match tri!(self.read.parse_str_raw(&mut self.scratch)) {
                     Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b),
                     Reference::Copied(b) => visitor.visit_bytes(b),
                 }
@@ -1502,10 +1499,10 @@
     where
         V: de::Visitor<'de>,
     {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(b'n') => {
                 self.eat_char();
-                try!(self.parse_ident(b"ull"));
+                tri!(self.parse_ident(b"ull"));
                 visitor.visit_none()
             }
             _ => visitor.visit_some(self),
@@ -1516,7 +1513,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1526,7 +1523,7 @@
         let value = match peek {
             b'n' => {
                 self.eat_char();
-                try!(self.parse_ident(b"ull"));
+                tri!(self.parse_ident(b"ull"));
                 visitor.visit_unit()
             }
             _ => Err(self.peek_invalid_type(&visitor)),
@@ -1553,7 +1550,7 @@
     {
         #[cfg(feature = "raw_value")]
         {
-            if name == ::raw::TOKEN {
+            if name == crate::raw::TOKEN {
                 return self.deserialize_raw_value(visitor);
             }
         }
@@ -1566,7 +1563,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1617,7 +1614,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1654,7 +1651,7 @@
     where
         V: de::Visitor<'de>,
     {
-        let peek = match try!(self.parse_whitespace()) {
+        let peek = match tri!(self.parse_whitespace()) {
             Some(b) => b,
             None => {
                 return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
@@ -1705,14 +1702,14 @@
     where
         V: de::Visitor<'de>,
     {
-        match try!(self.parse_whitespace()) {
+        match tri!(self.parse_whitespace()) {
             Some(b'{') => {
                 check_recursion! {
                     self.eat_char();
-                    let value = try!(visitor.visit_enum(VariantAccess::new(self)));
+                    let value = tri!(visitor.visit_enum(VariantAccess::new(self)));
                 }
 
-                match try!(self.parse_whitespace()) {
+                match tri!(self.parse_whitespace()) {
                     Some(b'}') => {
                         self.eat_char();
                         Ok(value)
@@ -1738,7 +1735,7 @@
     where
         V: de::Visitor<'de>,
     {
-        try!(self.ignore_value());
+        tri!(self.ignore_value());
         visitor.visit_unit()
     }
 }
@@ -1760,16 +1757,16 @@
     where
         T: de::DeserializeSeed<'de>,
     {
-        match try!(self.de.parse_whitespace()) {
+        match tri!(self.de.parse_whitespace()) {
             Some(b) => {
                 // List most common branch first.
                 if b != b']' {
-                    let result = Ok(Some(try!(seed.deserialize(&mut *self.de))));
+                    let result = Ok(Some(tri!(seed.deserialize(&mut *self.de))));
                     if !result.is_ok() {
                         return result;
                     }
 
-                    match try!(self.de.parse_whitespace()) {
+                    match tri!(self.de.parse_whitespace()) {
                         Some(b',') => self.de.eat_char(),
                         Some(b']') => {
                             // Ignore.
@@ -1808,7 +1805,7 @@
     where
         K: de::DeserializeSeed<'de>,
     {
-        match try!(self.de.parse_whitespace()) {
+        match tri!(self.de.parse_whitespace()) {
             Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
             Some(b'}') => {
                 return Ok(None);
@@ -1822,10 +1819,10 @@
     where
         V: de::DeserializeSeed<'de>,
     {
-        try!(self.de.parse_object_colon());
+        tri!(self.de.parse_object_colon());
         let result = seed.deserialize(&mut *self.de);
         if result.is_ok() {
-            match try!(self.de.parse_whitespace()) {
+            match tri!(self.de.parse_whitespace()) {
                 Some(b',') => self.de.eat_char(),
                 Some(b'}') => {
                     // Ignore.
@@ -1860,8 +1857,8 @@
     where
         V: de::DeserializeSeed<'de>,
     {
-        let val = try!(seed.deserialize(&mut *self.de));
-        try!(self.de.parse_object_colon());
+        let val = tri!(seed.deserialize(&mut *self.de));
+        tri!(self.de.parse_object_colon());
         Ok((val, self))
     }
 }
@@ -1913,7 +1910,7 @@
     where
         V: de::DeserializeSeed<'de>,
     {
-        let variant = try!(seed.deserialize(&mut *self.de));
+        let variant = tri!(seed.deserialize(&mut *self.de));
         Ok((variant, self))
     }
 }
@@ -1970,7 +1967,7 @@
         {
             self.de.eat_char();
             self.de.scratch.clear();
-            let string = try!(self.de.read.parse_str(&mut self.de.scratch));
+            let string = tri!(self.de.read.parse_str(&mut self.de.scratch));
             match (string.parse(), string) {
                 (Ok(integer), _) => visitor.$visit(integer),
                 (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s),
@@ -1993,7 +1990,7 @@
     {
         self.de.eat_char();
         self.de.scratch.clear();
-        match try!(self.de.read.parse_str(&mut self.de.scratch)) {
+        match tri!(self.de.read.parse_str(&mut self.de.scratch)) {
             Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
             Reference::Copied(s) => visitor.visit_str(s),
         }
@@ -2075,7 +2072,7 @@
 /// The data can consist of any JSON value. Values need to be a self-delineating value e.g.
 /// arrays, objects, or strings, or be followed by whitespace or a self-delineating value.
 ///
-/// ```edition2018
+/// ```
 /// use serde_jsonrc::{Deserializer, Value};
 ///
 /// fn main() {
@@ -2123,7 +2120,7 @@
     /// If a stream deserializer returns an EOF error, new data can be joined to
     /// `old_data[stream.byte_offset()..]` to try again.
     ///
-    /// ```edition2018
+    /// ```
     /// let data = b"[0] [1] [";
     ///
     /// let de = serde_jsonrc::Deserializer::from_slice(data);
@@ -2154,7 +2151,7 @@
     }
 
     fn peek_end_of_value(&mut self) -> Result<()> {
-        match try!(self.de.peek()) {
+        match tri!(self.de.peek()) {
             Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b'"') | Some(b'[')
             | Some(b']') | Some(b'{') | Some(b'}') | Some(b',') | Some(b':') | None => Ok(()),
             Some(_) => {
@@ -2221,10 +2218,10 @@
     T: de::Deserialize<'de>,
 {
     let mut de = Deserializer::new(read);
-    let value = try!(de::Deserialize::deserialize(&mut de));
+    let value = tri!(de::Deserialize::deserialize(&mut de));
 
     // Make sure the whole stream has been consumed.
-    try!(de.end());
+    tri!(de.end());
     Ok(value)
 }
 
@@ -2256,7 +2253,7 @@
 ///
 /// Reading the contents of a file.
 ///
-/// ```edition2018
+/// ```
 /// use serde::Deserialize;
 ///
 /// use std::error::Error;
@@ -2292,7 +2289,7 @@
 ///
 /// Reading from a persistent socket connection.
 ///
-/// ```edition2018
+/// ```
 /// use serde::Deserialize;
 ///
 /// use std::error::Error;
@@ -2331,9 +2328,10 @@
 /// is wrong with the data, for example required struct fields are missing from
 /// the JSON map or some number is too big to fit in the expected primitive
 /// type.
+#[cfg(feature = "std")]
 pub fn from_reader<R, T>(rdr: R) -> Result<T>
 where
-    R: io::Read,
+    R: crate::io::Read,
     T: de::DeserializeOwned,
 {
     from_trait(read::IoRead::new(rdr))
@@ -2343,7 +2341,7 @@
 ///
 /// # Example
 ///
-/// ```edition2018
+/// ```
 /// use serde::Deserialize;
 ///
 /// #[derive(Deserialize, Debug)]
@@ -2385,7 +2383,7 @@
 ///
 /// # Example
 ///
-/// ```edition2018
+/// ```
 /// use serde::Deserialize;
 ///
 /// #[derive(Deserialize, Debug)]
diff --git a/src/error.rs b/src/error.rs
index 4cebca5..6cad288 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,13 +1,9 @@
 //! When serializing or deserializing JSON goes wrong.
 
-use std::error;
-use std::fmt::{self, Debug, Display};
-use std::io;
-use std::result;
-use std::str::FromStr;
-
-use serde::de;
-use serde::ser;
+use crate::io;
+use crate::lib::str::FromStr;
+use crate::lib::*;
+use serde::{de, ser};
 
 /// This type represents all possible errors that can occur when serializing or
 /// deserializing JSON data.
@@ -60,10 +56,8 @@
             | ErrorCode::ExpectedCommentSlashOrStar
             | ErrorCode::ExpectedListCommaOrEnd
             | ErrorCode::ExpectedObjectCommaOrEnd
-            | ErrorCode::ExpectedObjectOrArray
             | ErrorCode::ExpectedSomeIdent
             | ErrorCode::ExpectedSomeValue
-            | ErrorCode::ExpectedSomeString
             | ErrorCode::InvalidEscape
             | ErrorCode::InvalidNumber
             | ErrorCode::NumberOutOfRange
@@ -132,14 +126,15 @@
     Eof,
 }
 
-#[cfg_attr(feature = "cargo-clippy", allow(fallible_impl_from))]
+#[cfg(feature = "std")]
+#[allow(clippy::fallible_impl_from)]
 impl From<Error> for io::Error {
     /// Convert a `serde_jsonrc::Error` into an `io::Error`.
     ///
     /// JSON syntax and data errors are turned into `InvalidData` IO errors.
     /// EOF errors are turned into `UnexpectedEof` IO errors.
     ///
-    /// ```edition2018
+    /// ```
     /// use std::io;
     ///
     /// enum MyError {
@@ -180,9 +175,7 @@
     column: usize,
 }
 
-// Not public API. Should be pub(crate).
-#[doc(hidden)]
-pub enum ErrorCode {
+pub(crate) enum ErrorCode {
     /// Catchall for syntax error messages
     Message(Box<str>),
 
@@ -217,18 +210,12 @@
     /// Expected this character to be either a `','` or a `'}'`.
     ExpectedObjectCommaOrEnd,
 
-    /// Expected this character to be either a `'{'` or a `'['`.
-    ExpectedObjectOrArray,
-
     /// Expected to parse either a `true`, `false`, or a `null`.
     ExpectedSomeIdent,
 
     /// Expected this character to start a JSON value.
     ExpectedSomeValue,
 
-    /// Expected this character to start a JSON string.
-    ExpectedSomeString,
-
     /// Invalid hex escape code.
     InvalidEscape,
 
@@ -264,10 +251,8 @@
 }
 
 impl Error {
-    // Not public API. Should be pub(crate).
-    #[doc(hidden)]
     #[cold]
-    pub fn syntax(code: ErrorCode, line: usize, column: usize) -> Self {
+    pub(crate) fn syntax(code: ErrorCode, line: usize, column: usize) -> Self {
         Error {
             err: Box::new(ErrorImpl {
                 code: code,
@@ -292,10 +277,8 @@
         }
     }
 
-    // Not public API. Should be pub(crate).
-    #[doc(hidden)]
     #[cold]
-    pub fn fix_position<F>(self, f: F) -> Self
+    pub(crate) fn fix_position<F>(self, f: F) -> Self
     where
         F: FnOnce(ErrorCode) -> Error,
     {
@@ -323,10 +306,8 @@
             ErrorCode::ExpectedCommentSlashOrStar => f.write_str("expected `/` or `*` after `/`"),
             ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"),
             ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"),
-            ErrorCode::ExpectedObjectOrArray => f.write_str("expected `{` or `[`"),
             ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"),
             ErrorCode::ExpectedSomeValue => f.write_str("expected value"),
-            ErrorCode::ExpectedSomeString => f.write_str("expected string"),
             ErrorCode::InvalidEscape => f.write_str("invalid escape"),
             ErrorCode::InvalidNumber => f.write_str("invalid number"),
             ErrorCode::NumberOutOfRange => f.write_str("number out of range"),
@@ -346,18 +327,9 @@
     }
 }
 
-impl error::Error for Error {
-    fn description(&self) -> &str {
-        match self.err.code {
-            ErrorCode::Io(ref err) => error::Error::description(err),
-            _ => {
-                // If you want a better message, use Display::fmt or to_string().
-                "JSON error"
-            }
-        }
-    }
-
-    fn cause(&self) -> Option<&error::Error> {
+impl serde::de::StdError for Error {
+    #[cfg(feature = "std")]
+    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
         match self.err.code {
             ErrorCode::Io(ref err) => Some(err),
             _ => None,
@@ -406,7 +378,7 @@
     }
 
     #[cold]
-    fn invalid_type(unexp: de::Unexpected, exp: &de::Expected) -> Self {
+    fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
         if let de::Unexpected::Unit = unexp {
             Error::custom(format_args!("invalid type: null, expected {}", exp))
         } else {
diff --git a/src/features_check/error.rs b/src/features_check/error.rs
new file mode 100644
index 0000000..22e5823
--- /dev/null
+++ b/src/features_check/error.rs
@@ -0,0 +1 @@
+"serde_json requires that either `std` (default) or `alloc` feature is enabled"
diff --git a/src/features_check/mod.rs b/src/features_check/mod.rs
new file mode 100644
index 0000000..d12032c
--- /dev/null
+++ b/src/features_check/mod.rs
@@ -0,0 +1,13 @@
+//! Shows a user-friendly compiler error on incompatible selected features.
+
+#[allow(unused_macros)]
+macro_rules! hide_from_rustfmt {
+    ($mod:item) => {
+        $mod
+    };
+}
+
+#[cfg(not(any(feature = "std", feature = "alloc")))]
+hide_from_rustfmt! {
+    mod error;
+}
diff --git a/src/io/core.rs b/src/io/core.rs
new file mode 100644
index 0000000..97354eb
--- /dev/null
+++ b/src/io/core.rs
@@ -0,0 +1,77 @@
+//! Reimplements core logic and types from `std::io` in an `alloc`-friendly
+//! fashion.
+
+use crate::lib::*;
+
+pub enum ErrorKind {
+    Other,
+}
+
+// IO errors can never occur in no-std mode. All our no-std IO implementations
+// are infallible.
+pub struct Error;
+
+impl Display for Error {
+    fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        unreachable!()
+    }
+}
+
+impl Error {
+    pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error {
+        Error
+    }
+}
+
+pub type Result<T> = result::Result<T, Error>;
+
+pub trait Write {
+    fn write(&mut self, buf: &[u8]) -> Result<usize>;
+
+    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+        // All our Write impls in no_std mode always write the whole buffer in
+        // one call infallibly.
+        let result = self.write(buf);
+        debug_assert!(result.is_ok());
+        debug_assert_eq!(result.unwrap_or(0), buf.len());
+        Ok(())
+    }
+
+    fn flush(&mut self) -> Result<()>;
+}
+
+impl<W: Write> Write for &mut W {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> Result<usize> {
+        (*self).write(buf)
+    }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+        (*self).write_all(buf)
+    }
+
+    #[inline]
+    fn flush(&mut self) -> Result<()> {
+        (*self).flush()
+    }
+}
+
+impl Write for Vec<u8> {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> Result<usize> {
+        self.extend_from_slice(buf);
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+        self.extend_from_slice(buf);
+        Ok(())
+    }
+
+    #[inline]
+    fn flush(&mut self) -> Result<()> {
+        Ok(())
+    }
+}
diff --git a/src/io/mod.rs b/src/io/mod.rs
new file mode 100644
index 0000000..9dee4a0
--- /dev/null
+++ b/src/io/mod.rs
@@ -0,0 +1,20 @@
+//! A tiny, `no_std`-friendly facade around `std::io`.
+//! Reexports types from `std` when available; otherwise reimplements and
+//! provides some of the core logic.
+//!
+//! The main reason that `std::io` hasn't found itself reexported as part of
+//! the `core` crate is the `std::io::{Read, Write}` traits' reliance on
+//! `std::io::Error`, which may contain internally a heap-allocated `Box<Error>`
+//! and/or now relying on OS-specific `std::backtrace::Backtrace`.
+
+pub use self::imp::{Error, ErrorKind, Result, Write};
+
+#[cfg(not(feature = "std"))]
+#[path = "core.rs"]
+mod imp;
+
+#[cfg(feature = "std")]
+use std::io as imp;
+
+#[cfg(feature = "std")]
+pub use std::io::{Bytes, Read};
diff --git a/src/iter.rs b/src/iter.rs
index 1a9a954..1219f08 100644
--- a/src/iter.rs
+++ b/src/iter.rs
@@ -1,4 +1,4 @@
-use std::io;
+use crate::io;
 
 pub struct LineColIterator<I> {
     iter: I,
diff --git a/src/lib.rs b/src/lib.rs
index 069441a..f09da9b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -49,7 +49,7 @@
 //! Any valid JSON data can be manipulated in the following recursive enum
 //! representation. This data structure is [`serde_jsonrc::Value`][value].
 //!
-//! ```edition2018
+//! ```
 //! # use serde_jsonrc::{Number, Map};
 //! #
 //! # #[allow(dead_code)]
@@ -69,7 +69,7 @@
 //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
 //! a TCP stream.
 //!
-//! ```edition2018
+//! ```
 //! use serde_jsonrc::{Result, Value};
 //!
 //! fn untyped_example() -> Result<()> {
@@ -127,7 +127,7 @@
 //! Serde provides a powerful way of mapping JSON data into Rust data structures
 //! largely automatically.
 //!
-//! ```edition2018
+//! ```
 //! use serde::{Deserialize, Serialize};
 //! use serde_jsonrc::Result;
 //!
@@ -189,7 +189,7 @@
 //! Serde jsonrc provides a [`json!` macro][macro] to build `serde_jsonrc::Value`
 //! objects with very natural JSON syntax.
 //!
-//! ```edition2018
+//! ```
 //! use serde_jsonrc::json;
 //!
 //! fn main() {
@@ -218,7 +218,7 @@
 //! will check at compile time that the value you are interpolating is able to
 //! be represented as JSON.
 //!
-//! ```edition2018
+//! ```
 //! # use serde_jsonrc::json;
 //! #
 //! # fn random_phone() -> u16 { 0 }
@@ -249,7 +249,7 @@
 //! [`serde_jsonrc::to_writer`][to_writer] which serializes to any `io::Write`
 //! such as a File or a TCP stream.
 //!
-//! ```edition2018
+//! ```
 //! use serde::{Deserialize, Serialize};
 //! use serde_jsonrc::Result;
 //!
@@ -287,8 +287,17 @@
 //!
 //! # No-std support
 //!
-//! This crate currently requires the Rust standard library. For JSON support in
-//! Serde without a standard library, please see the [`serde-json-core`] crate.
+//! As long as there is a memory allocator, it is possible to use serde_json
+//! without the rest of the Rust standard library. This is supported on Rust
+//! 1.36+. Disable the default "std" feature and enable the "alloc" feature:
+//!
+//! ```toml
+//! [dependencies]
+//! serde_jsonrc = { version = "1.0", default-features = false, features = ["alloc"] }
+//! ```
+//!
+//! For JSON support in Serde without a memory allocator, please see the
+//! [`serde-json-core`] crate.
 //!
 //! [value]: https://docs.serde.rs/serde_jsonrc/value/enum.Value.html
 //! [from_str]: https://docs.serde.rs/serde_jsonrc/de/fn.from_str.html
@@ -300,66 +309,122 @@
 //! [macro]: https://docs.serde.rs/serde_jsonrc/macro.json.html
 //! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_jsonrc_core/
 
-#![doc(html_root_url = "https://docs.rs/serde_jsonrc/0.1.1")]
-#![allow(unknown_lints, bare_trait_objects, ellipsis_inclusive_range_patterns)]
-#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
-#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
+#![doc(html_root_url = "https://docs.rs/serde_jsonrc/0.1.2")]
+#![deny(clippy::all, clippy::pedantic)]
 // Ignored clippy lints
-#![cfg_attr(
-    feature = "cargo-clippy",
-    allow(deprecated_cfg_attr, doc_markdown, needless_doctest_main)
+#![allow(
+    clippy::deprecated_cfg_attr,
+    clippy::doc_markdown,
+    clippy::needless_doctest_main,
+    clippy::transmute_ptr_to_ptr
 )]
 // Ignored clippy_pedantic lints
-#![cfg_attr(feature = "cargo-clippy", allow(
+#![allow(
     // Deserializer::from_str, into_iter
-    should_implement_trait,
+    clippy::should_implement_trait,
     // integer and float ser/de requires these sorts of casts
-    cast_possible_wrap,
-    cast_precision_loss,
-    cast_sign_loss,
+    clippy::cast_possible_wrap,
+    clippy::cast_precision_loss,
+    clippy::cast_sign_loss,
     // correctly used
-    integer_division,
+    clippy::integer_division,
     // things are often more readable this way
-    cast_lossless,
-    module_name_repetitions,
-    shadow_unrelated,
-    single_match_else,
-    too_many_lines,
-    use_self,
-    zero_prefixed_literal,
+    clippy::cast_lossless,
+    clippy::module_name_repetitions,
+    clippy::shadow_unrelated,
+    clippy::single_match_else,
+    clippy::too_many_lines,
+    clippy::use_self,
+    clippy::zero_prefixed_literal,
     // we support older compilers
-    checked_conversions,
-    redundant_field_names,
+    clippy::checked_conversions,
+    clippy::redundant_field_names,
     // noisy
-    must_use_candidate,
-))]
+    clippy::missing_errors_doc,
+    clippy::must_use_candidate,
+)]
 #![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
 
-#[macro_use]
-extern crate serde;
-#[cfg(feature = "preserve_order")]
-extern crate indexmap;
-extern crate itoa;
-extern crate ryu;
+////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+/// A facade around all the types we need from the `std`, `core`, and `alloc`
+/// crates. This avoids elaborate import wrangling having to happen in every
+/// module.
+mod lib {
+    mod core {
+        #[cfg(not(feature = "std"))]
+        pub use core::*;
+        #[cfg(feature = "std")]
+        pub use std::*;
+    }
+
+    pub use self::core::cell::{Cell, RefCell};
+    pub use self::core::clone::{self, Clone};
+    pub use self::core::convert::{self, From, Into};
+    pub use self::core::default::{self, Default};
+    pub use self::core::fmt::{self, Debug, Display};
+    pub use self::core::hash::{self, Hash};
+    pub use self::core::marker::{self, PhantomData};
+    pub use self::core::result::{self, Result};
+    pub use self::core::{borrow, char, cmp, iter, mem, num, ops, slice, str};
+
+    #[cfg(not(feature = "std"))]
+    pub use alloc::borrow::{Cow, ToOwned};
+    #[cfg(feature = "std")]
+    pub use std::borrow::{Cow, ToOwned};
+
+    #[cfg(not(feature = "std"))]
+    pub use alloc::string::{String, ToString};
+    #[cfg(feature = "std")]
+    pub use std::string::{String, ToString};
+
+    #[cfg(not(feature = "std"))]
+    pub use alloc::vec::{self, Vec};
+    #[cfg(feature = "std")]
+    pub use std::vec::{self, Vec};
+
+    #[cfg(not(feature = "std"))]
+    pub use alloc::boxed::Box;
+    #[cfg(feature = "std")]
+    pub use std::boxed::Box;
+
+    #[cfg(not(feature = "std"))]
+    pub use alloc::collections::{btree_map, BTreeMap};
+    #[cfg(feature = "std")]
+    pub use std::collections::{btree_map, BTreeMap};
+
+    #[cfg(feature = "std")]
+    pub use std::error;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
 #[doc(inline)]
-pub use self::de::{from_reader, from_slice, from_str, Deserializer, StreamDeserializer};
+pub use crate::de::from_reader;
 #[doc(inline)]
-pub use self::error::{Error, Result};
+pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer};
 #[doc(inline)]
-pub use self::ser::{
-    to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer, to_writer_pretty, Serializer,
-};
+pub use crate::error::{Error, Result};
 #[doc(inline)]
-pub use self::value::{from_value, to_value, Map, Number, Value};
+pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty};
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::ser::{to_writer, to_writer_pretty, Serializer};
+#[doc(inline)]
+pub use crate::value::{from_value, to_value, Map, Number, Value};
 
 // We only use our own error type; no need for From conversions provided by the
 // standard library's try! macro. This reduces lines of LLVM IR by 4%.
-macro_rules! try {
+macro_rules! tri {
     ($e:expr) => {
         match $e {
-            ::std::result::Result::Ok(val) => val,
-            ::std::result::Result::Err(err) => return ::std::result::Result::Err(err),
+            crate::lib::Result::Ok(val) => val,
+            crate::lib::Result::Err(err) => return crate::lib::Result::Err(err),
         }
     };
 }
@@ -370,9 +435,16 @@
 pub mod de;
 pub mod error;
 pub mod map;
+#[cfg(feature = "std")]
 pub mod ser;
+#[cfg(not(feature = "std"))]
+mod ser;
 pub mod value;
 
+mod features_check;
+
+mod io;
+#[cfg(feature = "std")]
 mod iter;
 mod number;
 mod read;
diff --git a/src/macros.rs b/src/macros.rs
index f6d8ccb..c460bc0 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -1,6 +1,6 @@
 /// Construct a `serde_jsonrc::Value` from a JSON literal.
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::json;
 /// #
 /// let value = json!({
@@ -22,7 +22,7 @@
 /// interpolated type decides to fail, or if the interpolated type contains a
 /// map with non-string keys, the `json!` macro will panic.
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::json;
 /// #
 /// let code = 200;
@@ -39,7 +39,7 @@
 ///
 /// Trailing commas are allowed inside both arrays and objects.
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::json;
 /// #
 /// let value = json!([
diff --git a/src/map.rs b/src/map.rs
index 5e13df9..b93b795 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -6,16 +6,11 @@
 //! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
 //! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html
 
+use crate::lib::borrow::Borrow;
+use crate::lib::iter::FromIterator;
+use crate::lib::*;
+use crate::value::Value;
 use serde::{de, ser};
-use std::borrow::Borrow;
-use std::fmt::{self, Debug};
-use std::hash::Hash;
-use std::iter::FromIterator;
-use std::ops;
-use value::Value;
-
-#[cfg(not(feature = "preserve_order"))]
-use std::collections::{btree_map, BTreeMap};
 
 #[cfg(feature = "preserve_order")]
 use indexmap::{self, IndexMap};
@@ -132,16 +127,27 @@
         return self.map.remove(key);
     }
 
+    /// Moves all elements from other into Self, leaving other empty.
+    #[inline]
+    pub fn append(&mut self, other: &mut Self) {
+        #[cfg(feature = "preserve_order")]
+        for (k, v) in std::mem::replace(&mut other.map, MapImpl::default()).into_iter() {
+            self.map.insert(k, v);
+        }
+        #[cfg(not(feature = "preserve_order"))]
+        self.map.append(&mut other.map);
+    }
+
     /// Gets the given key's corresponding entry in the map for in-place
     /// manipulation.
     pub fn entry<S>(&mut self, key: S) -> Entry
     where
         S: Into<String>,
     {
+        #[cfg(not(feature = "preserve_order"))]
+        use crate::lib::btree_map::Entry as EntryImpl;
         #[cfg(feature = "preserve_order")]
         use indexmap::map::Entry as EntryImpl;
-        #[cfg(not(feature = "preserve_order"))]
-        use std::collections::btree_map::Entry as EntryImpl;
 
         match self.map.entry(key.into()) {
             EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }),
@@ -239,7 +245,7 @@
 /// Access an element of this map. Panics if the given key is not present in the
 /// map.
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::Value;
 /// #
 /// # let val = &Value::String("".to_owned());
@@ -267,7 +273,7 @@
 /// Mutably access an element of this map. Panics if the given key is not
 /// present in the map.
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::json;
 /// #
 /// # let mut map = serde_jsonrc::Map::new();
@@ -299,10 +305,10 @@
         S: ser::Serializer,
     {
         use serde::ser::SerializeMap;
-        let mut map = try!(serializer.serialize_map(Some(self.len())));
+        let mut map = tri!(serializer.serialize_map(Some(self.len())));
         for (k, v) in self {
-            try!(map.serialize_key(k));
-            try!(map.serialize_value(v));
+            tri!(map.serialize_key(k));
+            tri!(map.serialize_value(v));
         }
         map.end()
     }
@@ -338,7 +344,7 @@
             {
                 let mut values = Map::new();
 
-                while let Some((key, value)) = try!(visitor.next_entry()) {
+                while let Some((key, value)) = tri!(visitor.next_entry()) {
                     values.insert(key, value);
                 }
 
@@ -443,7 +449,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// let mut map = serde_jsonrc::Map::new();
     /// assert_eq!(map.entry("serde").key(), &"serde");
     /// ```
@@ -459,7 +465,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut map = serde_jsonrc::Map::new();
@@ -480,7 +486,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut map = serde_jsonrc::Map::new();
@@ -505,7 +511,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::map::Entry;
     ///
     /// let mut map = serde_jsonrc::Map::new();
@@ -527,7 +533,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -552,7 +558,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -576,7 +582,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -600,7 +606,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -626,7 +632,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -653,7 +659,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
@@ -678,7 +684,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// use serde_jsonrc::map::Entry;
diff --git a/src/number.rs b/src/number.rs
index 7ed3066..638c1d4 100644
--- a/src/number.rs
+++ b/src/number.rs
@@ -1,24 +1,19 @@
-use error::Error;
+use crate::de::ParserNumber;
+use crate::error::Error;
+use crate::lib::*;
 use serde::de::{self, Unexpected, Visitor};
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::fmt::{self, Debug, Display};
+use serde::{
+    forward_to_deserialize_any, serde_if_integer128, Deserialize, Deserializer, Serialize,
+    Serializer,
+};
 
 #[cfg(feature = "arbitrary_precision")]
-use itoa;
-#[cfg(feature = "arbitrary_precision")]
-use ryu;
+use crate::error::ErrorCode;
 #[cfg(feature = "arbitrary_precision")]
 use serde::de::{IntoDeserializer, MapAccess};
 
-use de::ParserNumber;
-
 #[cfg(feature = "arbitrary_precision")]
-use error::ErrorCode;
-
-#[cfg(feature = "arbitrary_precision")]
-/// Not public API. Should be pub(crate).
-#[doc(hidden)]
-pub const TOKEN: &'static str = "$serde_jsonrc::private::Number";
+pub(crate) const TOKEN: &str = "$serde_jsonrc::private::Number";
 
 /// Represents a JSON number, whether integer or floating point.
 #[derive(Clone, PartialEq)]
@@ -46,7 +41,7 @@
     /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
     /// return the integer value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let big = i64::max_value() as u64 + 10;
@@ -77,7 +72,7 @@
     /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
     /// return the integer value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
@@ -109,7 +104,7 @@
     /// Currently this function returns true if and only if both `is_i64` and
     /// `is_u64` return false but this is not a guarantee in the future.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
@@ -141,7 +136,7 @@
     /// If the `Number` is an integer, represent it as i64 if possible. Returns
     /// None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let big = i64::max_value() as u64 + 10;
@@ -172,7 +167,7 @@
     /// If the `Number` is an integer, represent it as u64 if possible. Returns
     /// None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
@@ -194,7 +189,7 @@
 
     /// Represents the number as f64 if possible. Returns None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
@@ -218,7 +213,7 @@
     /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
     /// numbers.
     ///
-    /// ```edition2018
+    /// ```
     /// # use std::f64;
     /// #
     /// # use serde_jsonrc::Number;
@@ -434,7 +429,7 @@
             where
                 E: de::Error,
             {
-                let n = try!(s.parse().map_err(de::Error::custom));
+                let n = tri!(s.parse().map_err(de::Error::custom));
                 Ok(NumberFromString { value: n })
             }
         }
@@ -570,9 +565,7 @@
 }
 
 #[cfg(feature = "arbitrary_precision")]
-// Not public API. Should be pub(crate).
-#[doc(hidden)]
-pub struct NumberDeserializer {
+pub(crate) struct NumberDeserializer {
     pub number: Option<String>,
 }
 
@@ -731,10 +724,8 @@
 
 impl Number {
     #[cfg(not(feature = "arbitrary_precision"))]
-    // Not public API. Should be pub(crate).
-    #[doc(hidden)]
     #[cold]
-    pub fn unexpected(&self) -> Unexpected {
+    pub(crate) fn unexpected(&self) -> Unexpected {
         match self.n {
             N::PosInt(u) => Unexpected::Unsigned(u),
             N::NegInt(i) => Unexpected::Signed(i),
@@ -743,10 +734,8 @@
     }
 
     #[cfg(feature = "arbitrary_precision")]
-    // Not public API. Should be pub(crate).
-    #[doc(hidden)]
     #[cold]
-    pub fn unexpected(&self) -> Unexpected {
+    pub(crate) fn unexpected(&self) -> Unexpected {
         Unexpected::Other("number")
     }
 }
diff --git a/src/raw.rs b/src/raw.rs
index 0aea3f6..2d7703a 100644
--- a/src/raw.rs
+++ b/src/raw.rs
@@ -1,15 +1,13 @@
-use std::fmt::{self, Debug, Display};
-use std::mem;
-
+use crate::error::Error;
+use crate::lib::*;
 use serde::de::value::BorrowedStrDeserializer;
 use serde::de::{
     self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected,
     Visitor,
 };
+use serde::forward_to_deserialize_any;
 use serde::ser::{Serialize, SerializeStruct, Serializer};
 
-use error::Error;
-
 /// Reference to a range of bytes encompassing a single valid JSON value in the
 /// input data.
 ///
@@ -32,7 +30,7 @@
 ///
 /// # Example
 ///
-/// ```edition2018
+/// ```
 /// use serde::{Deserialize, Serialize};
 /// use serde_jsonrc::{Result, value::RawValue};
 ///
@@ -78,7 +76,7 @@
 ///
 /// The typical usage of `RawValue` will be in the borrowed form:
 ///
-/// ```edition2018
+/// ```
 /// # use serde::Deserialize;
 /// # use serde_jsonrc::value::RawValue;
 /// #
@@ -101,7 +99,7 @@
 /// [`serde_jsonrc::from_slice`]: ../fn.from_slice.html
 /// [`serde_jsonrc::from_reader`]: ../fn.from_reader.html
 ///
-/// ```edition2018
+/// ```
 /// # use serde::Deserialize;
 /// # use serde_jsonrc::value::RawValue;
 /// #
@@ -171,7 +169,7 @@
     /// - the input has capacity equal to its length.
     pub fn from_string(json: String) -> Result<Box<Self>, Error> {
         {
-            let borrowed = ::from_str::<&Self>(&json)?;
+            let borrowed = crate::from_str::<&Self>(&json)?;
             if borrowed.json.len() < json.len() {
                 return Ok(borrowed.to_owned());
             }
@@ -183,7 +181,7 @@
     ///
     /// # Example
     ///
-    /// ```edition2018
+    /// ```
     /// use serde::Deserialize;
     /// use serde_jsonrc::{Result, value::RawValue};
     ///
@@ -217,7 +215,7 @@
     }
 }
 
-pub const TOKEN: &'static str = "$serde_jsonrc::private::RawValue";
+pub const TOKEN: &str = "$serde_jsonrc::private::RawValue";
 
 impl Serialize for RawValue {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
diff --git a/src/read.rs b/src/read.rs
index 00538d9..3847f72 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -1,16 +1,19 @@
-use std::ops::Deref;
-use std::{char, cmp, io, str};
+use crate::error::{Error, ErrorCode, Result};
+use crate::lib::ops::Deref;
+use crate::lib::*;
 
+#[cfg(feature = "std")]
+use crate::io;
+#[cfg(feature = "std")]
+use crate::iter::LineColIterator;
+
+#[cfg(feature = "raw_value")]
+use crate::raw::BorrowedRawDeserializer;
+#[cfg(all(feature = "raw_value", feature = "std"))]
+use crate::raw::OwnedRawDeserializer;
 #[cfg(feature = "raw_value")]
 use serde::de::Visitor;
 
-use iter::LineColIterator;
-
-use error::{Error, ErrorCode, Result};
-
-#[cfg(feature = "raw_value")]
-use raw::{BorrowedRawDeserializer, OwnedRawDeserializer};
-
 /// Trait used by the deserializer for iterating over input. This is manually
 /// "specialized" for iterating over &[u8]. Once feature(specialization) is
 /// stable we can use actual specialization.
@@ -118,6 +121,7 @@
 }
 
 /// JSON input source that reads from a std::io input stream.
+#[cfg(feature = "std")]
 pub struct IoRead<R>
 where
     R: io::Read,
@@ -157,6 +161,7 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+#[cfg(feature = "std")]
 impl<R> IoRead<R>
 where
     R: io::Read,
@@ -181,8 +186,10 @@
     }
 }
 
+#[cfg(feature = "std")]
 impl<R> private::Sealed for IoRead<R> where R: io::Read {}
 
+#[cfg(feature = "std")]
 impl<R> IoRead<R>
 where
     R: io::Read,
@@ -198,7 +205,7 @@
         F: FnOnce(&'s Self, &'s [u8]) -> Result<T>,
     {
         loop {
-            let ch = try!(next_or_eof(self));
+            let ch = tri!(next_or_eof(self));
             if !ESCAPE[ch as usize] {
                 scratch.push(ch);
                 continue;
@@ -208,7 +215,7 @@
                     return result(self, scratch);
                 }
                 b'\\' => {
-                    try!(parse_escape(self, scratch));
+                    tri!(parse_escape(self, scratch));
                 }
                 _ => {
                     if validate {
@@ -221,6 +228,7 @@
     }
 }
 
+#[cfg(feature = "std")]
 impl<'de, R> Read<'de> for IoRead<R>
 where
     R: io::Read,
@@ -318,7 +326,7 @@
 
     fn ignore_str(&mut self) -> Result<()> {
         loop {
-            let ch = try!(next_or_eof(self));
+            let ch = tri!(next_or_eof(self));
             if !ESCAPE[ch as usize] {
                 continue;
             }
@@ -327,7 +335,7 @@
                     return Ok(());
                 }
                 b'\\' => {
-                    try!(ignore_escape(self));
+                    tri!(ignore_escape(self));
                 }
                 _ => {
                     return error(self, ErrorCode::ControlCharacterWhileParsingString);
@@ -339,7 +347,7 @@
     fn decode_hex_escape(&mut self) -> Result<u16> {
         let mut n = 0;
         for _ in 0..4 {
-            match decode_hex_val(try!(next_or_eof(self))) {
+            match decode_hex_val(tri!(next_or_eof(self))) {
                 None => return error(self, ErrorCode::InvalidEscape),
                 Some(val) => {
                     n = (n << 4) + val;
@@ -445,7 +453,7 @@
                 b'\\' => {
                     scratch.extend_from_slice(&self.slice[start..self.index]);
                     self.index += 1;
-                    try!(parse_escape(self, scratch));
+                    tri!(parse_escape(self, scratch));
                     start = self.index;
                 }
                 _ => {
@@ -531,7 +539,7 @@
                 }
                 b'\\' => {
                     self.index += 1;
-                    try!(ignore_escape(self));
+                    tri!(ignore_escape(self));
                 }
                 _ => {
                     return error(self, ErrorCode::ControlCharacterWhileParsingString);
@@ -674,7 +682,7 @@
 // Lookup table of bytes that must be escaped. A value of true at index i means
 // that byte i requires an escape sequence in the input.
 static ESCAPE: [bool; 256] = {
-    const CT: bool = true; // control character \x00...\x1F
+    const CT: bool = true; // control character \x00..=\x1F
     const QU: bool = true; // quote \x22
     const BS: bool = true; // backslash \x5C
     const __: bool = false; // allow unescaped
@@ -700,7 +708,7 @@
 };
 
 fn next_or_eof<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<u8> {
-    match try!(read.next()) {
+    match tri!(read.next()) {
         Some(b) => Ok(b),
         None => error(read, ErrorCode::EofWhileParsingString),
     }
@@ -718,7 +726,7 @@
 /// Parses a JSON escape sequence and appends it into the scratch space. Assumes
 /// the previous byte read was a backslash.
 fn parse_escape<'de, R: Read<'de>>(read: &mut R, scratch: &mut Vec<u8>) -> Result<()> {
-    let ch = try!(next_or_eof(read));
+    let ch = tri!(next_or_eof(read));
 
     match ch {
         b'"' => scratch.push(b'"'),
@@ -730,22 +738,22 @@
         b'r' => scratch.push(b'\r'),
         b't' => scratch.push(b'\t'),
         b'u' => {
-            let c = match try!(read.decode_hex_escape()) {
-                0xDC00...0xDFFF => {
+            let c = match tri!(read.decode_hex_escape()) {
+                0xDC00..=0xDFFF => {
                     return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
                 }
 
                 // Non-BMP characters are encoded as a sequence of
                 // two hex escapes, representing UTF-16 surrogates.
-                n1 @ 0xD800...0xDBFF => {
-                    if try!(next_or_eof(read)) != b'\\' {
+                n1 @ 0xD800..=0xDBFF => {
+                    if tri!(next_or_eof(read)) != b'\\' {
                         return error(read, ErrorCode::UnexpectedEndOfHexEscape);
                     }
-                    if try!(next_or_eof(read)) != b'u' {
+                    if tri!(next_or_eof(read)) != b'u' {
                         return error(read, ErrorCode::UnexpectedEndOfHexEscape);
                     }
 
-                    let n2 = try!(read.decode_hex_escape());
+                    let n2 = tri!(read.decode_hex_escape());
 
                     if n2 < 0xDC00 || n2 > 0xDFFF {
                         return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
@@ -782,27 +790,27 @@
 /// Parses a JSON escape sequence and discards the value. Assumes the previous
 /// byte read was a backslash.
 fn ignore_escape<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<()> {
-    let ch = try!(next_or_eof(read));
+    let ch = tri!(next_or_eof(read));
 
     match ch {
         b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
         b'u' => {
-            let n = match try!(read.decode_hex_escape()) {
-                0xDC00...0xDFFF => {
+            let n = match tri!(read.decode_hex_escape()) {
+                0xDC00..=0xDFFF => {
                     return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
                 }
 
                 // Non-BMP characters are encoded as a sequence of
                 // two hex escapes, representing UTF-16 surrogates.
-                n1 @ 0xD800...0xDBFF => {
-                    if try!(next_or_eof(read)) != b'\\' {
+                n1 @ 0xD800..=0xDBFF => {
+                    if tri!(next_or_eof(read)) != b'\\' {
                         return error(read, ErrorCode::UnexpectedEndOfHexEscape);
                     }
-                    if try!(next_or_eof(read)) != b'u' {
+                    if tri!(next_or_eof(read)) != b'u' {
                         return error(read, ErrorCode::UnexpectedEndOfHexEscape);
                     }
 
-                    let n2 = try!(read.decode_hex_escape());
+                    let n2 = tri!(read.decode_hex_escape());
 
                     if n2 < 0xDC00 || n2 > 0xDFFF {
                         return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
diff --git a/src/ser.rs b/src/ser.rs
index cfae381..1387e6c 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -1,15 +1,11 @@
 //! Serialize a Rust data structure into JSON data.
 
-use std::fmt;
-use std::io;
-use std::num::FpCategory;
-use std::str;
-
-use super::error::{Error, ErrorCode, Result};
+use crate::error::{Error, ErrorCode, Result};
+use crate::io;
+use crate::lib::num::FpCategory;
+use crate::lib::*;
 use serde::ser::{self, Impossible, Serialize};
-
-use itoa;
-use ryu;
+use serde::serde_if_integer128;
 
 /// A structure for serializing Rust values into JSON.
 pub struct Serializer<W, F = CompactFormatter> {
@@ -79,7 +75,7 @@
 
     #[inline]
     fn serialize_bool(self, value: bool) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_bool(&mut self.writer, value)
             .map_err(Error::io));
@@ -88,7 +84,7 @@
 
     #[inline]
     fn serialize_i8(self, value: i8) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_i8(&mut self.writer, value)
             .map_err(Error::io));
@@ -97,7 +93,7 @@
 
     #[inline]
     fn serialize_i16(self, value: i16) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_i16(&mut self.writer, value)
             .map_err(Error::io));
@@ -106,7 +102,7 @@
 
     #[inline]
     fn serialize_i32(self, value: i32) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_i32(&mut self.writer, value)
             .map_err(Error::io));
@@ -115,7 +111,7 @@
 
     #[inline]
     fn serialize_i64(self, value: i64) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_i64(&mut self.writer, value)
             .map_err(Error::io));
@@ -132,7 +128,7 @@
 
     #[inline]
     fn serialize_u8(self, value: u8) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_u8(&mut self.writer, value)
             .map_err(Error::io));
@@ -141,7 +137,7 @@
 
     #[inline]
     fn serialize_u16(self, value: u16) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_u16(&mut self.writer, value)
             .map_err(Error::io));
@@ -150,7 +146,7 @@
 
     #[inline]
     fn serialize_u32(self, value: u32) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_u32(&mut self.writer, value)
             .map_err(Error::io));
@@ -159,7 +155,7 @@
 
     #[inline]
     fn serialize_u64(self, value: u64) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_u64(&mut self.writer, value)
             .map_err(Error::io));
@@ -178,13 +174,13 @@
     fn serialize_f32(self, value: f32) -> Result<()> {
         match value.classify() {
             FpCategory::Nan | FpCategory::Infinite => {
-                try!(self
+                tri!(self
                     .formatter
                     .write_null(&mut self.writer)
                     .map_err(Error::io));
             }
             _ => {
-                try!(self
+                tri!(self
                     .formatter
                     .write_f32(&mut self.writer, value)
                     .map_err(Error::io));
@@ -197,13 +193,13 @@
     fn serialize_f64(self, value: f64) -> Result<()> {
         match value.classify() {
             FpCategory::Nan | FpCategory::Infinite => {
-                try!(self
+                tri!(self
                     .formatter
                     .write_null(&mut self.writer)
                     .map_err(Error::io));
             }
             _ => {
-                try!(self
+                tri!(self
                     .formatter
                     .write_f64(&mut self.writer, value)
                     .map_err(Error::io));
@@ -221,23 +217,23 @@
 
     #[inline]
     fn serialize_str(self, value: &str) -> Result<()> {
-        try!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io));
+        tri!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io));
         Ok(())
     }
 
     #[inline]
     fn serialize_bytes(self, value: &[u8]) -> Result<()> {
         use serde::ser::SerializeSeq;
-        let mut seq = try!(self.serialize_seq(Some(value.len())));
+        let mut seq = tri!(self.serialize_seq(Some(value.len())));
         for byte in value {
-            try!(seq.serialize_element(byte));
+            tri!(seq.serialize_element(byte));
         }
         seq.end()
     }
 
     #[inline]
     fn serialize_unit(self) -> Result<()> {
-        try!(self
+        tri!(self
             .formatter
             .write_null(&mut self.writer)
             .map_err(Error::io));
@@ -279,29 +275,29 @@
     where
         T: Serialize,
     {
-        try!(self
+        tri!(self
             .formatter
             .begin_object(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_key(&mut self.writer, true)
             .map_err(Error::io));
-        try!(self.serialize_str(variant));
-        try!(self
+        tri!(self.serialize_str(variant));
+        tri!(self
             .formatter
             .end_object_key(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_value(&mut self.writer)
             .map_err(Error::io));
-        try!(value.serialize(&mut *self));
-        try!(self
+        tri!(value.serialize(&mut *self));
+        tri!(self
             .formatter
             .end_object_value(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .end_object(&mut self.writer)
             .map_err(Error::io));
@@ -324,11 +320,11 @@
     #[inline]
     fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
         if len == Some(0) {
-            try!(self
+            tri!(self
                 .formatter
                 .begin_array(&mut self.writer)
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .formatter
                 .end_array(&mut self.writer)
                 .map_err(Error::io));
@@ -337,7 +333,7 @@
                 state: State::Empty,
             })
         } else {
-            try!(self
+            tri!(self
                 .formatter
                 .begin_array(&mut self.writer)
                 .map_err(Error::io));
@@ -370,20 +366,20 @@
         variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeTupleVariant> {
-        try!(self
+        tri!(self
             .formatter
             .begin_object(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_key(&mut self.writer, true)
             .map_err(Error::io));
-        try!(self.serialize_str(variant));
-        try!(self
+        tri!(self.serialize_str(variant));
+        tri!(self
             .formatter
             .end_object_key(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_value(&mut self.writer)
             .map_err(Error::io));
@@ -393,11 +389,11 @@
     #[inline]
     fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
         if len == Some(0) {
-            try!(self
+            tri!(self
                 .formatter
                 .begin_object(&mut self.writer)
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .formatter
                 .end_object(&mut self.writer)
                 .map_err(Error::io));
@@ -406,7 +402,7 @@
                 state: State::Empty,
             })
         } else {
-            try!(self
+            tri!(self
                 .formatter
                 .begin_object(&mut self.writer)
                 .map_err(Error::io));
@@ -421,9 +417,9 @@
     fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
         match name {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::TOKEN => Ok(Compound::Number { ser: self }),
+            crate::number::TOKEN => Ok(Compound::Number { ser: self }),
             #[cfg(feature = "raw_value")]
-            ::raw::TOKEN => Ok(Compound::RawValue { ser: self }),
+            crate::raw::TOKEN => Ok(Compound::RawValue { ser: self }),
             _ => self.serialize_map(Some(len)),
         }
     }
@@ -436,20 +432,20 @@
         variant: &'static str,
         len: usize,
     ) -> Result<Self::SerializeStructVariant> {
-        try!(self
+        tri!(self
             .formatter
             .begin_object(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_key(&mut self.writer, true)
             .map_err(Error::io));
-        try!(self.serialize_str(variant));
-        try!(self
+        tri!(self.serialize_str(variant));
+        tri!(self
             .formatter
             .end_object_key(&mut self.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .formatter
             .begin_object_value(&mut self.writer)
             .map_err(Error::io));
@@ -460,7 +456,7 @@
     where
         T: fmt::Display,
     {
-        use std::fmt::Write;
+        use self::fmt::Write;
 
         struct Adapter<'ser, W: 'ser, F: 'ser> {
             writer: &'ser mut W,
@@ -485,7 +481,7 @@
             }
         }
 
-        try!(self
+        tri!(self
             .formatter
             .begin_string(&mut self.writer)
             .map_err(Error::io));
@@ -502,7 +498,7 @@
                 }
             }
         }
-        try!(self
+        tri!(self
             .formatter
             .end_string(&mut self.writer)
             .map_err(Error::io));
@@ -510,16 +506,16 @@
     }
 }
 
-#[derive(Eq, PartialEq)]
-/// Not public API. Should be pub(crate).
+// Not public API. Should be pub(crate).
 #[doc(hidden)]
+#[derive(Eq, PartialEq)]
 pub enum State {
     Empty,
     First,
     Rest,
 }
 
-/// Not public API. Should be pub(crate).
+// Not public API. Should be pub(crate).
 #[doc(hidden)]
 pub enum Compound<'a, W: 'a, F: 'a> {
     Map {
@@ -550,13 +546,13 @@
                 ref mut ser,
                 ref mut state,
             } => {
-                try!(ser
+                tri!(ser
                     .formatter
                     .begin_array_value(&mut ser.writer, *state == State::First)
                     .map_err(Error::io));
                 *state = State::Rest;
-                try!(value.serialize(&mut **ser));
-                try!(ser
+                tri!(value.serialize(&mut **ser));
+                tri!(ser
                     .formatter
                     .end_array_value(&mut ser.writer)
                     .map_err(Error::io));
@@ -575,7 +571,7 @@
             Compound::Map { ser, state } => {
                 match state {
                     State::Empty => {}
-                    _ => try!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
+                    _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
                 }
                 Ok(())
             }
@@ -653,13 +649,13 @@
             Compound::Map { ser, state } => {
                 match state {
                     State::Empty => {}
-                    _ => try!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
+                    _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
                 }
-                try!(ser
+                tri!(ser
                     .formatter
                     .end_object_value(&mut ser.writer)
                     .map_err(Error::io));
-                try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
+                tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
                 Ok(())
             }
             #[cfg(feature = "arbitrary_precision")]
@@ -688,15 +684,15 @@
                 ref mut ser,
                 ref mut state,
             } => {
-                try!(ser
+                tri!(ser
                     .formatter
                     .begin_object_key(&mut ser.writer, *state == State::First)
                     .map_err(Error::io));
                 *state = State::Rest;
 
-                try!(key.serialize(MapKeySerializer { ser: *ser }));
+                tri!(key.serialize(MapKeySerializer { ser: *ser }));
 
-                try!(ser
+                tri!(ser
                     .formatter
                     .end_object_key(&mut ser.writer)
                     .map_err(Error::io));
@@ -716,12 +712,12 @@
     {
         match *self {
             Compound::Map { ref mut ser, .. } => {
-                try!(ser
+                tri!(ser
                     .formatter
                     .begin_object_value(&mut ser.writer)
                     .map_err(Error::io));
-                try!(value.serialize(&mut **ser));
-                try!(ser
+                tri!(value.serialize(&mut **ser));
+                tri!(ser
                     .formatter
                     .end_object_value(&mut ser.writer)
                     .map_err(Error::io));
@@ -740,7 +736,7 @@
             Compound::Map { ser, state } => {
                 match state {
                     State::Empty => {}
-                    _ => try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
+                    _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
                 }
                 Ok(())
             }
@@ -767,13 +763,13 @@
     {
         match *self {
             Compound::Map { .. } => {
-                try!(ser::SerializeMap::serialize_key(self, key));
+                tri!(ser::SerializeMap::serialize_key(self, key));
                 ser::SerializeMap::serialize_value(self, value)
             }
             #[cfg(feature = "arbitrary_precision")]
             Compound::Number { ref mut ser, .. } => {
-                if key == ::number::TOKEN {
-                    try!(value.serialize(NumberStrEmitter(&mut *ser)));
+                if key == crate::number::TOKEN {
+                    tri!(value.serialize(NumberStrEmitter(&mut *ser)));
                     Ok(())
                 } else {
                     Err(invalid_number())
@@ -781,8 +777,8 @@
             }
             #[cfg(feature = "raw_value")]
             Compound::RawValue { ref mut ser, .. } => {
-                if key == ::raw::TOKEN {
-                    try!(value.serialize(RawValueStrEmitter(&mut *ser)));
+                if key == crate::raw::TOKEN {
+                    tri!(value.serialize(RawValueStrEmitter(&mut *ser)));
                     Ok(())
                 } else {
                     Err(invalid_raw_value())
@@ -831,13 +827,13 @@
             Compound::Map { ser, state } => {
                 match state {
                     State::Empty => {}
-                    _ => try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
+                    _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
                 }
-                try!(ser
+                tri!(ser
                     .formatter
                     .end_object_value(&mut ser.writer)
                     .map_err(Error::io));
-                try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
+                tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
                 Ok(())
             }
             #[cfg(feature = "arbitrary_precision")]
@@ -910,17 +906,17 @@
     }
 
     fn serialize_i8(self, value: i8) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_i8(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -929,17 +925,17 @@
     }
 
     fn serialize_i16(self, value: i16) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_i16(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -948,17 +944,17 @@
     }
 
     fn serialize_i32(self, value: i32) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_i32(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -967,17 +963,17 @@
     }
 
     fn serialize_i64(self, value: i64) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_i64(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -987,17 +983,17 @@
 
     serde_if_integer128! {
         fn serialize_i128(self, value: i128) -> Result<()> {
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .begin_string(&mut self.ser.writer)
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .write_number_str(&mut self.ser.writer, &value.to_string())
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .end_string(&mut self.ser.writer)
@@ -1007,17 +1003,17 @@
     }
 
     fn serialize_u8(self, value: u8) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_u8(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -1026,17 +1022,17 @@
     }
 
     fn serialize_u16(self, value: u16) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_u16(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -1045,17 +1041,17 @@
     }
 
     fn serialize_u32(self, value: u32) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_u32(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -1064,17 +1060,17 @@
     }
 
     fn serialize_u64(self, value: u64) -> Result<()> {
-        try!(self
+        tri!(self
             .ser
             .formatter
             .begin_string(&mut self.ser.writer)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .write_u64(&mut self.ser.writer, value)
             .map_err(Error::io));
-        try!(self
+        tri!(self
             .ser
             .formatter
             .end_string(&mut self.ser.writer)
@@ -1084,17 +1080,17 @@
 
     serde_if_integer128! {
         fn serialize_u128(self, value: u128) -> Result<()> {
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .begin_string(&mut self.ser.writer)
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .write_number_str(&mut self.ser.writer, &value.to_string())
                 .map_err(Error::io));
-            try!(self
+            tri!(self
                 .ser
                 .formatter
                 .end_string(&mut self.ser.writer)
@@ -1638,7 +1634,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `-123` to the specified writer.
@@ -1647,7 +1645,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `-123` to the specified writer.
@@ -1656,7 +1656,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `-123` to the specified writer.
@@ -1665,7 +1667,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `123` to the specified writer.
@@ -1674,7 +1678,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `123` to the specified writer.
@@ -1683,7 +1689,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `123` to the specified writer.
@@ -1692,7 +1700,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes an integer value like `123` to the specified writer.
@@ -1701,7 +1711,9 @@
     where
         W: io::Write,
     {
-        itoa::write(writer, value).map(drop)
+        let mut buffer = itoa::Buffer::new();
+        let s = buffer.format(value);
+        writer.write_all(s.as_bytes())
     }
 
     /// Writes a floating point value like `-31.26e+12` to the specified writer.
@@ -1976,8 +1988,8 @@
         self.current_indent -= 1;
 
         if self.has_value {
-            try!(writer.write_all(b"\n"));
-            try!(indent(writer, self.current_indent, self.indent));
+            tri!(writer.write_all(b"\n"));
+            tri!(indent(writer, self.current_indent, self.indent));
         }
 
         writer.write_all(b"]")
@@ -1989,11 +2001,11 @@
         W: io::Write,
     {
         if first {
-            try!(writer.write_all(b"\n"));
+            tri!(writer.write_all(b"\n"));
         } else {
-            try!(writer.write_all(b",\n"));
+            tri!(writer.write_all(b",\n"));
         }
-        try!(indent(writer, self.current_indent, self.indent));
+        tri!(indent(writer, self.current_indent, self.indent));
         Ok(())
     }
 
@@ -2024,8 +2036,8 @@
         self.current_indent -= 1;
 
         if self.has_value {
-            try!(writer.write_all(b"\n"));
-            try!(indent(writer, self.current_indent, self.indent));
+            tri!(writer.write_all(b"\n"));
+            tri!(indent(writer, self.current_indent, self.indent));
         }
 
         writer.write_all(b"}")
@@ -2037,9 +2049,9 @@
         W: io::Write,
     {
         if first {
-            try!(writer.write_all(b"\n"));
+            tri!(writer.write_all(b"\n"));
         } else {
-            try!(writer.write_all(b",\n"));
+            tri!(writer.write_all(b",\n"));
         }
         indent(writer, self.current_indent, self.indent)
     }
@@ -2071,9 +2083,9 @@
     W: io::Write,
     F: Formatter,
 {
-    try!(formatter.begin_string(writer));
-    try!(format_escaped_str_contents(writer, formatter, value));
-    try!(formatter.end_string(writer));
+    tri!(formatter.begin_string(writer));
+    tri!(format_escaped_str_contents(writer, formatter, value));
+    tri!(formatter.end_string(writer));
     Ok(())
 }
 
@@ -2097,17 +2109,17 @@
         }
 
         if start < i {
-            try!(formatter.write_string_fragment(writer, &value[start..i]));
+            tri!(formatter.write_string_fragment(writer, &value[start..i]));
         }
 
         let char_escape = CharEscape::from_escape_table(escape, byte);
-        try!(formatter.write_char_escape(writer, char_escape));
+        tri!(formatter.write_char_escape(writer, char_escape));
 
         start = i + 1;
     }
 
     if start != bytes.len() {
-        try!(formatter.write_string_fragment(writer, &value[start..]));
+        tri!(formatter.write_string_fragment(writer, &value[start..]));
     }
 
     Ok(())
@@ -2158,7 +2170,7 @@
     T: Serialize,
 {
     let mut ser = Serializer::new(writer);
-    try!(value.serialize(&mut ser));
+    tri!(value.serialize(&mut ser));
     Ok(())
 }
 
@@ -2176,7 +2188,7 @@
     T: Serialize,
 {
     let mut ser = Serializer::pretty(writer);
-    try!(value.serialize(&mut ser));
+    tri!(value.serialize(&mut ser));
     Ok(())
 }
 
@@ -2192,7 +2204,7 @@
     T: Serialize,
 {
     let mut writer = Vec::with_capacity(128);
-    try!(to_writer(&mut writer, value));
+    tri!(to_writer(&mut writer, value));
     Ok(writer)
 }
 
@@ -2208,7 +2220,7 @@
     T: Serialize,
 {
     let mut writer = Vec::with_capacity(128);
-    try!(to_writer_pretty(&mut writer, value));
+    tri!(to_writer_pretty(&mut writer, value));
     Ok(writer)
 }
 
@@ -2223,7 +2235,7 @@
 where
     T: Serialize,
 {
-    let vec = try!(to_vec(value));
+    let vec = tri!(to_vec(value));
     let string = unsafe {
         // We do not emit invalid UTF-8.
         String::from_utf8_unchecked(vec)
@@ -2242,7 +2254,7 @@
 where
     T: Serialize,
 {
-    let vec = try!(to_vec_pretty(value));
+    let vec = tri!(to_vec_pretty(value));
     let string = unsafe {
         // We do not emit invalid UTF-8.
         String::from_utf8_unchecked(vec)
@@ -2255,7 +2267,7 @@
     W: io::Write,
 {
     for _ in 0..n {
-        try!(wr.write_all(s));
+        tri!(wr.write_all(s));
     }
 
     Ok(())
diff --git a/src/value/de.rs b/src/value/de.rs
index c1f0810..8e41dda 100644
--- a/src/value/de.rs
+++ b/src/value/de.rs
@@ -1,24 +1,17 @@
-use std::borrow::Cow;
-use std::fmt;
-use std::slice;
-use std::str;
-use std::vec;
-
-use serde;
+use crate::error::Error;
+use crate::lib::str::FromStr;
+use crate::lib::*;
+use crate::map::Map;
+use crate::number::Number;
+use crate::value::Value;
 use serde::de::{
-    Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess, SeqAccess,
-    Unexpected, VariantAccess, Visitor,
+    self, Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess,
+    SeqAccess, Unexpected, VariantAccess, Visitor,
 };
-
-use error::Error;
-use map::Map;
-use number::Number;
-use value::Value;
-
-use serde::de;
+use serde::{forward_to_deserialize_any, serde_if_integer128};
 
 #[cfg(feature = "arbitrary_precision")]
-use number::NumberFromString;
+use crate::number::NumberFromString;
 
 impl<'de> Deserialize<'de> for Value {
     #[inline]
@@ -93,7 +86,7 @@
             {
                 let mut vec = Vec::new();
 
-                while let Some(elem) = try!(visitor.next_element()) {
+                while let Some(elem) = tri!(visitor.next_element()) {
                     vec.push(elem);
                 }
 
@@ -112,14 +105,14 @@
                     }
                     #[cfg(feature = "raw_value")]
                     Some(KeyClass::RawValue) => {
-                        let value = visitor.next_value_seed(::raw::BoxedFromString)?;
-                        ::from_str(value.get()).map_err(de::Error::custom)
+                        let value = visitor.next_value_seed(crate::raw::BoxedFromString)?;
+                        crate::from_str(value.get()).map_err(de::Error::custom)
                     }
                     Some(KeyClass::Map(first_key)) => {
                         let mut values = Map::new();
 
-                        values.insert(first_key, try!(visitor.next_value()));
-                        while let Some((key, value)) = try!(visitor.next_entry()) {
+                        values.insert(first_key, tri!(visitor.next_value()));
+                        while let Some((key, value)) = tri!(visitor.next_entry()) {
                             values.insert(key, value);
                         }
 
@@ -134,7 +127,7 @@
     }
 }
 
-impl str::FromStr for Value {
+impl FromStr for Value {
     type Err = Error;
     fn from_str(s: &str) -> Result<Value, Error> {
         super::super::de::from_str(s)
@@ -173,7 +166,7 @@
 {
     let len = array.len();
     let mut deserializer = SeqDeserializer::new(array);
-    let seq = try!(visitor.visit_seq(&mut deserializer));
+    let seq = tri!(visitor.visit_seq(&mut deserializer));
     let remaining = deserializer.iter.len();
     if remaining == 0 {
         Ok(seq)
@@ -191,7 +184,7 @@
 {
     let len = object.len();
     let mut deserializer = MapDeserializer::new(object);
-    let map = try!(visitor.visit_map(&mut deserializer));
+    let map = tri!(visitor.visit_map(&mut deserializer));
     let remaining = deserializer.iter.len();
     if remaining == 0 {
         Ok(map)
@@ -305,8 +298,8 @@
     {
         #[cfg(feature = "raw_value")]
         {
-            if name == ::raw::TOKEN {
-                return visitor.visit_map(::raw::OwnedRawDeserializer {
+            if name == crate::raw::TOKEN {
+                return visitor.visit_map(crate::raw::OwnedRawDeserializer {
                     raw_value: Some(self.to_string()),
                 });
             }
@@ -581,7 +574,7 @@
         if len == 0 {
             visitor.visit_unit()
         } else {
-            let ret = try!(visitor.visit_seq(&mut self));
+            let ret = tri!(visitor.visit_seq(&mut self));
             let remaining = self.iter.len();
             if remaining == 0 {
                 Ok(ret)
@@ -723,7 +716,7 @@
 {
     let len = array.len();
     let mut deserializer = SeqRefDeserializer::new(array);
-    let seq = try!(visitor.visit_seq(&mut deserializer));
+    let seq = tri!(visitor.visit_seq(&mut deserializer));
     let remaining = deserializer.iter.len();
     if remaining == 0 {
         Ok(seq)
@@ -741,7 +734,7 @@
 {
     let len = object.len();
     let mut deserializer = MapRefDeserializer::new(object);
-    let map = try!(visitor.visit_map(&mut deserializer));
+    let map = tri!(visitor.visit_map(&mut deserializer));
     let remaining = deserializer.iter.len();
     if remaining == 0 {
         Ok(map)
@@ -852,8 +845,8 @@
     {
         #[cfg(feature = "raw_value")]
         {
-            if name == ::raw::TOKEN {
-                return visitor.visit_map(::raw::OwnedRawDeserializer {
+            if name == crate::raw::TOKEN {
+                return visitor.visit_map(crate::raw::OwnedRawDeserializer {
                     raw_value: Some(self.to_string()),
                 });
             }
@@ -1117,7 +1110,7 @@
         if len == 0 {
             visitor.visit_unit()
         } else {
-            let ret = try!(visitor.visit_seq(&mut self));
+            let ret = tri!(visitor.visit_seq(&mut self));
             let remaining = self.iter.len();
             if remaining == 0 {
                 Ok(ret)
@@ -1345,9 +1338,9 @@
     {
         match s {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::TOKEN => Ok(KeyClass::Number),
+            crate::number::TOKEN => Ok(KeyClass::Number),
             #[cfg(feature = "raw_value")]
-            ::raw::TOKEN => Ok(KeyClass::RawValue),
+            crate::raw::TOKEN => Ok(KeyClass::RawValue),
             _ => Ok(KeyClass::Map(s.to_owned())),
         }
     }
@@ -1358,9 +1351,9 @@
     {
         match s.as_str() {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::TOKEN => Ok(KeyClass::Number),
+            crate::number::TOKEN => Ok(KeyClass::Number),
             #[cfg(feature = "raw_value")]
-            ::raw::TOKEN => Ok(KeyClass::RawValue),
+            crate::raw::TOKEN => Ok(KeyClass::RawValue),
             _ => Ok(KeyClass::Map(s)),
         }
     }
@@ -1368,7 +1361,7 @@
 
 impl Value {
     #[cold]
-    fn invalid_type<E>(&self, exp: &Expected) -> E
+    fn invalid_type<E>(&self, exp: &dyn Expected) -> E
     where
         E: serde::de::Error,
     {
diff --git a/src/value/from.rs b/src/value/from.rs
index 4b93f09..2e2ac47 100644
--- a/src/value/from.rs
+++ b/src/value/from.rs
@@ -1,8 +1,11 @@
-use std::borrow::Cow;
-
 use super::Value;
-use map::Map;
-use number::Number;
+use crate::lib::iter::FromIterator;
+use crate::lib::*;
+use crate::map::Map;
+use crate::number::Number;
+
+#[cfg(feature = "arbitrary_precision")]
+use serde::serde_if_integer128;
 
 macro_rules! from_integer {
     ($($ty:ident)*) => {
@@ -33,7 +36,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let f: f32 = 13.37;
@@ -49,7 +52,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let f: f64 = 13.37;
@@ -65,7 +68,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let b = false;
@@ -81,7 +84,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let s: String = "lorem".to_string();
@@ -97,7 +100,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let s: &str = "lorem";
@@ -113,7 +116,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     /// use std::borrow::Cow;
     ///
@@ -121,7 +124,7 @@
     /// let x: Value = s.into();
     /// ```
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     /// use std::borrow::Cow;
     ///
@@ -138,7 +141,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::{Map, Value};
     ///
     /// let mut m = Map::new();
@@ -155,7 +158,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let v = vec!["lorem", "ipsum", "dolor"];
@@ -171,7 +174,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
@@ -182,26 +185,26 @@
     }
 }
 
-impl<T: Into<Value>> ::std::iter::FromIterator<T> for Value {
+impl<T: Into<Value>> FromIterator<T> for Value {
     /// Convert an iteratable type to a `Value`
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let v = std::iter::repeat(42).take(5);
     /// let x: Value = v.collect();
     /// ```
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
     /// let x: Value = v.into_iter().collect();
     /// ```
     ///
-    /// ```edition2018
+    /// ```
     /// use std::iter::FromIterator;
     /// use serde_jsonrc::Value;
     ///
@@ -217,7 +220,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// let u = ();
diff --git a/src/value/index.rs b/src/value/index.rs
index dba13bd..15e0114 100644
--- a/src/value/index.rs
+++ b/src/value/index.rs
@@ -1,8 +1,6 @@
-use std::fmt;
-use std::ops;
-
 use super::Value;
-use map::Map;
+use crate::lib::*;
+use crate::map::Map;
 
 /// A type that can be used to index into a `serde_jsonrc::Value`.
 ///
@@ -20,7 +18,7 @@
 ///
 /// # Examples
 ///
-/// ```edition2018
+/// ```
 /// # use serde_jsonrc::json;
 /// #
 /// let data = json!({ "inner": [1, 2, 3] });
@@ -135,7 +133,7 @@
     pub trait Sealed {}
     impl Sealed for usize {}
     impl Sealed for str {}
-    impl Sealed for String {}
+    impl Sealed for super::String {}
     impl<'a, T: ?Sized> Sealed for &'a T where T: Sealed {}
 }
 
@@ -193,7 +191,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let data = json!({
@@ -232,7 +230,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut data = json!({ "x": 0 });
diff --git a/src/value/mod.rs b/src/value/mod.rs
index b61d358..5ff3729 100644
--- a/src/value/mod.rs
+++ b/src/value/mod.rs
@@ -5,7 +5,7 @@
 //! Serde jsonrc provides a [`json!` macro][macro] to build `serde_jsonrc::Value`
 //! objects with very natural JSON syntax.
 //!
-//! ```edition2018
+//! ```
 //! use serde_jsonrc::json;
 //!
 //! fn main() {
@@ -34,7 +34,7 @@
 //! will check at compile time that the value you are interpolating is able to
 //! be represented as JSON.
 //!
-//! ```edition2018
+//! ```
 //! # use serde_jsonrc::json;
 //! #
 //! # fn random_phone() -> u16 { 0 }
@@ -58,7 +58,7 @@
 //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
 //! a TCP stream.
 //!
-//! ```edition2018
+//! ```
 //! use serde_jsonrc::{json, Value, Error};
 //!
 //! fn untyped_example() -> Result<(), Error> {
@@ -90,24 +90,19 @@
 //! [from_slice]: https://docs.serde.rs/serde_jsonrc/de/fn.from_slice.html
 //! [from_reader]: https://docs.serde.rs/serde_jsonrc/de/fn.from_reader.html
 
-use std::fmt::{self, Debug};
-use std::io;
-use std::mem;
-use std::str;
-
+use self::ser::Serializer;
+use crate::error::Error;
+use crate::io;
+use crate::lib::*;
 use serde::de::DeserializeOwned;
 use serde::ser::Serialize;
 
-use error::Error;
-pub use map::Map;
-pub use number::Number;
+pub use self::index::Index;
+pub use crate::map::Map;
+pub use crate::number::Number;
 
 #[cfg(feature = "raw_value")]
-pub use raw::RawValue;
-
-pub use self::index::Index;
-
-use self::ser::Serializer;
+pub use crate::raw::RawValue;
 
 /// Represents any valid JSON value.
 ///
@@ -116,7 +111,7 @@
 pub enum Value {
     /// Represents a JSON null value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!(null);
@@ -125,7 +120,7 @@
 
     /// Represents a JSON boolean.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!(true);
@@ -134,7 +129,7 @@
 
     /// Represents a JSON number, whether integer or floating point.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!(12.5);
@@ -143,7 +138,7 @@
 
     /// Represents a JSON string.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!("a string");
@@ -152,7 +147,7 @@
 
     /// Represents a JSON array.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!(["an", "array"]);
@@ -167,7 +162,7 @@
     /// allows JSON data to be deserialized into a Value and serialized to a
     /// string while retaining the order of map keys in the input.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "an": "object" });
@@ -199,8 +194,8 @@
             // maps it to fmt::Error
             io::Error::new(io::ErrorKind::Other, "fmt error")
         }
-        let s = try!(str::from_utf8(buf).map_err(io_error));
-        try!(self.inner.write_str(s).map_err(io_error));
+        let s = tri!(str::from_utf8(buf).map_err(io_error));
+        tri!(self.inner.write_str(s).map_err(io_error));
         Ok(buf.len())
     }
 
@@ -212,7 +207,7 @@
 impl fmt::Display for Value {
     /// Display a JSON value as a string.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let json = json!({ "city": "London", "street": "10 Downing Street" });
@@ -264,7 +259,7 @@
     /// number. Also returns `None` if the given key does not exist in the map
     /// or the given index is not within the bounds of the array.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let object = json!({ "A": 65, "B": 66, "C": 67 });
@@ -280,7 +275,7 @@
     /// way. This returns `Value::Null` in cases where `get` would have returned
     /// `None`.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let object = json!({
@@ -306,7 +301,7 @@
     /// number. Also returns `None` if the given key does not exist in the map
     /// or the given index is not within the bounds of the array.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut object = json!({ "A": 65, "B": 66, "C": 67 });
@@ -325,7 +320,7 @@
     /// `as_object_mut` are guaranteed to return the map representation of the
     /// object.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] });
@@ -343,7 +338,7 @@
     /// If the `Value` is an Object, returns the associated Map. Returns None
     /// otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] });
@@ -364,7 +359,7 @@
     /// If the `Value` is an Object, returns the associated mutable Map.
     /// Returns None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut v = json!({ "a": { "nested": true } });
@@ -385,7 +380,7 @@
     /// `as_array_mut` are guaranteed to return the vector representing the
     /// array.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } });
@@ -402,7 +397,7 @@
     /// If the `Value` is an Array, returns the associated vector. Returns None
     /// otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } });
@@ -423,7 +418,7 @@
     /// If the `Value` is an Array, returns the associated mutable vector.
     /// Returns None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut v = json!({ "a": ["an", "array"] });
@@ -443,7 +438,7 @@
     /// For any Value on which `is_string` returns true, `as_str` is guaranteed
     /// to return the string slice.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": "some string", "b": false });
@@ -460,7 +455,7 @@
     /// If the `Value` is a String, returns the associated str. Returns None
     /// otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": "some string", "b": false });
@@ -489,7 +484,7 @@
 
     /// Returns true if the `Value` is a Number. Returns false otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 1, "b": "2" });
@@ -512,7 +507,7 @@
     /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
     /// return the integer value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let big = i64::max_value() as u64 + 10;
@@ -538,7 +533,7 @@
     /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
     /// return the integer value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
@@ -566,7 +561,7 @@
     /// Currently this function returns true if and only if both `is_i64` and
     /// `is_u64` return false but this is not a guarantee in the future.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
@@ -587,7 +582,7 @@
     /// If the `Value` is an integer, represent it as i64 if possible. Returns
     /// None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let big = i64::max_value() as u64 + 10;
@@ -607,7 +602,7 @@
     /// If the `Value` is an integer, represent it as u64 if possible. Returns
     /// None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
@@ -626,7 +621,7 @@
     /// If the `Value` is a number, represent it as f64 if possible. Returns
     /// None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
@@ -647,7 +642,7 @@
     /// For any Value on which `is_boolean` returns true, `as_bool` is
     /// guaranteed to return the boolean value.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": false, "b": "false" });
@@ -664,7 +659,7 @@
     /// If the `Value` is a Boolean, returns the associated bool. Returns None
     /// otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": false, "b": "false" });
@@ -686,7 +681,7 @@
     /// For any Value on which `is_null` returns true, `as_null` is guaranteed
     /// to return `Some(())`.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": null, "b": false });
@@ -702,7 +697,7 @@
 
     /// If the `Value` is a Null, returns (). Returns None otherwise.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let v = json!({ "a": null, "b": false });
@@ -733,7 +728,7 @@
     ///
     /// # Examples
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let data = json!({
@@ -745,7 +740,7 @@
     /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz"));
     /// assert_eq!(data.pointer("/a/b/c"), None);
     /// ```
-    pub fn pointer<'a>(&'a self, pointer: &str) -> Option<&'a Value> {
+    pub fn pointer(&self, pointer: &str) -> Option<&Value> {
         if pointer == "" {
             return Some(self);
         }
@@ -788,7 +783,7 @@
     ///
     /// # Example of Use
     ///
-    /// ```edition2018
+    /// ```
     /// use serde_jsonrc::Value;
     ///
     /// fn main() {
@@ -801,6 +796,8 @@
     ///     *value.pointer_mut("/x").unwrap() = 1.5.into();
     ///     // Check that new value was written
     ///     assert_eq!(value.pointer("/x"), Some(&1.5.into()));
+    ///     // Or change the value only if it exists
+    ///     value.pointer_mut("/x").map(|v| *v = 1.5.into());
     ///
     ///     // "Steal" ownership of a value. Can replace with any valid Value.
     ///     let old_x = value.pointer_mut("/x").map(Value::take).unwrap();
@@ -808,7 +805,7 @@
     ///     assert_eq!(value.pointer("/x").unwrap(), &Value::Null);
     /// }
     /// ```
-    pub fn pointer_mut<'a>(&'a mut self, pointer: &str) -> Option<&'a mut Value> {
+    pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> {
         if pointer == "" {
             return Some(self);
         }
@@ -843,7 +840,7 @@
 
     /// Takes the value out of the `Value`, leaving a `Null` in its place.
     ///
-    /// ```edition2018
+    /// ```
     /// # use serde_jsonrc::json;
     /// #
     /// let mut v = json!({ "x": "y" });
@@ -861,7 +858,7 @@
 ///
 /// # Examples
 ///
-/// ```edition2018
+/// ```
 /// # use serde::Deserialize;
 /// use serde_jsonrc::Value;
 ///
@@ -901,7 +898,7 @@
 ///
 /// # Example
 ///
-/// ```edition2018
+/// ```
 /// use serde::Serialize;
 /// use serde_jsonrc::json;
 ///
@@ -939,7 +936,7 @@
 /// This conversion can fail if `T`'s implementation of `Serialize` decides to
 /// fail, or if `T` contains a map with non-string keys.
 ///
-/// ```edition2018
+/// ```
 /// use std::collections::BTreeMap;
 ///
 /// fn main() {
@@ -963,7 +960,7 @@
 ///
 /// # Example
 ///
-/// ```edition2018
+/// ```
 /// use serde::Deserialize;
 /// use serde_jsonrc::json;
 ///
diff --git a/src/value/partial_eq.rs b/src/value/partial_eq.rs
index cfcf957..354ea5a 100644
--- a/src/value/partial_eq.rs
+++ b/src/value/partial_eq.rs
@@ -1,4 +1,5 @@
 use super::Value;
+use crate::lib::*;
 
 fn eq_i64(value: &Value, other: i64) -> bool {
     value.as_i64().map_or(false, |i| i == other)
diff --git a/src/value/ser.rs b/src/value/ser.rs
index b0e09be..6b76b16 100644
--- a/src/value/ser.rs
+++ b/src/value/ser.rs
@@ -1,10 +1,12 @@
-use serde::ser::Impossible;
-use serde::{self, Serialize};
+use crate::error::{Error, ErrorCode};
+use crate::lib::*;
+use crate::map::Map;
+use crate::number::Number;
+use crate::value::{to_value, Value};
+use serde::ser::{Impossible, Serialize};
 
-use error::{Error, ErrorCode};
-use map::Map;
-use number::Number;
-use value::{to_value, Value};
+#[cfg(feature = "arbitrary_precision")]
+use serde::serde_if_integer128;
 
 impl Serialize for Value {
     #[inline]
@@ -20,10 +22,10 @@
             Value::Array(ref v) => v.serialize(serializer),
             Value::Object(ref m) => {
                 use serde::ser::SerializeMap;
-                let mut map = try!(serializer.serialize_map(Some(m.len())));
+                let mut map = tri!(serializer.serialize_map(Some(m.len())));
                 for (k, v) in m {
-                    try!(map.serialize_key(k));
-                    try!(map.serialize_value(v));
+                    tri!(map.serialize_key(k));
+                    tri!(map.serialize_value(v));
                 }
                 map.end()
             }
@@ -173,7 +175,7 @@
         T: Serialize,
     {
         let mut values = Map::new();
-        values.insert(String::from(variant), try!(to_value(&value)));
+        values.insert(String::from(variant), tri!(to_value(&value)));
         Ok(Value::Object(values))
     }
 
@@ -235,9 +237,9 @@
     ) -> Result<Self::SerializeStruct, Error> {
         match name {
             #[cfg(feature = "arbitrary_precision")]
-            ::number::TOKEN => Ok(SerializeMap::Number { out_value: None }),
+            crate::number::TOKEN => Ok(SerializeMap::Number { out_value: None }),
             #[cfg(feature = "raw_value")]
-            ::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }),
+            crate::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }),
             _ => self.serialize_map(Some(len)),
         }
     }
@@ -289,7 +291,7 @@
     where
         T: Serialize,
     {
-        self.vec.push(try!(to_value(&value)));
+        self.vec.push(tri!(to_value(&value)));
         Ok(())
     }
 
@@ -338,7 +340,7 @@
     where
         T: Serialize,
     {
-        self.vec.push(try!(to_value(&value)));
+        self.vec.push(tri!(to_value(&value)));
         Ok(())
     }
 
@@ -363,7 +365,7 @@
             SerializeMap::Map {
                 ref mut next_key, ..
             } => {
-                *next_key = Some(try!(key.serialize(MapKeySerializer)));
+                *next_key = Some(tri!(key.serialize(MapKeySerializer)));
                 Ok(())
             }
             #[cfg(feature = "arbitrary_precision")]
@@ -386,7 +388,7 @@
                 // Panic because this indicates a bug in the program rather than an
                 // expected failure.
                 let key = key.expect("serialize_value called before serialize_key");
-                map.insert(key, try!(to_value(&value)));
+                map.insert(key, tri!(to_value(&value)));
                 Ok(())
             }
             #[cfg(feature = "arbitrary_precision")]
@@ -600,12 +602,12 @@
     {
         match *self {
             SerializeMap::Map { .. } => {
-                try!(serde::ser::SerializeMap::serialize_key(self, key));
+                tri!(serde::ser::SerializeMap::serialize_key(self, key));
                 serde::ser::SerializeMap::serialize_value(self, value)
             }
             #[cfg(feature = "arbitrary_precision")]
             SerializeMap::Number { ref mut out_value } => {
-                if key == ::number::TOKEN {
+                if key == crate::number::TOKEN {
                     *out_value = Some(value.serialize(NumberValueEmitter)?);
                     Ok(())
                 } else {
@@ -614,7 +616,7 @@
             }
             #[cfg(feature = "raw_value")]
             SerializeMap::RawValue { ref mut out_value } => {
-                if key == ::raw::TOKEN {
+                if key == crate::raw::TOKEN {
                     *out_value = Some(value.serialize(RawValueEmitter)?);
                     Ok(())
                 } else {
@@ -647,7 +649,7 @@
     where
         T: Serialize,
     {
-        self.map.insert(String::from(key), try!(to_value(&value)));
+        self.map.insert(String::from(key), tri!(to_value(&value)));
         Ok(())
     }
 
@@ -730,7 +732,7 @@
     }
 
     fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
-        let n = try!(value.to_owned().parse());
+        let n = tri!(value.to_owned().parse());
         Ok(Value::Number(n))
     }
 
@@ -909,7 +911,7 @@
     }
 
     fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
-        ::from_str(value)
+        crate::from_str(value)
     }
 
     fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
diff --git a/tests/crate/Cargo.toml b/tests/crate/Cargo.toml
index d09de09..996ad03 100644
--- a/tests/crate/Cargo.toml
+++ b/tests/crate/Cargo.toml
@@ -1,16 +1,20 @@
 [package]
 name = "serde_json_test"
 version = "0.0.0"
+edition = "2018"
 publish = false
 
 [lib]
 path = "test.rs"
 
 [dependencies]
-serde_jsonrc = { path = "../.." }
+serde_jsonrc = { path = "../..", default-features = false }
 
 [features]
-arbitrary_precision = ["serde_jsonrc/arbitrary_precision"]
+default = ["std"]
+std = ["serde_jsonrc/std"]
+alloc = ["serde_jsonrc/alloc"]
 preserve_order = ["serde_jsonrc/preserve_order"]
+arbitrary_precision = ["serde_jsonrc/arbitrary_precision"]
 raw_value = ["serde_jsonrc/raw_value"]
 unbounded_depth = ["serde_jsonrc/unbounded_depth"]
diff --git a/tests/crate/test.rs b/tests/crate/test.rs
index d1ee3b8..373af7a 100644
--- a/tests/crate/test.rs
+++ b/tests/crate/test.rs
@@ -1,2 +1 @@
-extern crate serde_jsonrc;
 pub use serde_jsonrc::*;
diff --git a/tests/debug.rs b/tests/debug.rs
index 692c0fa..c55810c 100644
--- a/tests/debug.rs
+++ b/tests/debug.rs
@@ -1,7 +1,4 @@
-#[macro_use]
-extern crate serde_jsonrc;
-
-use serde_jsonrc::{Number, Value};
+use serde_jsonrc::{json, Number, Value};
 
 #[test]
 fn number() {
diff --git a/tests/map.rs b/tests/map.rs
new file mode 100644
index 0000000..d69c183
--- /dev/null
+++ b/tests/map.rs
@@ -0,0 +1,36 @@
+use serde_jsonrc::{from_str, Map, Value};
+
+#[test]
+fn test_preserve_order() {
+    // Sorted order
+    #[cfg(not(feature = "preserve_order"))]
+    const EXPECTED: &[&str] = &["a", "b", "c"];
+
+    // Insertion order
+    #[cfg(feature = "preserve_order")]
+    const EXPECTED: &[&str] = &["b", "a", "c"];
+
+    let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
+    let keys: Vec<_> = v.as_object().unwrap().keys().collect();
+    assert_eq!(keys, EXPECTED);
+}
+
+#[test]
+fn test_append() {
+    // Sorted order
+    #[cfg(not(feature = "preserve_order"))]
+    const EXPECTED: &[&str] = &["a", "b", "c"];
+
+    // Insertion order
+    #[cfg(feature = "preserve_order")]
+    const EXPECTED: &[&str] = &["b", "a", "c"];
+
+    let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
+    let val = v.as_object_mut().unwrap();
+    let mut m = Map::new();
+    m.append(val);
+    let keys: Vec<_> = m.keys().collect();
+
+    assert_eq!(keys, EXPECTED);
+    assert!(val.is_empty());
+}
diff --git a/tests/preserve_order.rs b/tests/preserve_order.rs
deleted file mode 100644
index c4d39c8..0000000
--- a/tests/preserve_order.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-extern crate serde_jsonrc;
-
-use serde_jsonrc::{from_str, Value};
-
-#[test]
-fn test_map_order() {
-    // Sorted order
-    #[cfg(not(feature = "preserve_order"))]
-    const EXPECTED: &[&str] = &["a", "b", "c"];
-
-    // Insertion order
-    #[cfg(feature = "preserve_order")]
-    const EXPECTED: &[&str] = &["b", "a", "c"];
-
-    let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
-    let keys: Vec<_> = v.as_object().unwrap().keys().collect();
-    assert_eq!(keys, EXPECTED);
-}
diff --git a/tests/regression.rs b/tests/regression.rs
index eff29ff..34c67d2 100644
--- a/tests/regression.rs
+++ b/tests/regression.rs
@@ -1,6 +1,2 @@
-extern crate automod;
-extern crate serde;
-extern crate serde_derive;
-
 #[path = "regression/mod.rs"]
 mod regression;
diff --git a/tests/stream.rs b/tests/stream.rs
index 9638e48..7b614b5 100644
--- a/tests/stream.rs
+++ b/tests/stream.rs
@@ -1,14 +1,9 @@
 #![cfg(not(feature = "preserve_order"))]
 
-extern crate serde;
-
-#[macro_use]
-extern crate serde_jsonrc;
-
-use serde_jsonrc::{Deserializer, Value};
+use serde_jsonrc::{json, Deserializer, Value};
 
 // Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740
-#[cfg_attr(rustfmt, rustfmt_skip)]
+#[rustfmt::skip]
 macro_rules! test_stream {
     ($data:expr, $ty:ty, |$stream:ident| $test:block) => {
         {
diff --git a/tests/test.rs b/tests/test.rs
index c9f9070..0009212 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,20 +1,20 @@
 #![cfg(not(feature = "preserve_order"))]
-#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, unreadable_literal))]
+#![allow(clippy::float_cmp, clippy::unreadable_literal)]
 #![cfg_attr(feature = "trace-macros", feature(trace_macros))]
 #[cfg(feature = "trace-macros")]
 trace_macros!(true);
 
 #[macro_use]
-extern crate serde_derive;
-
-extern crate serde;
-extern crate serde_bytes;
-#[macro_use]
-extern crate serde_jsonrc;
-
-#[macro_use]
 mod macros;
 
+use serde::de::{self, IgnoredAny, IntoDeserializer};
+use serde::ser::{self, Serializer};
+use serde::{Deserialize, Serialize};
+use serde_bytes::{ByteBuf, Bytes};
+use serde_jsonrc::{
+    from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value,
+    to_vec, to_writer, Deserializer, Number, Value,
+};
 use std::collections::BTreeMap;
 use std::fmt::{self, Debug};
 use std::io;
@@ -26,16 +26,6 @@
 use std::{i16, i32, i64, i8};
 use std::{u16, u32, u64, u8};
 
-use serde::de::{self, Deserialize, IgnoredAny, IntoDeserializer};
-use serde::ser::{self, Serialize, Serializer};
-
-use serde_bytes::{ByteBuf, Bytes};
-
-use serde_jsonrc::{
-    from_reader, from_slice, from_str, from_value, to_string, to_string_pretty, to_value, to_vec,
-    to_writer, Deserializer, Number, Value,
-};
-
 macro_rules! treemap {
     () => {
         BTreeMap::new()
@@ -2000,7 +1990,7 @@
 
 #[test]
 // Clippy false positive: https://github.com/Manishearth/rust-clippy/issues/292
-#[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
+#[allow(clippy::needless_lifetimes)]
 fn test_into_io_error() {
     fn io_error<'de, T: Deserialize<'de> + Debug>(j: &'static str) -> io::Error {
         from_str::<T>(j).unwrap_err().into()