Skip to content

Support user-defined functions for serialising Inf and NaN #292

@hhaensel

Description

@hhaensel

Currently, Inf and NaN are translated to Infinity and NaN if allow_inf = true is passed to JSON.write().

Unfortunately, the standard JSON parser in the browser does not support this syntax. Typical workarounds are regex substitution of Infinity to "Infinity", which is slow and error-prone.

If only Inf translation is needed, a nice hack is to translate Inf to 1e1000 which is converted to Infinity by the built-in number parser rather than by the JSON parser.
If also NaN is needed, the only possibility I am aware of is via reviver. But as there is no standard format, I could propose, I thought a customisable solution would be nice.

I propose to support user-defined translations via value types;
Inf, -Inf and NaN are output as RawType() for which the users can define their own values, e.g.

JSON3.rawbytes(::Val{Inf}) = codeunits("1e1000")
JSON3.rawbytes(::Val{-Inf}) = codeunits("-1e1000")
JSON3.rawbytes(::Val{NaN}) = codeunits("__nan__")

so that

julia> JSON3.write((a = Inf, b = -Inf32, c = NaN), allow_inf = true)
"{\"a\":1e1000,\"b\":-1e1000, \"c\":\"__nan__\"}"

I've prepared a PR, which I will submit for consideration.
There is a slight perfomance reduction of 1% vs. the existing treatment of Inf, while NaNs are treated a bit faster. I'd consider the changes negligable, given the fact that the occurrence of the these values rather low.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions