// Rust JSON serialization library.
// Copyright (c) 2011 Google Inc.

#![forbid(non_camel_case_types)]
#![allow(missing_docs)]

//! JSON parsing and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in Javascript.
//! Like XML, it allows to encode structured data in a text format that can be easily read by humans
//! Its simple syntax and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `Json` enum for more details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `Number`: equivalent to rust's `f64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//!   same array
//! * `Object`: equivalent to rust's `BTreeMap<String, json::Json>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format.
//! Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).
//! A simple JSON document encoding a person, their age, address and phone numbers could look like
//!
//! ```json
//! {
//!     "FirstName": "John",
//!     "LastName": "Doe",
//!     "Age": 43,
//!     "Address": {
//!         "Street": "Downing Street 10",
//!         "City": "London",
//!         "Country": "Great Britain"
//!     },
//!     "PhoneNumbers": [
//!         "+44 1234567",
//!         "+44 2345678"
//!     ]
//! }
//! ```
//!
//! # Rust Type-based Encoding and Decoding
//!
//! Rust provides a mechanism for low boilerplate encoding & decoding of values to and from JSON via
//! the serialization API.
//! To be able to encode a piece of data, it must implement the `serialize::RustcEncodable` trait.
//! To be able to decode a piece of data, it must implement the `serialize::RustcDecodable` trait.
//! The Rust compiler provides an annotation to automatically generate the code for these traits:
//! `#[derive(RustcDecodable, RustcEncodable)]`
//!
//! The JSON API provides an enum `json::Json` and a trait `ToJson` to encode objects.
//! The `ToJson` trait provides a `to_json` method to convert an object into a `json::Json` value.
//! A `json::Json` value can be encoded as a string or buffer using the functions described above.
//! You can also use the `json::Encoder` object, which implements the `Encoder` trait.
//!
//! When using `ToJson` the `RustcEncodable` trait implementation is not mandatory.
//!
//! # Examples of use
//!
//! ## Using Autoserialization
//!
//! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
//! serialization API, using the derived serialization code.
//!
//! ```rust
//! # #![feature(rustc_private)]
//! extern crate serialize as rustc_serialize; // for the deriving below
//! use rustc_serialize::json;
//!
//! // Automatically generate `Decodable` and `Encodable` trait implementations
//! #[derive(RustcDecodable, RustcEncodable)]
//! pub struct TestStruct  {
//!     data_int: u8,
//!     data_str: String,
//!     data_vector: Vec<u8>,
//! }
//!
//! fn main() {
//!     let object = TestStruct {
//!         data_int: 1,
//!         data_str: "homura".to_string(),
//!         data_vector: vec![2,3,4,5],
//!     };
//!
//!     // Serialize using `json::encode`
//!     let encoded = json::encode(&object).unwrap();
//!
//!     // Deserialize using `json::decode`
//!     let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
//! }
//! ```
//!
//! ## Using the `ToJson` trait
//!
//! The examples above use the `ToJson` trait to generate the JSON string, which is required
//! for custom mappings.
//!
//! ### Simple example of `ToJson` usage
//!
//! ```rust
//! # #![feature(rustc_private)]
//! extern crate serialize as rustc_serialize;
//! use rustc_serialize::json::{self, ToJson, Json};
//!
//! // A custom data structure
//! struct ComplexNum {
//!     a: f64,
//!     b: f64,
//! }
//!
//! // JSON value representation
//! impl ToJson for ComplexNum {
//!     fn to_json(&self) -> Json {
//!         Json::String(format!("{}+{}i", self.a, self.b))
//!     }
//! }
//!
//! // Only generate `RustcEncodable` trait implementation
//! #[derive(RustcEncodable)]
//! pub struct ComplexNumRecord {
//!     uid: u8,
//!     dsc: String,
//!     val: Json,
//! }
//!
//! fn main() {
//!     let num = ComplexNum { a: 0.0001, b: 12.539 };
//!     let data: String = json::encode(&ComplexNumRecord{
//!         uid: 1,
//!         dsc: "test".to_string(),
//!         val: num.to_json(),
//!     }).unwrap();
//!     println!("data: {}", data);
//!     // data: {"uid":1,"dsc":"test","val":"0.0001+12.539i"};
//! }
//! ```
//!
//! ### Verbose example of `ToJson` usage
//!
//! ```rust
//! # #![feature(rustc_private)]
//! extern crate serialize as rustc_serialize;
//! use std::collections::BTreeMap;
//! use rustc_serialize::json::{self, Json, ToJson};
//!
//! // Only generate `RustcDecodable` trait implementation
//! #[derive(RustcDecodable)]
//! pub struct TestStruct {
//!     data_int: u8,
//!     data_str: String,
//!     data_vector: Vec<u8>,
//! }
//!
//! // Specify encoding method manually
//! impl ToJson for TestStruct {
//!     fn to_json(&self) -> Json {
//!         let mut d = BTreeMap::new();
//!         // All standard types implement `to_json()`, so use it
//!         d.insert("data_int".to_string(), self.data_int.to_json());
//!         d.insert("data_str".to_string(), self.data_str.to_json());
//!         d.insert("data_vector".to_string(), self.data_vector.to_json());
//!         Json::Object(d)
//!     }
//! }
//!
//! fn main() {
//!     // Serialize using `ToJson`
//!     let input_data = TestStruct {
//!         data_int: 1,
//!         data_str: "madoka".to_string(),
//!         data_vector: vec![2,3,4,5],
//!     };
//!     let json_obj: Json = input_data.to_json();
//!     let json_str: String = json_obj.to_string();
//!
//!     // Deserialize like before
//!     let decoded: TestStruct = json::decode(&json_str).unwrap();
//! }
//! ```

use self::JsonEvent::*;
use self::ErrorCode::*;
use self::ParserError::*;
use self::DecoderError::*;
use self::ParserState::*;
use self::InternalStackElement::*;

use std::borrow::Cow;
use std::collections::{HashMap, BTreeMap};
use std::io::prelude::*;
use std::io;
use std::mem::swap;
use std::num::FpCategory as Fp;
use std::ops::Index;
use std::str::FromStr;
use std::string;
use std::{char, f64, fmt, str};

use crate::Encodable;

/// Represents a json value
#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub enum Json {
    I64(i64),
    U64(u64),
    F64(f64),
    String(string::String),
    Boolean(bool),
    Array(self::Array),
    Object(self::Object),
    Null,
}

pub type Array = Vec<Json>;
pub type Object = BTreeMap<string::String, Json>;

pub struct PrettyJson<'a> { inner: &'a Json }

pub struct AsJson<'a, T> { inner: &'a T }
pub struct AsPrettyJson<'a, T> { inner: &'a T, indent: Option<usize> }

/// The errors that can arise while parsing a JSON stream.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ErrorCode {
    InvalidSyntax,
    InvalidNumber,
    EOFWhileParsingObject,
    EOFWhileParsingArray,
    EOFWhileParsingValue,
    EOFWhileParsingString,
    KeyMustBeAString,
    ExpectedColon,
    TrailingCharacters,
    TrailingComma,
    InvalidEscape,
    InvalidUnicodeCodePoint,
    LoneLeadingSurrogateInHexEscape,
    UnexpectedEndOfHexEscape,
    UnrecognizedHex,
    NotFourDigit,
    NotUtf8,
}

#[derive(Clone, PartialEq, Debug)]
pub enum ParserError {
    /// msg, line, col
    SyntaxError(ErrorCode, usize, usize),
    IoError(io::ErrorKind, String),
}

// Builder and Parser have the same errors.
pub type BuilderError = ParserError;

#[derive(Clone, PartialEq, Debug)]
pub enum DecoderError {
    ParseError(ParserError),
    ExpectedError(string::String, string::String),
    MissingFieldError(string::String),
    UnknownVariantError(string::String),
    ApplicationError(string::String)
}

#[derive(Copy, Clone, Debug)]
pub enum EncoderError {
    FmtError(fmt::Error),
    BadHashmapKey,
}

/// Returns a readable error string for a given error code.
pub fn error_str(error: ErrorCode) -> &'static str {
    match error {
        InvalidSyntax => "invalid syntax",
        InvalidNumber => "invalid number",
        EOFWhileParsingObject => "EOF While parsing object",
        EOFWhileParsingArray => "EOF While parsing array",
        EOFWhileParsingValue => "EOF While parsing value",
        EOFWhileParsingString => "EOF While parsing string",
        KeyMustBeAString => "key must be a string",
        ExpectedColon => "expected `:`",
        TrailingCharacters => "trailing characters",
        TrailingComma => "trailing comma",
        InvalidEscape => "invalid escape",
        UnrecognizedHex => "invalid \\u{ esc}ape (unrecognized hex)",
        NotFourDigit => "invalid \\u{ esc}ape (not four digits)",
        NotUtf8 => "contents not utf-8",
        InvalidUnicodeCodePoint => "invalid Unicode code point",
        LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape",
        UnexpectedEndOfHexEscape => "unexpected end of hex escape",
    }
}

/// Shortcut function to decode a JSON `&str` into an object
pub fn decode<T: crate::Decodable>(s: &str) -> DecodeResult<T> {
    let json = match from_str(s) {
        Ok(x) => x,
        Err(e) => return Err(ParseError(e))
    };

    let mut decoder = Decoder::new(json);
    crate::Decodable::decode(&mut decoder)
}

/// Shortcut function to encode a `T` into a JSON `String`
pub fn encode<T: crate::Encodable>(object: &T) -> Result<string::String, EncoderError> {
    let mut s = String::new();
    {
        let mut encoder = Encoder::new(&mut s);
        object.encode(&mut encoder)?;
    }
    Ok(s)
}

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        error_str(*self).fmt(f)
    }
}

fn io_error_to_error(io: io::Error) -> ParserError {
    IoError(io.kind(), io.to_string())
}

impl fmt::Display for ParserError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // FIXME this should be a nicer error
        fmt::Debug::fmt(self, f)
    }
}

impl fmt::Display for DecoderError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // FIXME this should be a nicer error
        fmt::Debug::fmt(self, f)
    }
}

impl std::error::Error for DecoderError {
    fn description(&self) -> &str { "decoder error" }
}

impl fmt::Display for EncoderError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // FIXME this should be a nicer error
        fmt::Debug::fmt(self, f)
    }
}

impl std::error::Error for EncoderError {
    fn description(&self) -> &str { "encoder error" }
}

impl From<fmt::Error> for EncoderError {
    /// Converts a [`fmt::Error`] into `EncoderError`
    ///
    /// This conversion does not allocate memory.
    fn from(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
}

pub type EncodeResult = Result<(), EncoderError>;
pub type DecodeResult<T> = Result<T, DecoderError>;

fn escape_str(wr: &mut dyn fmt::Write, v: &str) -> EncodeResult {
    wr.write_str("\"")?;

    let mut start = 0;

    for (i, byte) in v.bytes().enumerate() {
        let escaped = match byte {
            b'"' => "\\\"",
            b'\\' => "\\\\",
            b'\x00' => "\\u0000",
            b'\x01' => "\\u0001",
            b'\x02' => "\\u0002",
            b'\x03' => "\\u0003",
            b'\x04' => "\\u0004",
            b'\x05' => "\\u0005",
            b'\x06' => "\\u0006",
            b'\x07' => "\\u0007",
            b'\x08' => "\\b",
            b'\t' => "\\t",
            b'\n' => "\\n",
            b'\x0b' => "\\u000b",
            b'\x0c' => "\\f",
            b'\r' => "\\r",
            b'\x0e' => "\\u000e",
            b'\x0f' => "\\u000f",
            b'\x10' => "\\u0010",
            b'\x11' => "\\u0011",
            b'\x12' => "\\u0012",
            b'\x13' => "\\u0013",
            b'\x14' => "\\u0014",
            b'\x15' => "\\u0015",
            b'\x16' => "\\u0016",
            b'\x17' => "\\u0017",
            b'\x18' => "\\u0018",
            b'\x19' => "\\u0019",
            b'\x1a' => "\\u001a",
            b'\x1b' => "\\u001b",
            b'\x1c' => "\\u001c",
            b'\x1d' => "\\u001d",
            b'\x1e' => "\\u001e",
            b'\x1f' => "\\u001f",
            b'\x7f' => "\\u007f",
            _ => { continue; }
        };

        if start < i {
            wr.write_str(&v[start..i])?;
        }

        wr.write_str(escaped)?;

        start = i + 1;
    }

    if start != v.len() {
        wr.write_str(&v[start..])?;
    }

    wr.write_str("\"")?;
    Ok(())
}

fn escape_char(writer: &mut dyn fmt::Write, v: char) -> EncodeResult {
    escape_str(writer, v.encode_utf8(&mut [0; 4]))
}

fn spaces(wr: &mut dyn fmt::Write, mut n: usize) -> EncodeResult {
    const BUF: &str = "                ";

    while n >= BUF.len() {
        wr.write_str(BUF)?;
        n -= BUF.len();
    }

    if n > 0 {
        wr.write_str(&BUF[..n])?;
    }
    Ok(())
}

fn fmt_number_or_null(v: f64) -> string::String {
    match v.classify() {
        Fp::Nan | Fp::Infinite => string::String::from("null"),
        _ if v.fract() != 0f64 => v.to_string(),
        _ => v.to_string() + ".0",
    }
}

/// A structure for implementing serialization to JSON.
pub struct Encoder<'a> {
    writer: &'a mut (dyn fmt::Write+'a),
    is_emitting_map_key: bool,
}

impl<'a> Encoder<'a> {
    /// Creates a new JSON encoder whose output will be written to the writer
    /// specified.
    pub fn new(writer: &'a mut dyn fmt::Write) -> Encoder<'a> {
        Encoder { writer, is_emitting_map_key: false, }
    }
}

macro_rules! emit_enquoted_if_mapkey {
    ($enc:ident,$e:expr) => ({
        if $enc.is_emitting_map_key {
            write!($enc.writer, "\"{}\"", $e)?;
        } else {
            write!($enc.writer, "{}", $e)?;
        }
        Ok(())
    })
}

impl<'a> crate::Encoder for Encoder<'a> {
    type Error = EncoderError;

    fn emit_unit(&mut self) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, "null")?;
        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u128(&mut self, v: u128) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }

    fn emit_isize(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i128(&mut self, v: i128) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i8(&mut self, v: i8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }

    fn emit_bool(&mut self, v: bool) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> EncodeResult {
        emit_enquoted_if_mapkey!(self, fmt_number_or_null(v))
    }
    fn emit_f32(&mut self, v: f32) -> EncodeResult {
        self.emit_f64(f64::from(v))
    }

    fn emit_char(&mut self, v: char) -> EncodeResult {
        escape_char(self.writer, v)
    }
    fn emit_str(&mut self, v: &str) -> EncodeResult {
        escape_str(self.writer, v)
    }

    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        f(self)
    }

    fn emit_enum_variant<F>(&mut self,
                            name: &str,
                            _id: usize,
                            cnt: usize,
                            f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        // enums are encoded as strings or objects
        // Bunny => "Bunny"
        // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
        if cnt == 0 {
            escape_str(self.writer, name)
        } else {
            if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
            write!(self.writer, "{{\"variant\":")?;
            escape_str(self.writer, name)?;
            write!(self.writer, ",\"fields\":[")?;
            f(self)?;
            write!(self.writer, "]}}")?;
            Ok(())
        }
    }

    fn emit_enum_variant_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx != 0 {
            write!(self.writer, ",")?;
        }
        f(self)
    }

    fn emit_enum_struct_variant<F>(&mut self,
                                   name: &str,
                                   id: usize,
                                   cnt: usize,
                                   f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_enum_variant(name, id, cnt, f)
    }

    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         idx: usize,
                                         f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_enum_variant_arg(idx, f)
    }

    fn emit_struct<F>(&mut self, _: &str, _: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, "{{")?;
        f(self)?;
        write!(self.writer, "}}")?;
        Ok(())
    }

    fn emit_struct_field<F>(&mut self, name: &str, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx != 0 { write!(self.writer, ",")?; }
        escape_str(self.writer, name)?;
        write!(self.writer, ":")?;
        f(self)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq(len, f)
    }
    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq_elt(idx, f)
    }

    fn emit_tuple_struct<F>(&mut self, _name: &str, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq(len, f)
    }
    fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq_elt(idx, f)
    }

    fn emit_option<F>(&mut self, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        f(self)
    }
    fn emit_option_none(&mut self) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_unit()
    }
    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        f(self)
    }

    fn emit_seq<F>(&mut self, _len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, "[")?;
        f(self)?;
        write!(self.writer, "]")?;
        Ok(())
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx != 0 {
            write!(self.writer, ",")?;
        }
        f(self)
    }

    fn emit_map<F>(&mut self, _len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, "{{")?;
        f(self)?;
        write!(self.writer, "}}")?;
        Ok(())
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx != 0 { write!(self.writer, ",")? }
        self.is_emitting_map_key = true;
        f(self)?;
        self.is_emitting_map_key = false;
        Ok(())
    }

    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, ":")?;
        f(self)
    }
}

