// Written in the D programming language.

/**
Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files.
It's easy for humans to read and write, and it's easy for machines to parse and generate.

$(RED Warning: While $(LREF JSONValue) is fine for small-scale use, at the range of hundreds of megabytes it is
known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See
also $(LINK https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org).)

Copyright: Copyright Jeremie Pelletier 2008 - 2009.
License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors:   Jeremie Pelletier, David Herberth
References: $(LINK http://json.org/), $(LINK http://seriot.ch/parsing_json.html)
Source:    $(PHOBOSSRC std/json.d)
*/
/*
         Copyright Jeremie Pelletier 2008 - 2009.
Distributed under the Boost Software License, Version 1.0.
   (See accompanying file LICENSE_1_0.txt or copy at
         http://www.boost.org/LICENSE_1_0.txt)
*/
module std.json;

import std.array;
import std.conv;
import std.range;
import std.traits;

///
@system unittest
{
    import std.conv : to;

    // parse a file or string of json into a usable structure
    string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
    JSONValue j = parseJSON(s);
    // j and j["language"] return JSONValue,
    // j["language"].str returns a string
    assert(j["language"].str == "D");
    assert(j["rating"].floating == 3.5);

    // check a type
    long x;
    if (const(JSONValue)* code = "code" in j)
    {
        if (code.type() == JSONType.integer)
            x = code.integer;
        else
            x = to!int(code.str);
    }

    // create a json struct
    JSONValue jj = [ "language": "D" ];
    // rating doesnt exist yet, so use .object to assign
    jj.object["rating"] = JSONValue(3.5);
    // create an array to assign to list
    jj.object["list"] = JSONValue( ["a", "b", "c"] );
    // list already exists, so .object optional
    jj["list"].array ~= JSONValue("D");

    string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
    assert(jj.toString == jjStr);
}

/**
String literals used to represent special float values within JSON strings.
*/
enum JSONFloatLiteral : string
{
    nan         = "NaN",       /// String representation of floating-point NaN
    inf         = "Infinite",  /// String representation of floating-point Infinity
    negativeInf = "-Infinite", /// String representation of floating-point negative Infinity
}

/**
Flags that control how JSON is encoded and parsed.
*/
enum JSONOptions
{
    none,                       /// Standard parsing and encoding
    specialFloatLiterals = 0x1, /// Encode NaN and Inf float values as strings
    escapeNonAsciiChars = 0x2,  /// Encode non-ASCII characters with a Unicode escape sequence
    doNotEscapeSlashes = 0x4,   /// Do not escape slashes ('/')
    strictParsing = 0x8,        /// Strictly follow RFC-8259 grammar when parsing
}

/**
Enumeration of JSON types
*/
enum JSONType : byte
{
    /// Indicates the type of a `JSONValue`.
    null_,
    string,   /// ditto
    integer,  /// ditto
    uinteger, /// ditto
    float_,   /// ditto
    array,    /// ditto
    object,   /// ditto
    true_,    /// ditto
    false_,   /// ditto
    // FIXME: Find some way to deprecate the enum members below, which does NOT
    // create lots of spam-like deprecation warnings, which can't be fixed
    // by the user. See discussion on this issue at
    // https://forum.dlang.org/post/feudrhtxkaxxscwhhhff@forum.dlang.org
    /* deprecated("Use .null_")    */ NULL = null_,
    /* deprecated("Use .string")   */ STRING = string,
    /* deprecated("Use .integer")  */ INTEGER = integer,
    /* deprecated("Use .uinteger") */ UINTEGER = uinteger,
    /* deprecated("Use .float_")   */ FLOAT = float_,
    /* deprecated("Use .array")    */ ARRAY = array,
    /* deprecated("Use .object")   */ OBJECT = object,
    /* deprecated("Use .true_")    */ TRUE = true_,
    /* deprecated("Use .false_")   */ FALSE = false_,
}

deprecated("Use JSONType and the new enum member names") alias JSON_TYPE = JSONType;

/**
JSON value node
*/
struct JSONValue
{
    import std.exception : enforce;

    union Store
    {
        string                          str;
        long                            integer;
        ulong                           uinteger;
        double                          floating;
        JSONValue[string]               object;
        JSONValue[]                     array;
    }
    private Store store;
    private JSONType type_tag;

    /**
      Returns the JSONType of the value stored in this structure.
    */
    @property JSONType type() const pure nothrow @safe @nogc
    {
        return type_tag;
    }
    ///
    @safe unittest
    {
          string s = "{ \"language\": \"D\" }";
          JSONValue j = parseJSON(s);
          assert(j.type == JSONType.object);
          assert(j["language"].type == JSONType.string);
    }

    /***
     * Value getter/setter for `JSONType.string`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.string`.
     */
    @property string str() const pure @trusted return scope
    {
        enforce!JSONException(type == JSONType.string,
                                "JSONValue is not a string");
        return store.str;
    }
    /// ditto
    @property string str(return scope string v) pure nothrow @nogc @trusted return // TODO make @safe
    {
        assign(v);
        return v;
    }
    ///
    @safe unittest
    {
        JSONValue j = [ "language": "D" ];

        // get value
        assert(j["language"].str == "D");

        // change existing key to new string
        j["language"].str = "Perl";
        assert(j["language"].str == "Perl");
    }

    /***
     * Value getter/setter for `JSONType.integer`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.integer`.
     */
    @property long integer() const pure @safe
    {
        enforce!JSONException(type == JSONType.integer,
                                "JSONValue is not an integer");
        return store.integer;
    }
    /// ditto
    @property long integer(long v) pure nothrow @safe @nogc
    {
        assign(v);
        return store.integer;
    }

    /***
     * Value getter/setter for `JSONType.uinteger`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.uinteger`.
     */
    @property ulong uinteger() const pure @safe
    {
        enforce!JSONException(type == JSONType.uinteger,
                                "JSONValue is not an unsigned integer");
        return store.uinteger;
    }
    /// ditto
    @property ulong uinteger(ulong v) pure nothrow @safe @nogc
    {
        assign(v);
        return store.uinteger;
    }

    /***
     * Value getter/setter for `JSONType.float_`. Note that despite
     * the name, this is a $(B 64)-bit `double`, not a 32-bit `float`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.float_`.
     */
    @property double floating() const pure @safe
    {
        enforce!JSONException(type == JSONType.float_,
                                "JSONValue is not a floating type");
        return store.floating;
    }
    /// ditto
    @property double floating(double v) pure nothrow @safe @nogc
    {
        assign(v);
        return store.floating;
    }

    /***
     * Value getter/setter for boolean stored in JSON.
     * Throws: `JSONException` for read access if `this.type` is not
     * `JSONType.true_` or `JSONType.false_`.
     */
    @property bool boolean() const pure @safe
    {
        if (type == JSONType.true_) return true;
        if (type == JSONType.false_) return false;

        throw new JSONException("JSONValue is not a boolean type");
    }
    /// ditto
    @property bool boolean(bool v) pure nothrow @safe @nogc
    {
        assign(v);
        return v;
    }
    ///
    @safe unittest
    {
        JSONValue j = true;
        assert(j.boolean == true);

        j.boolean = false;
        assert(j.boolean == false);

        j.integer = 12;
        import std.exception : assertThrown;
        assertThrown!JSONException(j.boolean);
    }