/// Another encoder for JSON, but prints out human-readable JSON instead of
/// compact data
pub struct PrettyEncoder<'a> {
    writer: &'a mut (dyn fmt::Write+'a),
    curr_indent: usize,
    indent: usize,
    is_emitting_map_key: bool,
}

impl<'a> PrettyEncoder<'a> {
    /// Creates a new encoder whose output will be written to the specified writer
    pub fn new(writer: &'a mut dyn fmt::Write) -> PrettyEncoder<'a> {
        PrettyEncoder {
            writer,
            curr_indent: 0,
            indent: 2,
            is_emitting_map_key: false,
        }
    }

    /// Sets the number of spaces to indent for each level.
    /// This is safe to set during encoding.
    pub fn set_indent(&mut self, indent: usize) {
        // self.indent very well could be 0 so we need to use checked division.
        let level = self.curr_indent.checked_div(self.indent).unwrap_or(0);
        self.indent = indent;
        self.curr_indent = level * self.indent;
    }
}

impl<'a> crate::Encoder for PrettyEncoder<'a> {
    type Error = EncoderError;

    fn emit_unit(&mut self) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, "null")?;
        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u128(&mut self, v: u128) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }

    fn emit_isize(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i128(&mut self, v: i128) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
    fn emit_i8(&mut self, v: i8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }

    fn emit_bool(&mut self, v: bool) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }
        Ok(())
    }

    fn emit_f64(&mut self, v: f64) -> EncodeResult {
        emit_enquoted_if_mapkey!(self, fmt_number_or_null(v))
    }
    fn emit_f32(&mut self, v: f32) -> EncodeResult {
        self.emit_f64(f64::from(v))
    }

    fn emit_char(&mut self, v: char) -> EncodeResult {
        escape_char(self.writer, v)
    }
    fn emit_str(&mut self, v: &str) -> EncodeResult {
        escape_str(self.writer, v)
    }

    fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        f(self)
    }

    fn emit_enum_variant<F>(&mut self,
                            name: &str,
                            _id: usize,
                            cnt: usize,
                            f: F)
                            -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if cnt == 0 {
            escape_str(self.writer, name)
        } else {
            if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
            writeln!(self.writer, "{{")?;
            self.curr_indent += self.indent;
            spaces(self.writer, self.curr_indent)?;
            write!(self.writer, "\"variant\": ")?;
            escape_str(self.writer, name)?;
            writeln!(self.writer, ",")?;
            spaces(self.writer, self.curr_indent)?;
            writeln!(self.writer, "\"fields\": [")?;
            self.curr_indent += self.indent;
            f(self)?;
            self.curr_indent -= self.indent;
            writeln!(self.writer)?;
            spaces(self.writer, self.curr_indent)?;
            self.curr_indent -= self.indent;
            writeln!(self.writer, "]")?;
            spaces(self.writer, self.curr_indent)?;
            write!(self.writer, "}}")?;
            Ok(())
        }
    }

    fn emit_enum_variant_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx != 0 {
            writeln!(self.writer, ",")?;
        }
        spaces(self.writer, self.curr_indent)?;
        f(self)
    }

    fn emit_enum_struct_variant<F>(&mut self,
                                   name: &str,
                                   id: usize,
                                   cnt: usize,
                                   f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_enum_variant(name, id, cnt, f)
    }

    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         idx: usize,
                                         f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_enum_variant_arg(idx, f)
    }


    fn emit_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if len == 0 {
            write!(self.writer, "{{}}")?;
        } else {
            write!(self.writer, "{{")?;
            self.curr_indent += self.indent;
            f(self)?;
            self.curr_indent -= self.indent;
            writeln!(self.writer)?;
            spaces(self.writer, self.curr_indent)?;
            write!(self.writer, "}}")?;
        }
        Ok(())
    }

    fn emit_struct_field<F>(&mut self, name: &str, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx == 0 {
            writeln!(self.writer)?;
        } else {
            writeln!(self.writer, ",")?;
        }
        spaces(self.writer, self.curr_indent)?;
        escape_str(self.writer, name)?;
        write!(self.writer, ": ")?;
        f(self)
    }

    fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq(len, f)
    }
    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq_elt(idx, f)
    }

    fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq(len, f)
    }
    fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_seq_elt(idx, f)
    }

    fn emit_option<F>(&mut self, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        f(self)
    }
    fn emit_option_none(&mut self) -> EncodeResult {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        self.emit_unit()
    }
    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        f(self)
    }

    fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if len == 0 {
            write!(self.writer, "[]")?;
        } else {
            write!(self.writer, "[")?;
            self.curr_indent += self.indent;
            f(self)?;
            self.curr_indent -= self.indent;
            writeln!(self.writer)?;
            spaces(self.writer, self.curr_indent)?;
            write!(self.writer, "]")?;
        }
        Ok(())
    }

    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx == 0 {
            writeln!(self.writer)?;
        } else {
            writeln!(self.writer, ",")?;
        }
        spaces(self.writer, self.curr_indent)?;
        f(self)
    }

    fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if len == 0 {
            write!(self.writer, "{{}}")?;
        } else {
            write!(self.writer, "{{")?;
            self.curr_indent += self.indent;
            f(self)?;
            self.curr_indent -= self.indent;
            writeln!(self.writer)?;
            spaces(self.writer, self.curr_indent)?;
            write!(self.writer, "}}")?;
        }
        Ok(())
    }

    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        if idx == 0 {
            writeln!(self.writer)?;
        } else {
            writeln!(self.writer, ",")?;
        }
        spaces(self.writer, self.curr_indent)?;
        self.is_emitting_map_key = true;
        f(self)?;
        self.is_emitting_map_key = false;
        Ok(())
    }

    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
        F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
    {
        if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
        write!(self.writer, ": ")?;
        f(self)
    }
}

impl Encodable for Json {
    fn encode<E: crate::Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
        match *self {
            Json::I64(v) => v.encode(e),
            Json::U64(v) => v.encode(e),
            Json::F64(v) => v.encode(e),
            Json::String(ref v) => v.encode(e),
            Json::Boolean(v) => v.encode(e),
            Json::Array(ref v) => v.encode(e),
            Json::Object(ref v) => v.encode(e),
            Json::Null => e.emit_unit(),
        }
    }
}

/// Creates an `AsJson` wrapper which can be used to print a value as JSON
/// on-the-fly via `write!`
pub fn as_json<T>(t: &T) -> AsJson<'_, T> {
    AsJson { inner: t }
}

/// Creates an `AsPrettyJson` wrapper which can be used to print a value as JSON
/// on-the-fly via `write!`
pub fn as_pretty_json<T>(t: &T) -> AsPrettyJson<'_, T> {
    AsPrettyJson { inner: t, indent: None }
}