    /***
     * Value getter/setter for `JSONType.object`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.object`.
     * Note: This is @system because of the following pattern:
       ---
       auto a = &(json.object());
       json.uinteger = 0;        // overwrite AA pointer
       (*a)["hello"] = "world";  // segmentation fault
       ---
     */
    @property ref inout(JSONValue[string]) object() inout pure @system return
    {
        enforce!JSONException(type == JSONType.object,
                                "JSONValue is not an object");
        return store.object;
    }
    /// ditto
    @property JSONValue[string] object(return scope JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe
    {
        assign(v);
        return v;
    }

    /***
     * Value getter for `JSONType.object`.
     * Unlike `object`, this retrieves the object by value
     * and can be used in @safe code.
     *
     * One possible caveat is that, if the returned value is null,
     * modifications will not be visible:
     * ---
     * JSONValue json;
     * json.object = null;
     * json.objectNoRef["hello"] = JSONValue("world");
     * assert("hello" !in json.object);
     * ---
     *
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.object`.
     */
    @property inout(JSONValue[string]) objectNoRef() inout pure @trusted
    {
        enforce!JSONException(type == JSONType.object,
                                "JSONValue is not an object");
        return store.object;
    }

    /***
     * Value getter/setter for `JSONType.array`.
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.array`.
     * Note: This is @system because of the following pattern:
       ---
       auto a = &(json.array());
       json.uinteger = 0;  // overwrite array pointer
       (*a)[0] = "world";  // segmentation fault
       ---
     */
    @property ref inout(JSONValue[]) array() scope return inout pure @system
    {
        enforce!JSONException(type == JSONType.array,
                                "JSONValue is not an array");
        return store.array;
    }
    /// ditto
    @property JSONValue[] array(return scope JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe
    {
        assign(v);
        return v;
    }

    /***
     * Value getter for `JSONType.array`.
     * Unlike `array`, this retrieves the array by value and can be used in @safe code.
     *
     * One possible caveat is that, if you append to the returned array,
     * the new values aren't visible in the `JSONValue`:
     * ---
     * JSONValue json;
     * json.array = [JSONValue("hello")];
     * json.arrayNoRef ~= JSONValue("world");
     * assert(json.array.length == 1);
     * ---
     *
     * Throws: `JSONException` for read access if `type` is not
     * `JSONType.array`.
     */
    @property inout(JSONValue[]) arrayNoRef() inout pure @trusted
    {
        enforce!JSONException(type == JSONType.array,
                                "JSONValue is not an array");
        return store.array;
    }

    /// Test whether the type is `JSONType.null_`
    @property bool isNull() const pure nothrow @safe @nogc
    {
        return type == JSONType.null_;
    }

    /***
     * A convenience getter that returns this `JSONValue` as the specified D type.
     * Note: Only numeric types, `bool`, `string`, `JSONValue[string]`, and `JSONValue[]` types are accepted
     * Throws: `JSONException` if `T` cannot hold the contents of this `JSONValue`
     *         `ConvException` in case of integer overflow when converting to `T`
     */
    @property inout(T) get(T)() inout const pure @safe
    {
        static if (is(immutable T == immutable string))
        {
            return str;
        }
        else static if (is(immutable T == immutable bool))
        {
            return boolean;
        }
        else static if (isFloatingPoint!T)
        {
            switch (type)
            {
            case JSONType.float_:
                return cast(T) floating;
            case JSONType.uinteger:
                return cast(T) uinteger;
            case JSONType.integer:
                return cast(T) integer;
            default:
                throw new JSONException("JSONValue is not a number type");
            }
        }
        else static if (isIntegral!T)
        {
            switch (type)
            {
            case JSONType.uinteger:
                return uinteger.to!T;
            case JSONType.integer:
                return integer.to!T;
            default:
                throw new JSONException("JSONValue is not a an integral type");
            }
        }
        else
        {
            static assert(false, "Unsupported type");
        }
    }
    // This specialization is needed because arrayNoRef requires inout
    @property inout(T) get(T : JSONValue[])() inout pure @trusted /// ditto
    {
        return arrayNoRef;
    }
    /// ditto
    @property inout(T) get(T : JSONValue[string])() inout pure @trusted
    {
        return object;
    }
    ///
    @safe unittest
    {
        import std.exception;
        import std.conv;
        string s =
        `{
            "a": 123,
            "b": 3.1415,
            "c": "text",
            "d": true,
            "e": [1, 2, 3],
            "f": { "a": 1 },
            "g": -45,
            "h": ` ~ ulong.max.to!string ~ `,
         }`;

        struct a { }

        immutable json = parseJSON(s);
        assert(json["a"].get!double == 123.0);
        assert(json["a"].get!int == 123);
        assert(json["a"].get!uint == 123);
        assert(json["b"].get!double == 3.1415);
        assertThrown!JSONException(json["b"].get!int);
        assert(json["c"].get!string == "text");
        assert(json["d"].get!bool == true);
        assertNotThrown(json["e"].get!(JSONValue[]));
        assertNotThrown(json["f"].get!(JSONValue[string]));
        static assert(!__traits(compiles, json["a"].get!a));
        assertThrown!JSONException(json["e"].get!float);
        assertThrown!JSONException(json["d"].get!(JSONValue[string]));
        assertThrown!JSONException(json["f"].get!(JSONValue[]));
        assert(json["g"].get!int == -45);
        assertThrown!ConvException(json["g"].get!uint);
        assert(json["h"].get!ulong == ulong.max);
        assertThrown!ConvException(json["h"].get!uint);
        assertNotThrown(json["h"].get!float);
    }

    private void assign(T)(T arg)
    {
        static if (is(T : typeof(null)))
        {
            type_tag = JSONType.null_;
        }
        else static if (is(T : string))
        {
            type_tag = JSONType.string;
            string t = arg;
            () @trusted { store.str = t; }();
        }
        // https://issues.dlang.org/show_bug.cgi?id=15884
        else static if (isSomeString!T)
        {
            type_tag = JSONType.string;
            // FIXME: std.Array.Array(Range) is not deduced as 'pure'
            () @trusted {
                import std.utf : byUTF;
                store.str = cast(immutable)(arg.byUTF!char.array);
            }();
        }
        else static if (is(T : bool))
        {
            type_tag = arg ? JSONType.true_ : JSONType.false_;
        }
        else static if (is(T : ulong) && isUnsigned!T)
        {
            type_tag = JSONType.uinteger;
            store.uinteger = arg;
        }
        else static if (is(T : long))
        {
            type_tag = JSONType.integer;
            store.integer = arg;
        }
        else static if (isFloatingPoint!T)
        {
            type_tag = JSONType.float_;
            store.floating = arg;
        }
        else static if (is(T : Value[Key], Key, Value))
        {
            static assert(is(Key : string), "AA key must be string");
            type_tag = JSONType.object;
            static if (is(Value : JSONValue))
            {
                JSONValue[string] t = arg;
                () @trusted { store.object = t; }();
            }
            else
            {
                JSONValue[string] aa;
                foreach (key, value; arg)
                    aa[key] = JSONValue(value);
                () @trusted { store.object = aa; }();
            }
        }
        else static if (isArray!T)
        {
            type_tag = JSONType.array;
            static if (is(ElementEncodingType!T : JSONValue))
            {
                JSONValue[] t = arg;
                () @trusted { store.array = t; }();
            }
            else
            {
                JSONValue[] new_arg = new JSONValue[arg.length];
                foreach (i, e; arg)
                    new_arg[i] = JSONValue(e);
                () @trusted { store.array = new_arg; }();
            }
        }
        else static if (is(T : JSONValue))
        {
            type_tag = arg.type;
            store = arg.store;
        }
        else
        {
            static assert(false, text(`unable to convert type "`, T.stringof, `" to json`));
        }
    }

    private void assignRef(T)(ref T arg) if (isStaticArray!T)
    {
        type_tag = JSONType.array;
        static if (is(ElementEncodingType!T : JSONValue))
        {
            store.array = arg;
        }
        else
        {
            JSONValue[] new_arg = new JSONValue[arg.length];
            foreach (i, e; arg)
                new_arg[i] = JSONValue(e);
            store.array = new_arg;
        }
    }

    /**
     * Constructor for `JSONValue`. If `arg` is a `JSONValue`
     * its value and type will be copied to the new `JSONValue`.
     * Note that this is a shallow copy: if type is `JSONType.object`
     * or `JSONType.array` then only the reference to the data will
     * be copied.
     * Otherwise, `arg` must be implicitly convertible to one of the
     * following types: `typeof(null)`, `string`, `ulong`,
     * `long`, `double`, an associative array `V[K]` for any `V`
     * and `K` i.e. a JSON object, any array or `bool`. The type will
     * be set accordingly.
     */
    this(T)(T arg) if (!isStaticArray!T)
    {
        assign(arg);
    }
    /// Ditto
    this(T)(ref T arg) if (isStaticArray!T)
    {
        assignRef(arg);
    }
    /// Ditto
    this(T : JSONValue)(inout T arg) inout
    {
        store = arg.store;
        type_tag = arg.type;
    }
    ///
    @safe unittest
    {
        JSONValue j = JSONValue( "a string" );
        j = JSONValue(42);

        j = JSONValue( [1, 2, 3] );
        assert(j.type == JSONType.array);

        j = JSONValue( ["language": "D"] );
        assert(j.type == JSONType.object);
    }

    /**
     * An enum value that can be used to obtain a `JSONValue` representing
     * an empty JSON object.
     */
    enum emptyObject = JSONValue(string[string].init);
    ///
    @system unittest
    {
        JSONValue obj1 = JSONValue.emptyObject;
        assert(obj1.type == JSONType.object);
        obj1.object["a"] = JSONValue(1);
        assert(obj1.object["a"] == JSONValue(1));

        JSONValue obj2 = JSONValue.emptyObject;
        assert("a" !in obj2.object);
        obj2.object["b"] = JSONValue(5);
        assert(obj1 != obj2);
    }

    /**
     * An enum value that can be used to obtain a `JSONValue` representing
     * an empty JSON array.
     */
    enum emptyArray = JSONValue(JSONValue[].init);
    ///
    @system unittest
    {
        JSONValue arr1 = JSONValue.emptyArray;
        assert(arr1.type == JSONType.array);
        assert(arr1.array.length == 0);
        arr1.array ~= JSONValue("Hello");
        assert(arr1.array.length == 1);
        assert(arr1.array[0] == JSONValue("Hello"));

        JSONValue arr2 = JSONValue.emptyArray;
        assert(arr2.array.length == 0);
        assert(arr1 != arr2);
    }

    void opAssign(T)(T arg) if (!isStaticArray!T && !is(T : JSONValue))
    {
        assign(arg);
    }

    void opAssign(T)(ref T arg) if (isStaticArray!T)
    {
        assignRef(arg);
    }

    /***
     * Array syntax for JSON arrays.
     * Throws: `JSONException` if `type` is not `JSONType.array`.
     */
    ref inout(JSONValue) opIndex(size_t i) inout pure @safe
    {
        auto a = this.arrayNoRef;
        enforce!JSONException(i < a.length,
                                "JSONValue array index is out of range");
        return a[i];
    }
    ///
    @safe unittest
    {
        JSONValue j = JSONValue( [42, 43, 44] );
        assert( j[0].integer == 42 );
        assert( j[1].integer == 43 );
    }

    /***
     * Hash syntax for JSON objects.
     * Throws: `JSONException` if `type` is not `JSONType.object`.
     */
    ref inout(JSONValue) opIndex(return scope string k) inout pure @safe
    {
        auto o = this.objectNoRef;
        return *enforce!JSONException(k in o,
                                        "Key not found: " ~ k);
    }
    ///
    @safe unittest
    {
        JSONValue j = JSONValue( ["language": "D"] );
        assert( j["language"].str == "D" );
    }

    /***
     * Provides support for index assignments, which sets the
     * corresponding value of the JSON object's `key` field to `value`.
     *
     * If the `JSONValue` is `JSONType.null_`, then this function
     * initializes it with a JSON object and then performs
     * the index assignment.
     *
     * Throws: `JSONException` if `type` is not `JSONType.object`
     * or `JSONType.null_`.
     */
    void opIndexAssign(T)(auto ref T value, string key)
    {
        enforce!JSONException(type == JSONType.object || type == JSONType.null_,
                                "JSONValue must be object or null");
        JSONValue[string] aa = null;
        if (type == JSONType.object)
        {
            aa = this.objectNoRef;
        }

        aa[key] = value;
        this.object = aa;
    }
    ///
    @safe unittest
    {
            JSONValue j = JSONValue( ["language": "D"] );
            j["language"].str = "Perl";
            assert( j["language"].str == "Perl" );
    }

    /// ditto
    void opIndexAssign(T)(T arg, size_t i)
    {
        auto a = this.arrayNoRef;
        enforce!JSONException(i < a.length,
                                "JSONValue array index is out of range");
        a[i] = arg;
        this.array = a;
    }
    ///
    @safe unittest
    {
            JSONValue j = JSONValue( ["Perl", "C"] );
            j[1].str = "D";
            assert( j[1].str == "D" );
    }

    JSONValue opBinary(string op : "~", T)(T arg)
    {
        auto a = this.arrayNoRef;
        static if (isArray!T)
        {
            return JSONValue(a ~ JSONValue(arg).arrayNoRef);
        }
        else static if (is(T : JSONValue))
        {
            return JSONValue(a ~ arg.arrayNoRef);
        }
        else
        {
            static assert(false, "argument is not an array or a JSONValue array");
        }
    }

    void opOpAssign(string op : "~", T)(T arg)
    {
        auto a = this.arrayNoRef;
        static if (isArray!T)
        {
            a ~= JSONValue(arg).arrayNoRef;
        }
        else static if (is(T : JSONValue))
        {
            a ~= arg.arrayNoRef;
        }
        else
        {
            static assert(false, "argument is not an array or a JSONValue array");
        }
        this.array = a;
    }

    /**
     * Provides support for the `in` operator.
     *
     * Tests whether a key can be found in an object.
     *
     * Returns:
     *      When found, the `inout(JSONValue)*` that matches to the key,
     *      otherwise `null`.
     *
     * Throws: `JSONException` if the right hand side argument `JSONType`
     * is not `object`.
     */
    inout(JSONValue)* opBinaryRight(string op : "in")(string k) inout @safe
    {
        return k in this.objectNoRef;
    }
    ///
    @safe unittest
    {
        JSONValue j = [ "language": "D", "author": "walter" ];
        string a = ("author" in j).str;
        *("author" in j) = "Walter";
        assert(j["author"].str == "Walter");
    }

    ///
    bool opEquals(const JSONValue rhs) const @nogc nothrow pure @safe
    {
        return opEquals(rhs);
    }

    /// ditto
    bool opEquals(ref const JSONValue rhs) const @nogc nothrow pure @trusted
    {
        // Default doesn't work well since store is a union.  Compare only
        // what should be in store.
        // This is @trusted to remain nogc, nothrow, fast, and usable from @safe code.

        final switch (type_tag)
        {
        case JSONType.integer:
            switch (rhs.type_tag)
            {
                case JSONType.integer:
                    return store.integer == rhs.store.integer;
                case JSONType.uinteger:
                    return store.integer == rhs.store.uinteger;
                case JSONType.float_:
                    return store.integer == rhs.store.floating;
                default:
                    return false;
            }
        case JSONType.uinteger:
            switch (rhs.type_tag)
            {
                case JSONType.integer:
                    return store.uinteger == rhs.store.integer;
                case JSONType.uinteger:
                    return store.uinteger == rhs.store.uinteger;
                case JSONType.float_:
                    return store.uinteger == rhs.store.floating;
                default:
                    return false;
            }
        case JSONType.float_:
            switch (rhs.type_tag)
            {
                case JSONType.integer:
                    return store.floating == rhs.store.integer;
                case JSONType.uinteger:
                    return store.floating == rhs.store.uinteger;
                case JSONType.float_:
                    return store.floating == rhs.store.floating;
                default:
                    return false;
            }
        case JSONType.string:
            return type_tag == rhs.type_tag && store.str == rhs.store.str;
        case JSONType.object:
            return type_tag == rhs.type_tag && store.object == rhs.store.object;
        case JSONType.array:
            return type_tag == rhs.type_tag && store.array == rhs.store.array;
        case JSONType.true_:
        case JSONType.false_:
        case JSONType.null_:
            return type_tag == rhs.type_tag;
        }
    }

    ///
    @safe unittest
    {
        assert(JSONValue(0u) == JSONValue(0));
        assert(JSONValue(0u) == JSONValue(0.0));
        assert(JSONValue(0) == JSONValue(0.0));
    }

    /// Implements the foreach `opApply` interface for json arrays.
    int opApply(scope int delegate(size_t index, ref JSONValue) dg) @system
    {
        int result;

        foreach (size_t index, ref value; array)
        {
            result = dg(index, value);
            if (result)
                break;
        }

        return result;
    }

    /// Implements the foreach `opApply` interface for json objects.
    int opApply(scope int delegate(string key, ref JSONValue) dg) @system
    {
        enforce!JSONException(type == JSONType.object,
                                "JSONValue is not an object");
        int result;

        foreach (string key, ref value; object)
        {
            result = dg(key, value);
            if (result)
                break;
        }

        return result;
    }

    /***
     * Implicitly calls `toJSON` on this JSONValue.
     *
     * $(I options) can be used to tweak the conversion behavior.
     */
    string toString(in JSONOptions options = JSONOptions.none) const @safe
    {
        return toJSON(this, false, options);
    }

    ///
    void toString(Out)(Out sink, in JSONOptions options = JSONOptions.none) const
    {
        toJSON(sink, this, false, options);
    }

    /***
     * Implicitly calls `toJSON` on this JSONValue, like `toString`, but
     * also passes $(I true) as $(I pretty) argument.
     *
     * $(I options) can be used to tweak the conversion behavior
     */
    string toPrettyString(in JSONOptions options = JSONOptions.none) const @safe
    {
        return toJSON(this, true, options);
    }

    ///
    void toPrettyString(Out)(Out sink, in JSONOptions options = JSONOptions.none) const
    {
        toJSON(sink, this, true, options);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=20874
@system unittest
{
    static struct MyCustomType
    {
        public string toString () const @system { return null; }
        alias toString this;
    }

    static struct B
    {
        public JSONValue asJSON() const @system { return JSONValue.init; }
        alias asJSON this;
    }

    if (false) // Just checking attributes
    {
        JSONValue json;
        MyCustomType ilovedlang;
        json = ilovedlang;
        json["foo"] = ilovedlang;
        auto s = ilovedlang in json;

        B b;
        json ~= b;
        json ~ b;
    }
}

/**
Parses a serialized string and returns a tree of JSON values.
Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth,
        $(LREF ConvException) if a number in the input cannot be represented by a native D type.
Params:
    json = json-formatted string to parse
    maxDepth = maximum depth of nesting allowed, -1 disables depth checking
    options = enable decoding string representations of NaN/Inf as float values
*/
JSONValue parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none)
if (isSomeFiniteCharInputRange!T)
{
    import std.ascii : isDigit, isHexDigit, toUpper, toLower;
    import std.typecons : Nullable, Yes;
    JSONValue root;
    root.type_tag = JSONType.null_;

    // Avoid UTF decoding when possible, as it is unnecessary when
    // processing JSON.
    static if (is(T : const(char)[]))
        alias Char = char;
    else
        alias Char = Unqual!(ElementType!T);

    int depth = -1;
    Nullable!Char next;
    int line = 1, pos = 0;
    immutable bool strict = (options & JSONOptions.strictParsing) != 0;

    void error(string msg)
    {
        throw new JSONException(msg, line, pos);
    }

    if (json.empty)
    {
        if (strict)
        {
            error("Empty JSON body");
        }
        return root;
    }

    bool isWhite(dchar c)
    {
        if (strict)
        {
            // RFC 7159 has a stricter definition of whitespace than general ASCII.
            return c == ' ' || c == '\t' || c == '\n' || c == '\r';
        }
        import std.ascii : isWhite;
        // Accept ASCII NUL as whitespace in non-strict mode.
        return c == 0 || isWhite(c);
    }

    Char popChar()
    {
        if (json.empty) error("Unexpected end of data.");
        static if (is(T : const(char)[]))
        {
            Char c = json[0];
            json = json[1..$];
        }
        else
        {
            Char c = json.front;
            json.popFront();
        }

        if (c == '\n')
        {
            line++;
            pos = 0;
        }
        else
        {
            pos++;
        }

        return c;
    }

    Char peekChar()
    {
        if (next.isNull)
        {
            if (json.empty) return '\0';
            next = popChar();
        }
        return next.get;
    }

    Nullable!Char peekCharNullable()
    {
        if (next.isNull && !json.empty)
        {
            next = popChar();
        }
        return next;
    }

    void skipWhitespace()
    {
        while (true)
        {
            auto c = peekCharNullable();
            if (c.isNull ||
                !isWhite(c.get))
            {
                return;
            }
            next.nullify();
        }
    }

    Char getChar(bool SkipWhitespace = false)()
    {
        static if (SkipWhitespace) skipWhitespace();

        Char c;
        if (!next.isNull)
        {
            c = next.get;
            next.nullify();
        }
        else
            c = popChar();

        return c;
    }

    void checkChar(bool SkipWhitespace = true)(char c, bool caseSensitive = true)
    {
        static if (SkipWhitespace) skipWhitespace();
        auto c2 = getChar();
        if (!caseSensitive) c2 = toLower(c2);

        if (c2 != c) error(text("Found '", c2, "' when expecting '", c, "'."));
    }

    bool testChar(bool SkipWhitespace = true, bool CaseSensitive = true)(char c)
    {
        static if (SkipWhitespace) skipWhitespace();
        auto c2 = peekChar();
        static if (!CaseSensitive) c2 = toLower(c2);

        if (c2 != c) return false;

        getChar();
        return true;
    }

    wchar parseWChar()
    {
        wchar val = 0;
        foreach_reverse (i; 0 .. 4)
        {
            auto hex = toUpper(getChar());
            if (!isHexDigit(hex)) error("Expecting hex character");
            val += (isDigit(hex) ? hex - '0' : hex - ('A' - 10)) << (4 * i);
        }
        return val;
    }

    string parseString()
    {
        import std.uni : isSurrogateHi, isSurrogateLo;
        import std.utf : encode, decode;

        auto str = appender!string();

    Next:
        switch (peekChar())
        {
            case '"':
                getChar();
                break;

            case '\\':
                getChar();
                auto c = getChar();
                switch (c)
                {
                    case '"':       str.put('"');   break;
                    case '\\':      str.put('\\');  break;
                    case '/':       str.put('/');   break;
                    case 'b':       str.put('\b');  break;
                    case 'f':       str.put('\f');  break;
                    case 'n':       str.put('\n');  break;
                    case 'r':       str.put('\r');  break;
                    case 't':       str.put('\t');  break;
                    case 'u':
                        wchar wc = parseWChar();
                        dchar val;
                        // Non-BMP characters are escaped as a pair of
                        // UTF-16 surrogate characters (see RFC 4627).
                        if (isSurrogateHi(wc))
                        {
                            wchar[2] pair;
                            pair[0] = wc;
                            if (getChar() != '\\') error("Expected escaped low surrogate after escaped high surrogate");
                            if (getChar() != 'u') error("Expected escaped low surrogate after escaped high surrogate");
                            pair[1] = parseWChar();
                            size_t index = 0;
                            val = decode(pair[], index);
                            if (index != 2) error("Invalid escaped surrogate pair");
                        }
                        else
                        if (isSurrogateLo(wc))
                            error(text("Unexpected low surrogate"));
                        else
                            val = wc;

                        char[4] buf;
                        immutable len = encode!(Yes.useReplacementDchar)(buf, val);
                        str.put(buf[0 .. len]);
                        break;

                    default:
                        error(text("Invalid escape sequence '\\", c, "'."));
                }
                goto Next;

            default:
                // RFC 7159 states that control characters U+0000 through
                // U+001F must not appear unescaped in a JSON string.
                // Note: std.ascii.isControl can't be used for this test
                // because it considers ASCII DEL (0x7f) to be a control
                // character but RFC 7159 does not.
                // Accept unescaped ASCII NULs in non-strict mode.
                auto c = getChar();
                if (c < 0x20 && (strict || c != 0))
                    error("Illegal control character.");
                str.put(c);
                goto Next;
        }

        return str.data.length ? str.data : "";
    }

    bool tryGetSpecialFloat(string str, out double val) {
        switch (str)
        {
            case JSONFloatLiteral.nan:
                val = double.nan;
                return true;
            case JSONFloatLiteral.inf:
                val = double.infinity;
                return true;
            case JSONFloatLiteral.negativeInf:
                val = -double.infinity;
                return true;
            default:
                return false;
        }
    }

    void parseValue(ref JSONValue value)
    {
        depth++;

        if (maxDepth != -1 && depth > maxDepth) error("Nesting too deep.");

        auto c = getChar!true();

        switch (c)
        {
            case '{':
                if (testChar('}'))
                {
                    value.object = null;
                    break;
                }

                JSONValue[string] obj;
                do
                {
                    skipWhitespace();
                    if (!strict && peekChar() == '}')
                    {
                        break;
                    }
                    checkChar('"');
                    string name = parseString();
                    checkChar(':');
                    JSONValue member;
                    parseValue(member);
                    obj[name] = member;
                }
                while (testChar(','));
                value.object = obj;

                checkChar('}');
                break;

            case '[':
                if (testChar(']'))
                {
                    value.type_tag = JSONType.array;
                    break;
                }

                JSONValue[] arr;
                do
                {
                    skipWhitespace();
                    if (!strict && peekChar() == ']')
                    {
                        break;
                    }
                    JSONValue element;
                    parseValue(element);
                    arr ~= element;
                }
                while (testChar(','));

                checkChar(']');
                value.array = arr;
                break;

            case '"':
                auto str = parseString();

                // if special float parsing is enabled, check if string represents NaN/Inf
                if ((options & JSONOptions.specialFloatLiterals) &&
                    tryGetSpecialFloat(str, value.store.floating))
                {
                    // found a special float, its value was placed in value.store.floating
                    value.type_tag = JSONType.float_;
                    break;
                }

                value.assign(str);
                break;

            case '0': .. case '9':
            case '-':
                auto number = appender!string();
                bool isFloat, isNegative;

                void readInteger()
                {
                    if (!isDigit(c)) error("Digit expected");

                Next: number.put(c);

                    if (isDigit(peekChar()))
                    {
                        c = getChar();
                        goto Next;
                    }
                }

                if (c == '-')
                {
                    number.put('-');
                    c = getChar();
                    isNegative = true;
                }

                if (strict && c == '0')
                {
                    number.put('0');
                    if (isDigit(peekChar()))
                    {
                        error("Additional digits not allowed after initial zero digit");
                    }
                }
                else
                {
                    readInteger();
                }

                if (testChar('.'))
                {
                    isFloat = true;
                    number.put('.');
                    c = getChar();
                    readInteger();
                }
                if (testChar!(false, false)('e'))
                {
                    isFloat = true;
                    number.put('e');
                    if (testChar('+')) number.put('+');
                    else if (testChar('-')) number.put('-');
                    c = getChar();
                    readInteger();
                }

                string data = number.data;
                if (isFloat)
                {
                    value.type_tag = JSONType.float_;
                    value.store.floating = parse!double(data);
                }
                else
                {
                    if (isNegative)
                    {
                        value.store.integer = parse!long(data);
                        value.type_tag = JSONType.integer;
                    }
                    else
                    {
                        // only set the correct union member to not confuse CTFE
                        ulong u = parse!ulong(data);
                        if (u & (1UL << 63))
                        {
                            value.store.uinteger = u;
                            value.type_tag = JSONType.uinteger;
                        }
                        else
                        {
                            value.store.integer = u;
                            value.type_tag = JSONType.integer;
                        }
                    }
                }
                break;

            case 'T':
                if (strict) goto default;
                goto case;
            case 't':
                value.type_tag = JSONType.true_;
                checkChar!false('r', strict);
                checkChar!false('u', strict);
                checkChar!false('e', strict);
                break;

            case 'F':
                if (strict) goto default;
                goto case;
            case 'f':
                value.type_tag = JSONType.false_;
                checkChar!false('a', strict);
                checkChar!false('l', strict);
                checkChar!false('s', strict);
                checkChar!false('e', strict);
                break;

            case 'N':
                if (strict) goto default;
                goto case;
            case 'n':
                value.type_tag = JSONType.null_;
                checkChar!false('u', strict);
                checkChar!false('l', strict);
                checkChar!false('l', strict);
                break;

            default:
                error(text("Unexpected character '", c, "'."));
        }

        depth--;
    }

    parseValue(root);
    if (strict)
    {
        skipWhitespace();
        if (!peekCharNullable().isNull) error("Trailing non-whitespace characters");
    }
    return root;
}

@safe unittest
{
    enum issue15742objectOfObject = `{ "key1": { "key2": 1 }}`;
    static assert(parseJSON(issue15742objectOfObject).type == JSONType.object);

    enum issue15742arrayOfArray = `[[1]]`;
    static assert(parseJSON(issue15742arrayOfArray).type == JSONType.array);
}

@safe unittest
{
    // Ensure we can parse and use JSON from @safe code
    auto a = `{ "key1": { "key2": 1 }}`.parseJSON;
    assert(a["key1"]["key2"].integer == 1);
    assert(a.toString == `{"key1":{"key2":1}}`);
}

@system unittest
{
    // Ensure we can parse JSON from a @system range.
    struct Range
    {
        string s;
        size_t index;
        @system
        {
            bool empty() { return index >= s.length; }
            void popFront() { index++; }
            char front() { return s[index]; }
        }
    }
    auto s = Range(`{ "key1": { "key2": 1 }}`);
    auto json = parseJSON(s);
    assert(json["key1"]["key2"].integer == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=20527
@safe unittest
{
    static assert(parseJSON(`{"a" : 2}`)["a"].integer == 2);
}

/**
Parses a serialized string and returns a tree of JSON values.
Throws: $(LREF JSONException) if the depth exceeds the max depth.
Params:
    json = json-formatted string to parse
    options = enable decoding string representations of NaN/Inf as float values
*/
JSONValue parseJSON(T)(T json, JSONOptions options)
if (isSomeFiniteCharInputRange!T)
{
    return parseJSON!T(json, -1, options);
}

/**
Takes a tree of JSON values and returns the serialized string.

Any Object types will be serialized in a key-sorted order.

If `pretty` is false no whitespaces are generated.
If `pretty` is true serialized string is formatted to be human-readable.
Set the $(LREF JSONOptions.specialFloatLiterals) flag is set in `options` to encode NaN/Infinity as strings.
*/
string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions options = JSONOptions.none) @safe
{
    auto json = appender!string();
    toJSON(json, root, pretty, options);
    return json.data;
}

///
void toJSON(Out)(
    auto ref Out json,
    const ref JSONValue root,
    in bool pretty = false,
    in JSONOptions options = JSONOptions.none)
if (isOutputRange!(Out,char))
{
    void toStringImpl(Char)(string str)
    {
        json.put('"');

        foreach (Char c; str)
        {
            switch (c)
            {
                case '"':       json.put("\\\"");       break;
                case '\\':      json.put("\\\\");       break;

                case '/':
                    if (!(options & JSONOptions.doNotEscapeSlashes))
                        json.put('\\');
                    json.put('/');
                    break;

                case '\b':      json.put("\\b");        break;
                case '\f':      json.put("\\f");        break;
                case '\n':      json.put("\\n");        break;
                case '\r':      json.put("\\r");        break;
                case '\t':      json.put("\\t");        break;
                default:
                {
                    import std.ascii : isControl;
                    import std.utf : encode;

                    // Make sure we do UTF decoding iff we want to
                    // escape Unicode characters.
                    assert(((options & JSONOptions.escapeNonAsciiChars) != 0)
                        == is(Char == dchar), "JSONOptions.escapeNonAsciiChars needs dchar strings");

                    with (JSONOptions) if (isControl(c) ||
                        ((options & escapeNonAsciiChars) >= escapeNonAsciiChars && c >= 0x80))
                    {
                        // Ensure non-BMP characters are encoded as a pair
                        // of UTF-16 surrogate characters, as per RFC 4627.
                        wchar[2] wchars; // 1 or 2 UTF-16 code units
                        size_t wNum = encode(wchars, c); // number of UTF-16 code units
                        foreach (wc; wchars[0 .. wNum])
                        {
                            json.put("\\u");
                            foreach_reverse (i; 0 .. 4)
                            {
                                char ch = (wc >>> (4 * i)) & 0x0f;
                                ch += ch < 10 ? '0' : 'A' - 10;
                                json.put(ch);
                            }
                        }
                    }
                    else
                    {
                        json.put(c);
                    }
                }
            }
        }

        json.put('"');
    }

    void toString(string str)
    {
        // Avoid UTF decoding when possible, as it is unnecessary when
        // processing JSON.
        if (options & JSONOptions.escapeNonAsciiChars)
            toStringImpl!dchar(str);
        else
            toStringImpl!char(str);
    }

    /* make the function infer @system when json.put() is @system
     */
    if (0)
        json.put(' ');

    /* Mark as @trusted because json.put() may be @system. This has difficulty
     * inferring @safe because it is recursive.
     */
    void toValueImpl(ref const JSONValue value, ulong indentLevel) @trusted
    {
        void putTabs(ulong additionalIndent = 0)
        {
            if (pretty)
                foreach (i; 0 .. indentLevel + additionalIndent)
                    json.put("    ");
        }
        void putEOL()
        {
            if (pretty)
                json.put('\n');
        }
        void putCharAndEOL(char ch)
        {
            json.put(ch);
            putEOL();
        }

        final switch (value.type)
        {
            case JSONType.object:
                auto obj = value.objectNoRef;
                if (!obj.length)
                {
                    json.put("{}");
                }
                else
                {
                    putCharAndEOL('{');
                    bool first = true;

                    void emit(R)(R names)
                    {
                        foreach (name; names)
                        {
                            auto member = obj[name];
                            if (!first)
                                putCharAndEOL(',');
                            first = false;
                            putTabs(1);
                            toString(name);
                            json.put(':');
                            if (pretty)
                                json.put(' ');
                            toValueImpl(member, indentLevel + 1);
                        }
                    }

                    import std.algorithm.sorting : sort;
                    // https://issues.dlang.org/show_bug.cgi?id=14439
                    // auto names = obj.keys;  // aa.keys can't be called in @safe code
                    auto names = new string[obj.length];
                    size_t i = 0;
                    foreach (k, v; obj)
                    {
                        names[i] = k;
                        i++;
                    }
                    sort(names);
                    emit(names);

                    putEOL();
                    putTabs();
                    json.put('}');
                }
                break;

            case JSONType.array:
                auto arr = value.arrayNoRef;
                if (arr.empty)
                {
                    json.put("[]");
                }
                else
                {
                    putCharAndEOL('[');
                    foreach (i, el; arr)
                    {
                        if (i)
                            putCharAndEOL(',');
                        putTabs(1);
                        toValueImpl(el, indentLevel + 1);
                    }
                    putEOL();
                    putTabs();
                    json.put(']');
                }
                break;

            case JSONType.string:
                toString(value.str);
                break;

            case JSONType.integer:
                json.put(to!string(value.store.integer));
                break;

            case JSONType.uinteger:
                json.put(to!string(value.store.uinteger));
                break;

            case JSONType.float_:
                import std.math.traits : isNaN, isInfinity;

                auto val = value.store.floating;

                if (val.isNaN)
                {
                    if (options & JSONOptions.specialFloatLiterals)
                    {
                        toString(JSONFloatLiteral.nan);
                    }
                    else
                    {
                        throw new JSONException(
                            "Cannot encode NaN. Consider passing the specialFloatLiterals flag.");
                    }
                }
                else if (val.isInfinity)
                {
                    if (options & JSONOptions.specialFloatLiterals)
                    {
                        toString((val > 0) ?  JSONFloatLiteral.inf : JSONFloatLiteral.negativeInf);
                    }
                    else
                    {
                        throw new JSONException(
                            "Cannot encode Infinity. Consider passing the specialFloatLiterals flag.");
                    }
                }
                else
                {
                    import std.algorithm.searching : canFind;
                    import std.format : sformat;
                    // The correct formula for the number of decimal digits needed for lossless round
                    // trips is actually:
                    //     ceil(log(pow(2.0, double.mant_dig - 1)) / log(10.0) + 1) == (double.dig + 2)
                    // Anything less will round off (1 + double.epsilon)
                    char[25] buf;
                    auto result = buf[].sformat!"%.18g"(val);
                    json.put(result);
                    if (!result.canFind('e') && !result.canFind('.'))
                        json.put(".0");
                }
                break;

            case JSONType.true_:
                json.put("true");
                break;

            case JSONType.false_:
                json.put("false");
                break;

            case JSONType.null_:
                json.put("null");
                break;
        }
    }

    toValueImpl(root, 0);
}

 // https://issues.dlang.org/show_bug.cgi?id=12897
@safe unittest
{
    JSONValue jv0 = JSONValue("test测试");
    assert(toJSON(jv0, false, JSONOptions.escapeNonAsciiChars) == `"test\u6D4B\u8BD5"`);
    JSONValue jv00 = JSONValue("test\u6D4B\u8BD5");
    assert(toJSON(jv00, false, JSONOptions.none) == `"test测试"`);
    assert(toJSON(jv0, false, JSONOptions.none) == `"test测试"`);
    JSONValue jv1 = JSONValue("été");
    assert(toJSON(jv1, false, JSONOptions.escapeNonAsciiChars) == `"\u00E9t\u00E9"`);
    JSONValue jv11 = JSONValue("\u00E9t\u00E9");
    assert(toJSON(jv11, false, JSONOptions.none) == `"été"`);
    assert(toJSON(jv1, false, JSONOptions.none) == `"été"`);
}

// https://issues.dlang.org/show_bug.cgi?id=20511
@system unittest
{
    import std.format.write : formattedWrite;
    import std.range : nullSink, outputRangeObject;

    outputRangeObject!(const(char)[])(nullSink)
        .formattedWrite!"%s"(JSONValue.init);
}

// Issue 16432 - JSON incorrectly parses to string
@safe unittest
{
    // Floating points numbers are rounded to the nearest integer and thus get
    // incorrectly parsed

    import std.math.operations : isClose;

    string s = "{\"rating\": 3.0 }";
    JSONValue j = parseJSON(s);
    assert(j["rating"].type == JSONType.float_);
    j = j.toString.parseJSON;
    assert(j["rating"].type == JSONType.float_);
    assert(isClose(j["rating"].floating, 3.0));

    s = "{\"rating\": -3.0 }";
    j = parseJSON(s);
    assert(j["rating"].type == JSONType.float_);
    j = j.toString.parseJSON;
    assert(j["rating"].type == JSONType.float_);
    assert(isClose(j["rating"].floating, -3.0));

    // https://issues.dlang.org/show_bug.cgi?id=13660
    auto jv1 = JSONValue(4.0);
    auto textual = jv1.toString();
    auto jv2 = parseJSON(textual);
    assert(jv1.type == JSONType.float_);
    assert(textual == "4.0");
    assert(jv2.type == JSONType.float_);
}

@safe unittest
{
    // Adapted from https://github.com/dlang/phobos/pull/5005
    // Result from toString is not checked here, because this
    // might differ (%e-like or %f-like output) depending
    // on OS and compiler optimization.
    import std.math.operations : isClose;

    // test positive extreme values
    JSONValue j;
    j["rating"] = 1e18 - 65;
    assert(isClose(j.toString.parseJSON["rating"].floating, 1e18 - 65));

    j["rating"] = 1e18 - 64;
    assert(isClose(j.toString.parseJSON["rating"].floating, 1e18 - 64));

    // negative extreme values
    j["rating"] = -1e18 + 65;
    assert(isClose(j.toString.parseJSON["rating"].floating, -1e18 + 65));

    j["rating"] = -1e18 + 64;
    assert(isClose(j.toString.parseJSON["rating"].floating, -1e18 + 64));
}

/**
Exception thrown on JSON errors
*/
class JSONException : Exception
{
    this(string msg, int line = 0, int pos = 0) pure nothrow @safe
    {
        if (line)
            super(text(msg, " (Line ", line, ":", pos, ")"));
        else
            super(msg);
    }

    this(string msg, string file, size_t line) pure nothrow @safe
    {
        super(msg, file, line);
    }
}


@system unittest
{
    import std.exception;
    JSONValue jv = "123";
    assert(jv.type == JSONType.string);
    assertNotThrown(jv.str);
    assertThrown!JSONException(jv.integer);
    assertThrown!JSONException(jv.uinteger);
    assertThrown!JSONException(jv.floating);
    assertThrown!JSONException(jv.object);
    assertThrown!JSONException(jv.array);
    assertThrown!JSONException(jv["aa"]);
    assertThrown!JSONException(jv[2]);

    jv = -3;
    assert(jv.type == JSONType.integer);
    assertNotThrown(jv.integer);

    jv = cast(uint) 3;
    assert(jv.type == JSONType.uinteger);
    assertNotThrown(jv.uinteger);

    jv = 3.0;
    assert(jv.type == JSONType.float_);
    assertNotThrown(jv.floating);

    jv = ["key" : "value"];
    assert(jv.type == JSONType.object);
    assertNotThrown(jv.object);
    assertNotThrown(jv["key"]);
    assert("key" in jv);
    assert("notAnElement" !in jv);
    assertThrown!JSONException(jv["notAnElement"]);
    const cjv = jv;
    assert("key" in cjv);
    assertThrown!JSONException(cjv["notAnElement"]);

    foreach (string key, value; jv)
    {
        static assert(is(typeof(value) == JSONValue));
        assert(key == "key");
        assert(value.type == JSONType.string);
        assertNotThrown(value.str);
        assert(value.str == "value");
    }

    jv = [3, 4, 5];
    assert(jv.type == JSONType.array);
    assertNotThrown(jv.array);
    assertNotThrown(jv[2]);
    foreach (size_t index, value; jv)
    {
        static assert(is(typeof(value) == JSONValue));
        assert(value.type == JSONType.integer);
        assertNotThrown(value.integer);
        assert(index == (value.integer-3));
    }

    jv = null;
    assert(jv.type == JSONType.null_);
    assert(jv.isNull);
    jv = "foo";
    assert(!jv.isNull);

    jv = JSONValue("value");
    assert(jv.type == JSONType.string);
    assert(jv.str == "value");

    JSONValue jv2 = JSONValue("value");
    assert(jv2.type == JSONType.string);
    assert(jv2.str == "value");

    JSONValue jv3 = JSONValue("\u001c");
    assert(jv3.type == JSONType.string);
    assert(jv3.str == "\u001C");
}

// https://issues.dlang.org/show_bug.cgi?id=11504
@system unittest
{
    JSONValue jv = 1;
    assert(jv.type == JSONType.integer);

    jv.str = "123";
    assert(jv.type == JSONType.string);
    assert(jv.str == "123");

    jv.integer = 1;
    assert(jv.type == JSONType.integer);
    assert(jv.integer == 1);

    jv.uinteger = 2u;
    assert(jv.type == JSONType.uinteger);
    assert(jv.uinteger == 2u);

    jv.floating = 1.5;
    assert(jv.type == JSONType.float_);
    assert(jv.floating == 1.5);

    jv.object = ["key" : JSONValue("value")];
    assert(jv.type == JSONType.object);
    assert(jv.object == ["key" : JSONValue("value")]);

    jv.array = [JSONValue(1), JSONValue(2), JSONValue(3)];
    assert(jv.type == JSONType.array);
    assert(jv.array == [JSONValue(1), JSONValue(2), JSONValue(3)]);

    jv = true;
    assert(jv.type == JSONType.true_);

    jv = false;
    assert(jv.type == JSONType.false_);

    enum E{True = true}
    jv = E.True;
    assert(jv.type == JSONType.true_);
}

@system pure unittest
{
    // Adding new json element via array() / object() directly

    JSONValue jarr = JSONValue([10]);
    foreach (i; 0 .. 9)
        jarr.array ~= JSONValue(i);
    assert(jarr.array.length == 10);

    JSONValue jobj = JSONValue(["key" : JSONValue("value")]);
    foreach (i; 0 .. 9)
        jobj.object[text("key", i)] = JSONValue(text("value", i));
    assert(jobj.object.length == 10);
}

@system pure unittest
{
    // Adding new json element without array() / object() access

    JSONValue jarr = JSONValue([10]);
    foreach (i; 0 .. 9)
        jarr ~= [JSONValue(i)];
    assert(jarr.array.length == 10);

    JSONValue jobj = JSONValue(["key" : JSONValue("value")]);
    foreach (i; 0 .. 9)
        jobj[text("key", i)] = JSONValue(text("value", i));
    assert(jobj.object.length == 10);

    // No array alias
    auto jarr2 = jarr ~ [1,2,3];
    jarr2[0] = 999;
    assert(jarr[0] == JSONValue(10));
}

@system unittest
{
    // @system because JSONValue.array is @system
    import std.exception;

    // An overly simple test suite, if it can parse a serializated string and
    // then use the resulting values tree to generate an identical
    // serialization, both the decoder and encoder works.

    auto jsons = [
        `null`,
        `true`,
        `false`,
        `0`,
        `123`,
        `-4321`,
        `0.25`,
        `-0.25`,
        `""`,
        `"hello\nworld"`,
        `"\"\\\/\b\f\n\r\t"`,
        `[]`,
        `[12,"foo",true,false]`,
        `{}`,
        `{"a":1,"b":null}`,
        `{"goodbye":[true,"or",false,["test",42,{"nested":{"a":23.5,"b":0.140625}}]],`
        ~`"hello":{"array":[12,null,{}],"json":"is great"}}`,
    ];

    enum dbl1_844 = `1.8446744073709568`;
    version (MinGW)
        jsons ~= dbl1_844 ~ `e+019`;
    else
        jsons ~= dbl1_844 ~ `e+19`;

    JSONValue val;
    string result;
    foreach (json; jsons)
    {
        try
        {
            val = parseJSON(json);
            enum pretty = false;
            result = toJSON(val, pretty);
            assert(result == json, text(result, " should be ", json));
        }
        catch (JSONException e)
        {
            import std.stdio : writefln;
            writefln(text(json, "\n", e.toString()));
        }
    }

    // Should be able to correctly interpret unicode entities
    val = parseJSON(`"\u003C\u003E"`);
    assert(toJSON(val) == "\"\&lt;\&gt;\"");
    assert(val.to!string() == "\"\&lt;\&gt;\"");
    val = parseJSON(`"\u0391\u0392\u0393"`);
    assert(toJSON(val) == "\"\&Alpha;\&Beta;\&Gamma;\"");
    assert(val.to!string() == "\"\&Alpha;\&Beta;\&Gamma;\"");
    val = parseJSON(`"\u2660\u2666"`);
    assert(toJSON(val) == "\"\&spades;\&diams;\"");
    assert(val.to!string() == "\"\&spades;\&diams;\"");

    //0x7F is a control character (see Unicode spec)
    val = parseJSON(`"\u007F"`);
    assert(toJSON(val) == "\"\\u007F\"");
    assert(val.to!string() == "\"\\u007F\"");

    with(parseJSON(`""`))
        assert(str == "" && str !is null);
    with(parseJSON(`[]`))
        assert(!array.length);

    // Formatting
    val = parseJSON(`{"a":[null,{"x":1},{},[]]}`);
    assert(toJSON(val, true) == `{
    "a": [
        null,
        {
            "x": 1
        },
        {},
        []
    ]
}`);
}

@safe unittest
{
  auto json = `"hello\nworld"`;
  const jv = parseJSON(json);
  assert(jv.toString == json);
  assert(jv.toPrettyString == json);
}

@system pure unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=12969

    JSONValue jv;
    jv["int"] = 123;

    assert(jv.type == JSONType.object);
    assert("int" in jv);
    assert(jv["int"].integer == 123);

    jv["array"] = [1, 2, 3, 4, 5];

    assert(jv["array"].type == JSONType.array);
    assert(jv["array"][2].integer == 3);

    jv["str"] = "D language";
    assert(jv["str"].type == JSONType.string);
    assert(jv["str"].str == "D language");

    jv["bool"] = false;
    assert(jv["bool"].type == JSONType.false_);

    assert(jv.object.length == 4);

    jv = [5, 4, 3, 2, 1];
    assert(jv.type == JSONType.array);
    assert(jv[3].integer == 2);
}

@safe unittest
{
    auto s = q"EOF
[
  1,
  2,
  3,
  potato
]
EOF";

    import std.exception;

    auto e = collectException!JSONException(parseJSON(s));
    assert(e.msg == "Unexpected character 'p'. (Line 5:3)", e.msg);
}

// handling of special float values (NaN, Inf, -Inf)
@safe unittest
{
    import std.exception : assertThrown;
    import std.math.traits : isNaN, isInfinity;

    // expected representations of NaN and Inf
    enum {
        nanString         = '"' ~ JSONFloatLiteral.nan         ~ '"',
        infString         = '"' ~ JSONFloatLiteral.inf         ~ '"',
        negativeInfString = '"' ~ JSONFloatLiteral.negativeInf ~ '"',
    }

    // with the specialFloatLiterals option, encode NaN/Inf as strings
    assert(JSONValue(float.nan).toString(JSONOptions.specialFloatLiterals)       == nanString);
    assert(JSONValue(double.infinity).toString(JSONOptions.specialFloatLiterals) == infString);
    assert(JSONValue(-real.infinity).toString(JSONOptions.specialFloatLiterals)  == negativeInfString);

    // without the specialFloatLiterals option, throw on encoding NaN/Inf
    assertThrown!JSONException(JSONValue(float.nan).toString);
    assertThrown!JSONException(JSONValue(double.infinity).toString);
    assertThrown!JSONException(JSONValue(-real.infinity).toString);

    // when parsing json with specialFloatLiterals option, decode special strings as floats
    JSONValue jvNan    = parseJSON(nanString, JSONOptions.specialFloatLiterals);
    JSONValue jvInf    = parseJSON(infString, JSONOptions.specialFloatLiterals);
    JSONValue jvNegInf = parseJSON(negativeInfString, JSONOptions.specialFloatLiterals);

    assert(jvNan.floating.isNaN);
    assert(jvInf.floating.isInfinity    && jvInf.floating > 0);
    assert(jvNegInf.floating.isInfinity && jvNegInf.floating < 0);

    // when parsing json without the specialFloatLiterals option, decode special strings as strings
    jvNan    = parseJSON(nanString);
    jvInf    = parseJSON(infString);
    jvNegInf = parseJSON(negativeInfString);

    assert(jvNan.str    == JSONFloatLiteral.nan);
    assert(jvInf.str    == JSONFloatLiteral.inf);
    assert(jvNegInf.str == JSONFloatLiteral.negativeInf);
}

pure nothrow @safe @nogc unittest
{
    JSONValue testVal;
    testVal = "test";
    testVal = 10;
    testVal = 10u;
    testVal = 1.0;
    testVal = (JSONValue[string]).init;
    testVal = JSONValue[].init;
    testVal = null;
    assert(testVal.isNull);
}

// https://issues.dlang.org/show_bug.cgi?id=15884
pure nothrow @safe unittest
{
    import std.typecons;
    void Test(C)() {
        C[] a = ['x'];
        JSONValue testVal = a;
        assert(testVal.type == JSONType.string);
        testVal = a.idup;
        assert(testVal.type == JSONType.string);
    }
    Test!char();
    Test!wchar();
    Test!dchar();
}

// https://issues.dlang.org/show_bug.cgi?id=15885
@safe unittest
{
    enum bool realInDoublePrecision = real.mant_dig == double.mant_dig;

    static bool test(const double num0)
    {
        import std.math.operations : feqrel;
        const json0 = JSONValue(num0);
        const num1 = to!double(toJSON(json0));
        static if (realInDoublePrecision)
            return feqrel(num1, num0) >= (double.mant_dig - 1);
        else
            return num1 == num0;
    }

    assert(test( 0.23));
    assert(test(-0.23));
    assert(test(1.223e+24));
    assert(test(23.4));
    assert(test(0.0012));
    assert(test(30738.22));

    assert(test(1 + double.epsilon));
    assert(test(double.min_normal));
    static if (realInDoublePrecision)
        assert(test(-double.max / 2));
    else
        assert(test(-double.max));

    const minSub = double.min_normal * double.epsilon;
    assert(test(minSub));
    assert(test(3*minSub));
}

// https://issues.dlang.org/show_bug.cgi?id=17555
@safe unittest
{
    import std.exception : assertThrown;

    assertThrown!JSONException(parseJSON("\"a\nb\""));
}

// https://issues.dlang.org/show_bug.cgi?id=17556
@safe unittest
{
    auto v = JSONValue("\U0001D11E");
    auto j = toJSON(v, false, JSONOptions.escapeNonAsciiChars);
    assert(j == `"\uD834\uDD1E"`);
}

// https://issues.dlang.org/show_bug.cgi?id=5904
@safe unittest
{
    string s = `"\uD834\uDD1E"`;
    auto j = parseJSON(s);
    assert(j.str == "\U0001D11E");
}

// https://issues.dlang.org/show_bug.cgi?id=17557
@safe unittest
{
    assert(parseJSON("\"\xFF\"").str == "\xFF");
    assert(parseJSON("\"\U0001D11E\"").str == "\U0001D11E");
}

// https://issues.dlang.org/show_bug.cgi?id=17553
@safe unittest
{
    auto v = JSONValue("\xFF");
    assert(toJSON(v) == "\"\xFF\"");
}

@safe unittest
{
    import std.utf;
    assert(parseJSON("\"\xFF\"".byChar).str == "\xFF");
    assert(parseJSON("\"\U0001D11E\"".byChar).str == "\U0001D11E");
}

// JSONOptions.doNotEscapeSlashes (https://issues.dlang.org/show_bug.cgi?id=17587)
@safe unittest
{
    assert(parseJSON(`"/"`).toString == `"\/"`);
    assert(parseJSON(`"\/"`).toString == `"\/"`);
    assert(parseJSON(`"/"`).toString(JSONOptions.doNotEscapeSlashes) == `"/"`);
    assert(parseJSON(`"\/"`).toString(JSONOptions.doNotEscapeSlashes) == `"/"`);
}

// JSONOptions.strictParsing (https://issues.dlang.org/show_bug.cgi?id=16639)
@safe unittest
{
    import std.exception : assertThrown;

    // Unescaped ASCII NULs
    assert(parseJSON("[\0]").type == JSONType.array);
    assertThrown!JSONException(parseJSON("[\0]", JSONOptions.strictParsing));
    assert(parseJSON("\"\0\"").str == "\0");
    assertThrown!JSONException(parseJSON("\"\0\"", JSONOptions.strictParsing));

    // Unescaped ASCII DEL (0x7f) in strings
    assert(parseJSON("\"\x7f\"").str == "\x7f");
    assert(parseJSON("\"\x7f\"", JSONOptions.strictParsing).str == "\x7f");

    // "true", "false", "null" case sensitivity
    assert(parseJSON("true").type == JSONType.true_);
    assert(parseJSON("true", JSONOptions.strictParsing).type == JSONType.true_);
    assert(parseJSON("True").type == JSONType.true_);
    assertThrown!JSONException(parseJSON("True", JSONOptions.strictParsing));
    assert(parseJSON("tRUE").type == JSONType.true_);
    assertThrown!JSONException(parseJSON("tRUE", JSONOptions.strictParsing));

    assert(parseJSON("false").type == JSONType.false_);
    assert(parseJSON("false", JSONOptions.strictParsing).type == JSONType.false_);
    assert(parseJSON("False").type == JSONType.false_);
    assertThrown!JSONException(parseJSON("False", JSONOptions.strictParsing));
    assert(parseJSON("fALSE").type == JSONType.false_);
    assertThrown!JSONException(parseJSON("fALSE", JSONOptions.strictParsing));

    assert(parseJSON("null").type == JSONType.null_);
    assert(parseJSON("null", JSONOptions.strictParsing).type == JSONType.null_);
    assert(parseJSON("Null").type == JSONType.null_);
    assertThrown!JSONException(parseJSON("Null", JSONOptions.strictParsing));
    assert(parseJSON("nULL").type == JSONType.null_);
    assertThrown!JSONException(parseJSON("nULL", JSONOptions.strictParsing));

    // Whitespace characters
    assert(parseJSON("[\f\v]").type == JSONType.array);
    assertThrown!JSONException(parseJSON("[\f\v]", JSONOptions.strictParsing));
    assert(parseJSON("[ \t\r\n]").type == JSONType.array);
    assert(parseJSON("[ \t\r\n]", JSONOptions.strictParsing).type == JSONType.array);

    // Empty input
    assert(parseJSON("").type == JSONType.null_);
    assertThrown!JSONException(parseJSON("", JSONOptions.strictParsing));

    // Numbers with leading '0's
    assert(parseJSON("01").integer == 1);
    assertThrown!JSONException(parseJSON("01", JSONOptions.strictParsing));
    assert(parseJSON("-01").integer == -1);
    assertThrown!JSONException(parseJSON("-01", JSONOptions.strictParsing));
    assert(parseJSON("0.01").floating == 0.01);
    assert(parseJSON("0.01", JSONOptions.strictParsing).floating == 0.01);
    assert(parseJSON("0e1").floating == 0);
    assert(parseJSON("0e1", JSONOptions.strictParsing).floating == 0);

    // Trailing characters after JSON value
    assert(parseJSON(`""asdf`).str == "");
    assertThrown!JSONException(parseJSON(`""asdf`, JSONOptions.strictParsing));
    assert(parseJSON("987\0").integer == 987);
    assertThrown!JSONException(parseJSON("987\0", JSONOptions.strictParsing));
    assert(parseJSON("987\0\0").integer == 987);
    assertThrown!JSONException(parseJSON("987\0\0", JSONOptions.strictParsing));
    assert(parseJSON("[]]").type == JSONType.array);
    assertThrown!JSONException(parseJSON("[]]", JSONOptions.strictParsing));
    assert(parseJSON("123 \t\r\n").integer == 123); // Trailing whitespace is OK
    assert(parseJSON("123 \t\r\n", JSONOptions.strictParsing).integer == 123);
}

@system unittest
{
    import std.algorithm.iteration : map;
    import std.array : array;
    import std.exception : assertThrown;

    string s = `{ "a" : [1,2,3,], }`;
    JSONValue j = parseJSON(s);
    assert(j["a"].array().map!(i => i.integer()).array == [1,2,3]);

    assertThrown(parseJSON(s, -1, JSONOptions.strictParsing));
}

@system unittest
{
    import std.algorithm.iteration : map;
    import std.array : array;
    import std.exception : assertThrown;

    string s = `{ "a" : { }  , }`;
    JSONValue j = parseJSON(s);
    assert("a" in j);
    auto t = j["a"].object();
    assert(t.empty);

    assertThrown(parseJSON(s, -1, JSONOptions.strictParsing));
}

// https://issues.dlang.org/show_bug.cgi?id=20330
@safe unittest
{
    import std.array : appender;

    string s = `{"a":[1,2,3]}`;
    JSONValue j = parseJSON(s);

    auto app = appender!string();
    j.toString(app);

    assert(app.data == s, app.data);
}

// https://issues.dlang.org/show_bug.cgi?id=20330
@safe unittest
{
    import std.array : appender;
    import std.format.write : formattedWrite;

    string s =
`{
    "a": [
        1,
        2,
        3
    ]
}`;
    JSONValue j = parseJSON(s);

    auto app = appender!string();
    j.toPrettyString(app);

    assert(app.data == s, app.data);
}