impl Json {
    /// Borrow this json object as a pretty object to generate a pretty
    /// representation for it via `Display`.
    pub fn pretty(&self) -> PrettyJson<'_> {
        PrettyJson { inner: self }
    }

     /// If the Json value is an Object, returns the value associated with the provided key.
    /// Otherwise, returns None.
    pub fn find(&self, key: &str) -> Option<&Json> {
        match *self {
            Json::Object(ref map) => map.get(key),
            _ => None
        }
    }

    /// Attempts to get a nested Json Object for each key in `keys`.
    /// If any key is found not to exist, `find_path` will return `None`.
    /// Otherwise, it will return the Json value associated with the final key.
    pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Json>{
        let mut target = self;
        for key in keys {
            target = target.find(*key)?;
        }
        Some(target)
    }

    /// If the Json value is an Object, performs a depth-first search until
    /// a value associated with the provided key is found. If no value is found
    /// or the Json value is not an Object, returns `None`.
    pub fn search(&self, key: &str) -> Option<&Json> {
        match *self {
            Json::Object(ref map) => {
                match map.get(key) {
                    Some(json_value) => Some(json_value),
                    None => {
                        for v in map.values() {
                            match v.search(key) {
                                x if x.is_some() => return x,
                                _ => ()
                            }
                        }
                        None
                    }
                }
            },
            _ => None
        }
    }

    /// Returns `true` if the Json value is an `Object`.
    pub fn is_object(&self) -> bool {
        self.as_object().is_some()
    }

    /// If the Json value is an `Object`, returns the associated `BTreeMap`;
    /// returns `None` otherwise.
    pub fn as_object(&self) -> Option<&Object> {
        match *self {
            Json::Object(ref map) => Some(map),
            _ => None
        }
    }

    /// Returns `true` if the Json value is an `Array`.
    pub fn is_array(&self) -> bool {
        self.as_array().is_some()
    }

    /// If the Json value is an `Array`, returns the associated vector;
    /// returns `None` otherwise.
    pub fn as_array(&self) -> Option<&Array> {
        match *self {
            Json::Array(ref array) => Some(&*array),
            _ => None
        }
    }

    /// Returns `true` if the Json value is a `String`.
    pub fn is_string(&self) -> bool {
        self.as_string().is_some()
    }

    /// If the Json value is a `String`, returns the associated `str`;
    /// returns `None` otherwise.
    pub fn as_string(&self) -> Option<&str> {
        match *self {
            Json::String(ref s) => Some(&s[..]),
            _ => None
        }
    }

    /// Returns `true` if the Json value is a `Number`.
    pub fn is_number(&self) -> bool {
        match *self {
            Json::I64(_) | Json::U64(_) | Json::F64(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the Json value is a `i64`.
    pub fn is_i64(&self) -> bool {
        match *self {
            Json::I64(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the Json value is a `u64`.
    pub fn is_u64(&self) -> bool {
        match *self {
            Json::U64(_) => true,
            _ => false,
        }
    }

    /// Returns `true` if the Json value is a `f64`.
    pub fn is_f64(&self) -> bool {
        match *self {
            Json::F64(_) => true,
            _ => false,
        }
    }

    /// If the Json value is a number, returns or cast it to a `i64`;
    /// returns `None` otherwise.
    pub fn as_i64(&self) -> Option<i64> {
        match *self {
            Json::I64(n) => Some(n),
            Json::U64(n) => Some(n as i64),
            _ => None
        }
    }

    /// If the Json value is a number, returns or cast it to a `u64`;
    /// returns `None` otherwise.
    pub fn as_u64(&self) -> Option<u64> {
        match *self {
            Json::I64(n) => Some(n as u64),
            Json::U64(n) => Some(n),
            _ => None
        }
    }

    /// If the Json value is a number, returns or cast it to a `f64`;
    /// returns `None` otherwise.
    pub fn as_f64(&self) -> Option<f64> {
        match *self {
            Json::I64(n) => Some(n as f64),
            Json::U64(n) => Some(n as f64),
            Json::F64(n) => Some(n),
            _ => None
        }
    }

    /// Returns `true` if the Json value is a `Boolean`.
    pub fn is_boolean(&self) -> bool {
        self.as_boolean().is_some()
    }

    /// If the Json value is a `Boolean`, returns the associated `bool`;
    /// returns `None` otherwise.
    pub fn as_boolean(&self) -> Option<bool> {
        match *self {
            Json::Boolean(b) => Some(b),
            _ => None
        }
    }

    /// Returns `true` if the Json value is a `Null`.
    pub fn is_null(&self) -> bool {
        self.as_null().is_some()
    }

    /// If the Json value is a `Null`, returns `()`;
    /// returns `None` otherwise.
    pub fn as_null(&self) -> Option<()> {
        match *self {
            Json::Null => Some(()),
            _ => None
        }
    }
}

impl<'a> Index<&'a str>  for Json {
    type Output = Json;

    fn index(&self, idx: &'a str) -> &Json {
        self.find(idx).unwrap()
    }
}

impl Index<usize> for Json {
    type Output = Json;

    fn index(&self, idx: usize) -> &Json {
        match *self {
            Json::Array(ref v) => &v[idx],
            _ => panic!("can only index Json with usize if it is an array")
        }
    }
}

/// The output of the streaming parser.
#[derive(PartialEq, Clone, Debug)]
pub enum JsonEvent {
    ObjectStart,
    ObjectEnd,
    ArrayStart,
    ArrayEnd,
    BooleanValue(bool),
    I64Value(i64),
    U64Value(u64),
    F64Value(f64),
    StringValue(string::String),
    NullValue,
    Error(ParserError),
}

#[derive(PartialEq, Debug)]
enum ParserState {
    // Parse a value in an array, true means first element.
    ParseArray(bool),
    // Parse ',' or ']' after an element in an array.
    ParseArrayComma,
    // Parse a key:value in an object, true means first element.
    ParseObject(bool),
    // Parse ',' or ']' after an element in an object.
    ParseObjectComma,
    // Initial state.
    ParseStart,
    // Expecting the stream to end.
    ParseBeforeFinish,
    // Parsing can't continue.
    ParseFinished,
}

/// A Stack represents the current position of the parser in the logical
/// structure of the JSON stream.
/// For example foo.bar[3].x
pub struct Stack {
    stack: Vec<InternalStackElement>,
    str_buffer: Vec<u8>,
}

/// StackElements compose a Stack.
/// For example, StackElement::Key("foo"), StackElement::Key("bar"),
/// StackElement::Index(3) and StackElement::Key("x") are the
/// StackElements compositing the stack that represents foo.bar[3].x
#[derive(PartialEq, Clone, Debug)]
pub enum StackElement<'l> {
    Index(u32),
    Key(&'l str),
}

// Internally, Key elements are stored as indices in a buffer to avoid
// allocating a string for every member of an object.
#[derive(PartialEq, Clone, Debug)]
enum InternalStackElement {
    InternalIndex(u32),
    InternalKey(u16, u16), // start, size
}

impl Stack {
    pub fn new() -> Stack {
        Stack { stack: Vec::new(), str_buffer: Vec::new() }
    }

    /// Returns The number of elements in the Stack.
    pub fn len(&self) -> usize { self.stack.len() }

    /// Returns `true` if the stack is empty.
    pub fn is_empty(&self) -> bool { self.stack.is_empty() }

    /// Provides access to the StackElement at a given index.
    /// lower indices are at the bottom of the stack while higher indices are
    /// at the top.
    pub fn get(&self, idx: usize) -> StackElement<'_> {
        match self.stack[idx] {
            InternalIndex(i) => StackElement::Index(i),
            InternalKey(start, size) => {
                StackElement::Key(str::from_utf8(
                    &self.str_buffer[start as usize .. start as usize + size as usize])
                        .unwrap())
            }
        }
    }

    /// Compares this stack with an array of StackElement<'_>s.
    pub fn is_equal_to(&self, rhs: &[StackElement<'_>]) -> bool {
        if self.stack.len() != rhs.len() { return false; }
        for (i, r) in rhs.iter().enumerate() {
            if self.get(i) != *r { return false; }
        }
        true
    }

    /// Returns `true` if the bottom-most elements of this stack are the same as
    /// the ones passed as parameter.
    pub fn starts_with(&self, rhs: &[StackElement<'_>]) -> bool {
        if self.stack.len() < rhs.len() { return false; }
        for (i, r) in rhs.iter().enumerate() {
            if self.get(i) != *r { return false; }
        }
        true
    }

    /// Returns `true` if the top-most elements of this stack are the same as
    /// the ones passed as parameter.
    pub fn ends_with(&self, rhs: &[StackElement<'_>]) -> bool {
        if self.stack.len() < rhs.len() { return false; }
        let offset = self.stack.len() - rhs.len();
        for (i, r) in rhs.iter().enumerate() {
            if self.get(i + offset) != *r { return false; }
        }
        true
    }

    /// Returns the top-most element (if any).
    pub fn top(&self) -> Option<StackElement<'_>> {
        match self.stack.last() {
            None => None,
            Some(&InternalIndex(i)) => Some(StackElement::Index(i)),
            Some(&InternalKey(start, size)) => {
                Some(StackElement::Key(str::from_utf8(
                    &self.str_buffer[start as usize .. (start+size) as usize]
                ).unwrap()))
            }
        }
    }

    // Used by Parser to insert StackElement::Key elements at the top of the stack.
    fn push_key(&mut self, key: string::String) {
        self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16));
        self.str_buffer.extend(key.as_bytes());
    }

    // Used by Parser to insert StackElement::Index elements at the top of the stack.
    fn push_index(&mut self, index: u32) {
        self.stack.push(InternalIndex(index));
    }

    // Used by Parser to remove the top-most element of the stack.
    fn pop(&mut self) {
        assert!(!self.is_empty());
        match *self.stack.last().unwrap() {
            InternalKey(_, sz) => {
                let new_size = self.str_buffer.len() - sz as usize;
                self.str_buffer.truncate(new_size);
            }
            InternalIndex(_) => {}
        }
        self.stack.pop();
    }

    // Used by Parser to test whether the top-most element is an index.
    fn last_is_index(&self) -> bool {
        match self.stack.last() {
            Some(InternalIndex(_)) => true,
            _ => false,
        }
    }

    // Used by Parser to increment the index of the top-most element.
    fn bump_index(&mut self) {
        let len = self.stack.len();
        let idx = match *self.stack.last().unwrap() {
            InternalIndex(i) => { i + 1 }
            _ => { panic!(); }
        };
        self.stack[len - 1] = InternalIndex(idx);
    }
}

/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming
/// an iterator of char.
pub struct Parser<T> {
    rdr: T,
    ch: Option<char>,
    line: usize,
    col: usize,
    // We maintain a stack representing where we are in the logical structure
    // of the JSON stream.
    stack: Stack,
    // A state machine is kept to make it possible to interrupt and resume parsing.
    state: ParserState,
}

impl<T: Iterator<Item=char>> Iterator for Parser<T> {
    type Item = JsonEvent;

    fn next(&mut self) -> Option<JsonEvent> {
        if self.state == ParseFinished {
            return None;
        }

        if self.state == ParseBeforeFinish {
            self.parse_whitespace();
            // Make sure there is no trailing characters.
            if self.eof() {
                self.state = ParseFinished;
                return None;
            } else {
                return Some(self.error_event(TrailingCharacters));
            }
        }

        Some(self.parse())
    }
}

impl<T: Iterator<Item=char>> Parser<T> {
    /// Creates the JSON parser.
    pub fn new(rdr: T) -> Parser<T> {
        let mut p = Parser {
            rdr,
            ch: Some('\x00'),
            line: 1,
            col: 0,
            stack: Stack::new(),
            state: ParseStart,
        };
        p.bump();
        p
    }

    /// Provides access to the current position in the logical structure of the
    /// JSON stream.
    pub fn stack(&self) -> &Stack {
        &self.stack
    }

    fn eof(&self) -> bool { self.ch.is_none() }
    fn ch_or_null(&self) -> char { self.ch.unwrap_or('\x00') }
    fn bump(&mut self) {
        self.ch = self.rdr.next();

        if self.ch_is('\n') {
            self.line += 1;
            self.col = 1;
        } else {
            self.col += 1;
        }
    }

    fn next_char(&mut self) -> Option<char> {
        self.bump();
        self.ch
    }
    fn ch_is(&self, c: char) -> bool {
        self.ch == Some(c)
    }

    fn error<U>(&self, reason: ErrorCode) -> Result<U, ParserError> {
        Err(SyntaxError(reason, self.line, self.col))
    }

    fn parse_whitespace(&mut self) {
        while self.ch_is(' ') ||
              self.ch_is('\n') ||
              self.ch_is('\t') ||
              self.ch_is('\r') { self.bump(); }
    }

    fn parse_number(&mut self) -> JsonEvent {
        let neg = if self.ch_is('-') {
            self.bump();
            true
        } else {
            false
        };

        let res = match self.parse_u64() {
            Ok(res) => res,
            Err(e) => { return Error(e); }
        };

        if self.ch_is('.') || self.ch_is('e') || self.ch_is('E') {
            let mut res = res as f64;

            if self.ch_is('.') {
                res = match self.parse_decimal(res) {
                    Ok(res) => res,
                    Err(e) => { return Error(e); }
                };
            }

            if self.ch_is('e') || self.ch_is('E') {
                res = match self.parse_exponent(res) {
                    Ok(res) => res,
                    Err(e) => { return Error(e); }
                };
            }

            if neg {
                res *= -1.0;
            }

            F64Value(res)
        } else if neg {
            let res = (res as i64).wrapping_neg();

            // Make sure we didn't underflow.
            if res > 0 {
                Error(SyntaxError(InvalidNumber, self.line, self.col))
            } else {
                I64Value(res)
            }
        } else {
            U64Value(res)
        }
    }

    fn parse_u64(&mut self) -> Result<u64, ParserError> {
        let mut accum = 0u64;
        let last_accum = 0; // necessary to detect overflow.

        match self.ch_or_null() {
            '0' => {
                self.bump();

                // A leading '0' must be the only digit before the decimal point.
                if let '0' ..= '9' = self.ch_or_null() {
                    return self.error(InvalidNumber)
                }
            },
            '1' ..= '9' => {
                while !self.eof() {
                    match self.ch_or_null() {
                        c @ '0' ..= '9' => {
                            accum = accum.wrapping_mul(10);
                            accum = accum.wrapping_add((c as u64) - ('0' as u64));

                            // Detect overflow by comparing to the last value.
                            if accum <= last_accum { return self.error(InvalidNumber); }

                            self.bump();
                        }
                        _ => break,
                    }
                }
            }
            _ => return self.error(InvalidNumber),
        }

        Ok(accum)
    }

    fn parse_decimal(&mut self, mut res: f64) -> Result<f64, ParserError> {
        self.bump();

        // Make sure a digit follows the decimal place.
        match self.ch_or_null() {
            '0' ..= '9' => (),
             _ => return self.error(InvalidNumber)
        }

        let mut dec = 1.0;
        while !self.eof() {
            match self.ch_or_null() {
                c @ '0' ..= '9' => {
                    dec /= 10.0;
                    res += (((c as isize) - ('0' as isize)) as f64) * dec;
                    self.bump();
                }
                _ => break,
            }
        }

        Ok(res)
    }

    fn parse_exponent(&mut self, mut res: f64) -> Result<f64, ParserError> {
        self.bump();

        let mut exp = 0;
        let mut neg_exp = false;

        if self.ch_is('+') {
            self.bump();
        } else if self.ch_is('-') {
            self.bump();
            neg_exp = true;
        }

        // Make sure a digit follows the exponent place.
        match self.ch_or_null() {
            '0' ..= '9' => (),
            _ => return self.error(InvalidNumber)
        }
        while !self.eof() {
            match self.ch_or_null() {
                c @ '0' ..= '9' => {
                    exp *= 10;
                    exp += (c as usize) - ('0' as usize);

                    self.bump();
                }
                _ => break
            }
        }

        let exp = 10_f64.powi(exp as i32);
        if neg_exp {
            res /= exp;
        } else {
            res *= exp;
        }

        Ok(res)
    }

    fn decode_hex_escape(&mut self) -> Result<u16, ParserError> {
        let mut i = 0;
        let mut n = 0;
        while i < 4 && !self.eof() {
            self.bump();
            n = match self.ch_or_null() {
                c @ '0' ..= '9' => n * 16 + ((c as u16) - ('0' as u16)),
                'a' | 'A' => n * 16 + 10,
                'b' | 'B' => n * 16 + 11,
                'c' | 'C' => n * 16 + 12,
                'd' | 'D' => n * 16 + 13,
                'e' | 'E' => n * 16 + 14,
                'f' | 'F' => n * 16 + 15,
                _ => return self.error(InvalidEscape)
            };

            i += 1;
        }

        // Error out if we didn't parse 4 digits.
        if i != 4 {
            return self.error(InvalidEscape);
        }

        Ok(n)
    }

    fn parse_str(&mut self) -> Result<string::String, ParserError> {
        let mut escape = false;
        let mut res = string::String::new();

        loop {
            self.bump();
            if self.eof() {
                return self.error(EOFWhileParsingString);
            }

            if escape {
                match self.ch_or_null() {
                    '"' => res.push('"'),
                    '\\' => res.push('\\'),
                    '/' => res.push('/'),
                    'b' => res.push('\x08'),
                    'f' => res.push('\x0c'),
                    'n' => res.push('\n'),
                    'r' => res.push('\r'),
                    't' => res.push('\t'),
                    'u' => match self.decode_hex_escape()? {
                        0xDC00 ..= 0xDFFF => {
                            return self.error(LoneLeadingSurrogateInHexEscape)
                        }

                        // Non-BMP characters are encoded as a sequence of
                        // two hex escapes, representing UTF-16 surrogates.
                        n1 @ 0xD800 ..= 0xDBFF => {
                            match (self.next_char(), self.next_char()) {
                                (Some('\\'), Some('u')) => (),
                                _ => return self.error(UnexpectedEndOfHexEscape),
                            }

                            let n2 = self.decode_hex_escape()?;
                            if n2 < 0xDC00 || n2 > 0xDFFF {
                                return self.error(LoneLeadingSurrogateInHexEscape)
                            }
                            let c = (u32::from(n1 - 0xD800) << 10 |
                                     u32::from(n2 - 0xDC00)) + 0x1_0000;
                            res.push(char::from_u32(c).unwrap());
                        }

                        n => match char::from_u32(u32::from(n)) {
                            Some(c) => res.push(c),
                            None => return self.error(InvalidUnicodeCodePoint),
                        },
                    },
                    _ => return self.error(InvalidEscape),
                }
                escape = false;
            } else if self.ch_is('\\') {
                escape = true;
            } else {
                match self.ch {
                    Some('"') => {
                        self.bump();
                        return Ok(res);
                    },
                    Some(c) => res.push(c),
                    None => unreachable!()
                }
            }
        }
    }

    // Invoked at each iteration, consumes the stream until it has enough
    // information to return a JsonEvent.
    // Manages an internal state so that parsing can be interrupted and resumed.
    // Also keeps track of the position in the logical structure of the json
    // stream isize the form of a stack that can be queried by the user using the
    // stack() method.
    fn parse(&mut self) -> JsonEvent {
        loop {
            // The only paths where the loop can spin a new iteration
            // are in the cases ParseArrayComma and ParseObjectComma if ','
            // is parsed. In these cases the state is set to (respectively)
            // ParseArray(false) and ParseObject(false), which always return,
            // so there is no risk of getting stuck in an infinite loop.
            // All other paths return before the end of the loop's iteration.
            self.parse_whitespace();

            match self.state {
                ParseStart => {
                    return self.parse_start();
                }
                ParseArray(first) => {
                    return self.parse_array(first);
                }
                ParseArrayComma => {
                    if let Some(evt) = self.parse_array_comma_or_end() {
                        return evt;
                    }
                }
                ParseObject(first) => {
                    return self.parse_object(first);
                }
                ParseObjectComma => {
                    self.stack.pop();
                    if self.ch_is(',') {
                        self.state = ParseObject(false);
                        self.bump();
                    } else {
                        return self.parse_object_end();
                    }
                }
                _ => {
                    return self.error_event(InvalidSyntax);
                }
            }
        }
    }

    fn parse_start(&mut self) -> JsonEvent {
        let val = self.parse_value();
        self.state = match val {
            Error(_) => ParseFinished,
            ArrayStart => ParseArray(true),
            ObjectStart => ParseObject(true),
            _ => ParseBeforeFinish,
        };
        val
    }

    fn parse_array(&mut self, first: bool) -> JsonEvent {
        if self.ch_is(']') {
            if !first {
                self.error_event(InvalidSyntax)
            } else {
                self.state = if self.stack.is_empty() {
                    ParseBeforeFinish
                } else if self.stack.last_is_index() {
                    ParseArrayComma
                } else {
                    ParseObjectComma
                };
                self.bump();
                ArrayEnd
            }
        } else {
            if first {
                self.stack.push_index(0);
            }
            let val = self.parse_value();
            self.state = match val {
                Error(_) => ParseFinished,
                ArrayStart => ParseArray(true),
                ObjectStart => ParseObject(true),
                _ => ParseArrayComma,
            };
            val
        }
    }

    fn parse_array_comma_or_end(&mut self) -> Option<JsonEvent> {
        if self.ch_is(',') {
            self.stack.bump_index();
            self.state = ParseArray(false);
            self.bump();
            None
        } else if self.ch_is(']') {
            self.stack.pop();
            self.state = if self.stack.is_empty() {
                ParseBeforeFinish
            } else if self.stack.last_is_index() {
                ParseArrayComma
            } else {
                ParseObjectComma
            };
            self.bump();
            Some(ArrayEnd)
        } else if self.eof() {
            Some(self.error_event(EOFWhileParsingArray))
        } else {
            Some(self.error_event(InvalidSyntax))
        }
    }

    fn parse_object(&mut self, first: bool) -> JsonEvent {
        if self.ch_is('}') {
            if !first {
                if self.stack.is_empty() {
                    return self.error_event(TrailingComma);
                } else {
                    self.stack.pop();
                }
            }
            self.state = if self.stack.is_empty() {
                ParseBeforeFinish
            } else if self.stack.last_is_index() {
                ParseArrayComma
            } else {
                ParseObjectComma
            };
            self.bump();
            return ObjectEnd;
        }
        if self.eof() {
            return self.error_event(EOFWhileParsingObject);
        }
        if !self.ch_is('"') {
            return self.error_event(KeyMustBeAString);
        }
        let s = match self.parse_str() {
            Ok(s) => s,
            Err(e) => {
                self.state = ParseFinished;
                return Error(e);
            }
        };
        self.parse_whitespace();
        if self.eof() {
            return self.error_event(EOFWhileParsingObject);
        } else if self.ch_or_null() != ':' {
            return self.error_event(ExpectedColon);
        }
        self.stack.push_key(s);
        self.bump();
        self.parse_whitespace();

        let val = self.parse_value();

        self.state = match val {
            Error(_) => ParseFinished,
            ArrayStart => ParseArray(true),
            ObjectStart => ParseObject(true),
            _ => ParseObjectComma,
        };
        val
    }

    fn parse_object_end(&mut self) -> JsonEvent {
        if self.ch_is('}') {
            self.state = if self.stack.is_empty() {
                ParseBeforeFinish
            } else if self.stack.last_is_index() {
                ParseArrayComma
            } else {
                ParseObjectComma
            };
            self.bump();
            ObjectEnd
        } else if self.eof() {
            self.error_event(EOFWhileParsingObject)
        } else {
            self.error_event(InvalidSyntax)
        }
    }

    fn parse_value(&mut self) -> JsonEvent {
        if self.eof() { return self.error_event(EOFWhileParsingValue); }
        match self.ch_or_null() {
            'n' => { self.parse_ident("ull", NullValue) }
            't' => { self.parse_ident("rue", BooleanValue(true)) }
            'f' => { self.parse_ident("alse", BooleanValue(false)) }
            '0' ..= '9' | '-' => self.parse_number(),
            '"' => match self.parse_str() {
                Ok(s) => StringValue(s),
                Err(e) => Error(e),
            },
            '[' => {
                self.bump();
                ArrayStart
            }
            '{' => {
                self.bump();
                ObjectStart
            }
            _ => { self.error_event(InvalidSyntax) }
        }
    }

    fn parse_ident(&mut self, ident: &str, value: JsonEvent) -> JsonEvent {
        if ident.chars().all(|c| Some(c) == self.next_char()) {
            self.bump();
            value
        } else {
            Error(SyntaxError(InvalidSyntax, self.line, self.col))
        }
    }

    fn error_event(&mut self, reason: ErrorCode) -> JsonEvent {
        self.state = ParseFinished;
        Error(SyntaxError(reason, self.line, self.col))
    }
}

/// A Builder consumes a json::Parser to create a generic Json structure.
pub struct Builder<T> {
    parser: Parser<T>,
    token: Option<JsonEvent>,
}

impl<T: Iterator<Item=char>> Builder<T> {
    /// Creates a JSON Builder.
    pub fn new(src: T) -> Builder<T> {
        Builder { parser: Parser::new(src), token: None, }
    }

    // Decode a Json value from a Parser.
    pub fn build(&mut self) -> Result<Json, BuilderError> {
        self.bump();
        let result = self.build_value();
        self.bump();
        match self.token {
            None => {}
            Some(Error(ref e)) => { return Err(e.clone()); }
            ref tok => { panic!("unexpected token {:?}", tok.clone()); }
        }
        result
    }

    fn bump(&mut self) {
        self.token = self.parser.next();
    }

    fn build_value(&mut self) -> Result<Json, BuilderError> {
        match self.token {
            Some(NullValue) => Ok(Json::Null),
            Some(I64Value(n)) => Ok(Json::I64(n)),
            Some(U64Value(n)) => Ok(Json::U64(n)),
            Some(F64Value(n)) => Ok(Json::F64(n)),
            Some(BooleanValue(b)) => Ok(Json::Boolean(b)),
            Some(StringValue(ref mut s)) => {
                let mut temp = string::String::new();
                swap(s, &mut temp);
                Ok(Json::String(temp))
            }
            Some(Error(ref e)) => Err(e.clone()),
            Some(ArrayStart) => self.build_array(),
            Some(ObjectStart) => self.build_object(),
            Some(ObjectEnd) => self.parser.error(InvalidSyntax),
            Some(ArrayEnd) => self.parser.error(InvalidSyntax),
            None => self.parser.error(EOFWhileParsingValue),
        }
    }

    fn build_array(&mut self) -> Result<Json, BuilderError> {
        self.bump();
        let mut values = Vec::new();

        loop {
            if self.token == Some(ArrayEnd) {
                return Ok(Json::Array(values.into_iter().collect()));
            }
            match self.build_value() {
                Ok(v) => values.push(v),
                Err(e) => { return Err(e) }
            }
            self.bump();
        }
    }

    fn build_object(&mut self) -> Result<Json, BuilderError> {
        self.bump();

        let mut values = BTreeMap::new();

        loop {
            match self.token {
                Some(ObjectEnd) => { return Ok(Json::Object(values)); }
                Some(Error(ref e)) => { return Err(e.clone()); }
                None => { break; }
                _ => {}
            }
            let key = match self.parser.stack().top() {
                Some(StackElement::Key(k)) => { k.to_owned() }
                _ => { panic!("invalid state"); }
            };
            match self.build_value() {
                Ok(value) => { values.insert(key, value); }
                Err(e) => { return Err(e); }
            }
            self.bump();
        }
        self.parser.error(EOFWhileParsingObject)
    }
}

/// Decodes a json value from an `&mut io::Read`
pub fn from_reader(rdr: &mut dyn Read) -> Result<Json, BuilderError> {
    let mut contents = Vec::new();
    match rdr.read_to_end(&mut contents) {
        Ok(c)  => c,
        Err(e) => return Err(io_error_to_error(e))
    };
    let s = match str::from_utf8(&contents).ok() {
        Some(s) => s,
        _       => return Err(SyntaxError(NotUtf8, 0, 0))
    };
    let mut builder = Builder::new(s.chars());
    builder.build()
}

/// Decodes a json value from a string
pub fn from_str(s: &str) -> Result<Json, BuilderError> {
    let mut builder = Builder::new(s.chars());
    builder.build()
}

/// A structure to decode JSON to values in rust.
pub struct Decoder {
    stack: Vec<Json>,
}

impl Decoder {
    /// Creates a new decoder instance for decoding the specified JSON value.
    pub fn new(json: Json) -> Decoder {
        Decoder { stack: vec![json] }
    }

    fn pop(&mut self) -> Json {
        self.stack.pop().unwrap()
    }
}

macro_rules! expect {
    ($e:expr, Null) => ({
        match $e {
            Json::Null => Ok(()),
            other => Err(ExpectedError("Null".to_owned(),
                                       other.to_string()))
        }
    });
    ($e:expr, $t:ident) => ({
        match $e {
            Json::$t(v) => Ok(v),
            other => {
                Err(ExpectedError(stringify!($t).to_owned(),
                                  other.to_string()))
            }
        }
    })
}

macro_rules! read_primitive {
    ($name:ident, $ty:ty) => {
        fn $name(&mut self) -> DecodeResult<$ty> {
            match self.pop() {
                Json::I64(f) => Ok(f as $ty),
                Json::U64(f) => Ok(f as $ty),
                Json::F64(f) => Err(ExpectedError("Integer".to_owned(), f.to_string())),
                // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                // is going to have a string here, as per JSON spec.
                Json::String(s) => match s.parse().ok() {
                    Some(f) => Ok(f),
                    None => Err(ExpectedError("Number".to_owned(), s)),
                },
                value => Err(ExpectedError("Number".to_owned(), value.to_string())),
            }
        }
    }
}

impl crate::Decoder for Decoder {
    type Error = DecoderError;

    fn read_nil(&mut self) -> DecodeResult<()> {
        expect!(self.pop(), Null)
    }

    read_primitive! { read_usize, usize }
    read_primitive! { read_u8, u8 }
    read_primitive! { read_u16, u16 }
    read_primitive! { read_u32, u32 }
    read_primitive! { read_u64, u64 }
    read_primitive! { read_u128, u128 }
    read_primitive! { read_isize, isize }
    read_primitive! { read_i8, i8 }
    read_primitive! { read_i16, i16 }
    read_primitive! { read_i32, i32 }
    read_primitive! { read_i64, i64 }
    read_primitive! { read_i128, i128 }

    fn read_f32(&mut self) -> DecodeResult<f32> { self.read_f64().map(|x| x as f32) }

    fn read_f64(&mut self) -> DecodeResult<f64> {
        match self.pop() {
            Json::I64(f) => Ok(f as f64),
            Json::U64(f) => Ok(f as f64),
            Json::F64(f) => Ok(f),
            Json::String(s) => {
                // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                // is going to have a string here, as per JSON spec.
                match s.parse().ok() {
                    Some(f) => Ok(f),
                    None => Err(ExpectedError("Number".to_owned(), s)),
                }
            },
            Json::Null => Ok(f64::NAN),
            value => Err(ExpectedError("Number".to_owned(), value.to_string()))
        }
    }

    fn read_bool(&mut self) -> DecodeResult<bool> {
        expect!(self.pop(), Boolean)
    }

    fn read_char(&mut self) -> DecodeResult<char> {
        let s = self.read_str()?;
        {
            let mut it = s.chars();
            if let (Some(c), None) = (it.next(), it.next()) {
                // exactly one character
                return Ok(c);
            }
        }
        Err(ExpectedError("single character string".to_owned(), s.to_string()))
    }

    fn read_str(&mut self) -> DecodeResult<Cow<'_, str>> {
        expect!(self.pop(), String).map(Cow::Owned)
    }

    fn read_enum<T, F>(&mut self, _name: &str, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        f(self)
    }

    fn read_enum_variant<T, F>(&mut self, names: &[&str],
                               mut f: F) -> DecodeResult<T>
        where F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
    {
        let name = match self.pop() {
            Json::String(s) => s,
            Json::Object(mut o) => {
                let n = match o.remove(&"variant".to_owned()) {
                    Some(Json::String(s)) => s,
                    Some(val) => {
                        return Err(ExpectedError("String".to_owned(), val.to_string()))
                    }
                    None => {
                        return Err(MissingFieldError("variant".to_owned()))
                    }
                };
                match o.remove(&"fields".to_string()) {
                    Some(Json::Array(l)) => {
                        self.stack.extend(l.into_iter().rev());
                    },
                    Some(val) => {
                        return Err(ExpectedError("Array".to_owned(), val.to_string()))
                    }
                    None => {
                        return Err(MissingFieldError("fields".to_owned()))
                    }
                }
                n
            }
            json => {
                return Err(ExpectedError("String or Object".to_owned(), json.to_string()))
            }
        };
        let idx = match names.iter().position(|n| *n == &name[..]) {
            Some(idx) => idx,
            None => return Err(UnknownVariantError(name))
        };
        f(self, idx)
    }

    fn read_enum_variant_arg<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        f(self)
    }

    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
        F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
    {
        self.read_enum_variant(names, f)
    }


    fn read_enum_struct_variant_field<T, F>(&mut self,
                                         _name: &str,
                                         idx: usize,
                                         f: F)
                                         -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        self.read_enum_variant_arg(idx, f)
    }

    fn read_struct<T, F>(&mut self, _name: &str, _len: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        let value = f(self)?;
        self.pop();
        Ok(value)
    }

    fn read_struct_field<T, F>(&mut self,
                               name: &str,
                               _idx: usize,
                               f: F)
                               -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        let mut obj = expect!(self.pop(), Object)?;

        let value = match obj.remove(&name.to_string()) {
            None => {
                // Add a Null and try to parse it as an Option<_>
                // to get None as a default value.
                self.stack.push(Json::Null);
                match f(self) {
                    Ok(x) => x,
                    Err(_) => return Err(MissingFieldError(name.to_string())),
                }
            },
            Some(json) => {
                self.stack.push(json);
                f(self)?
            }
        };
        self.stack.push(Json::Object(obj));
        Ok(value)
    }

    fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        self.read_seq(move |d, len| {
            if len == tuple_len {
                f(d)
            } else {
                Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)))
            }
        })
    }

    fn read_tuple_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        self.read_seq_elt(idx, f)
    }

    fn read_tuple_struct<T, F>(&mut self,
                               _name: &str,
                               len: usize,
                               f: F)
                               -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        self.read_tuple(len, f)
    }

    fn read_tuple_struct_arg<T, F>(&mut self,
                                   idx: usize,
                                   f: F)
                                   -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        self.read_tuple_arg(idx, f)
    }

    fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
        F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
    {
        match self.pop() {
            Json::Null => f(self, false),
            value => { self.stack.push(value); f(self, true) }
        }
    }

    fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
    {
        let array = expect!(self.pop(), Array)?;
        let len = array.len();
        self.stack.extend(array.into_iter().rev());
        f(self, len)
    }

    fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        f(self)
    }

    fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
    {
        let obj = expect!(self.pop(), Object)?;
        let len = obj.len();
        for (key, value) in obj {
            self.stack.push(value);
            self.stack.push(Json::String(key));
        }
        f(self, len)
    }

    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
       F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        f(self)
    }

    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
       F: FnOnce(&mut Decoder) -> DecodeResult<T>,
    {
        f(self)
    }

    fn error(&mut self, err: &str) -> DecoderError {
        ApplicationError(err.to_string())
    }
}

/// A trait for converting values to JSON
pub trait ToJson {
    /// Converts the value of `self` to an instance of JSON
    fn to_json(&self) -> Json;
}

macro_rules! to_json_impl_i64 {
    ($($t:ty), +) => (
        $(impl ToJson for $t {
            fn to_json(&self) -> Json {
                Json::I64(*self as i64)
            }
        })+
    )
}

to_json_impl_i64! { isize, i8, i16, i32, i64 }

macro_rules! to_json_impl_u64 {
    ($($t:ty), +) => (
        $(impl ToJson for $t {
            fn to_json(&self) -> Json {
                Json::U64(*self as u64)
            }
        })+
    )
}

to_json_impl_u64! { usize, u8, u16, u32, u64 }

impl ToJson for Json {
    fn to_json(&self) -> Json { self.clone() }
}

impl ToJson for f32 {
    fn to_json(&self) -> Json { f64::from(*self).to_json() }
}

impl ToJson for f64 {
    fn to_json(&self) -> Json {
        match self.classify() {
            Fp::Nan | Fp::Infinite => Json::Null,
            _                  => Json::F64(*self)
        }
    }
}

impl ToJson for () {
    fn to_json(&self) -> Json { Json::Null }
}

impl ToJson for bool {
    fn to_json(&self) -> Json { Json::Boolean(*self) }
}

impl ToJson for str {
    fn to_json(&self) -> Json { Json::String(self.to_string()) }
}

impl ToJson for string::String {
    fn to_json(&self) -> Json { Json::String((*self).clone()) }
}

macro_rules! tuple_impl {
    // use variables to indicate the arity of the tuple
    ($($tyvar:ident),* ) => {
        // the trailing commas are for the 1 tuple
        impl<
            $( $tyvar : ToJson ),*
            > ToJson for ( $( $tyvar ),* , ) {

            #[inline]
            #[allow(non_snake_case)]
            fn to_json(&self) -> Json {
                match *self {
                    ($(ref $tyvar),*,) => Json::Array(vec![$($tyvar.to_json()),*])
                }
            }
        }
    }
}

tuple_impl!{A}
tuple_impl!{A, B}
tuple_impl!{A, B, C}
tuple_impl!{A, B, C, D}
tuple_impl!{A, B, C, D, E}
tuple_impl!{A, B, C, D, E, F}
tuple_impl!{A, B, C, D, E, F, G}
tuple_impl!{A, B, C, D, E, F, G, H}
tuple_impl!{A, B, C, D, E, F, G, H, I}
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}

impl<A: ToJson> ToJson for [A] {
    fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) }
}

impl<A: ToJson> ToJson for Vec<A> {
    fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) }
}

impl<A: ToJson> ToJson for BTreeMap<string::String, A> {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        for (key, value) in self {
            d.insert((*key).clone(), value.to_json());
        }
        Json::Object(d)
    }
}

impl<A: ToJson> ToJson for HashMap<string::String, A> {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        for (key, value) in self {
            d.insert((*key).clone(), value.to_json());
        }
        Json::Object(d)
    }
}

impl<A:ToJson> ToJson for Option<A> {
    fn to_json(&self) -> Json {
        match *self {
            None => Json::Null,
            Some(ref value) => value.to_json()
        }
    }
}

struct FormatShim<'a, 'b> {
    inner: &'a mut fmt::Formatter<'b>,
}

impl<'a, 'b> fmt::Write for FormatShim<'a, 'b> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        match self.inner.write_str(s) {
            Ok(_) => Ok(()),
            Err(_) => Err(fmt::Error)
        }
    }
}

impl fmt::Display for Json {
    /// Encodes a json value into a string
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut shim = FormatShim { inner: f };
        let mut encoder = Encoder::new(&mut shim);
        match self.encode(&mut encoder) {
            Ok(_) => Ok(()),
            Err(_) => Err(fmt::Error)
        }
    }
}

impl<'a> fmt::Display for PrettyJson<'a> {
    /// Encodes a json value into a string
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut shim = FormatShim { inner: f };
        let mut encoder = PrettyEncoder::new(&mut shim);
        match self.inner.encode(&mut encoder) {
            Ok(_) => Ok(()),
            Err(_) => Err(fmt::Error)
        }
    }
}

impl<'a, T: Encodable> fmt::Display for AsJson<'a, T> {
    /// Encodes a json value into a string
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut shim = FormatShim { inner: f };
        let mut encoder = Encoder::new(&mut shim);
        match self.inner.encode(&mut encoder) {
            Ok(_) => Ok(()),
            Err(_) => Err(fmt::Error)
        }
    }
}

impl<'a, T> AsPrettyJson<'a, T> {
    /// Sets the indentation level for the emitted JSON
    pub fn indent(mut self, indent: usize) -> AsPrettyJson<'a, T> {
        self.indent = Some(indent);
        self
    }
}

impl<'a, T: Encodable> fmt::Display for AsPrettyJson<'a, T> {
    /// Encodes a json value into a string
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut shim = FormatShim { inner: f };
        let mut encoder = PrettyEncoder::new(&mut shim);
        if let Some(n) = self.indent {
            encoder.set_indent(n);
        }
        match self.inner.encode(&mut encoder) {
            Ok(_) => Ok(()),
            Err(_) => Err(fmt::Error)
        }
    }
}

impl FromStr for Json {
    type Err = BuilderError;
    fn from_str(s: &str) -> Result<Json, BuilderError> {
        from_str(s)
    }
}

#[cfg(test)]
mod tests;
