Serializing Julia Composite Type with Inline JavaScript to JSON

This is a follow-up to this issue, because I still can’t quite see how to do this.

I’d love to be able to create a Julia composite type, and when I serialize to JSON, be able to emit valid JavaScript. The JavaScript library I’m wrapping uses inline function definitions, which aren’t in the JSON specification but are valid JavaScript.

using JSON

type JSFunction
    symbolSize
end

a = JSFunction("function (data) {return Math.sqrt(data[2]) / 5e2;}")

print(JSON.json(a))

returns: {"symbolSize":"function (data) {return Math.sqrt(data[2]) / 5e2;}"}
need: {"symbolSize": function (data) {return Math.sqrt(data[2]) / 5e2;}}

https://github.com/JuliaIO/JSON.jl/issues/170

The trick is to define a new kind of serialization context that inherits from the default.

import JSON
using JSON.StructuralContext
using JSON.Serializations.CommonSerialization

immutable JSSerialization <: CommonSerialization end
immutable JSFunction
    data::Compat.UTF8String
end

function JSON.show_json(io::StructuralContext,
                          ::JSSerialization, f::JSFunction)
    first = true
    for line in split(f.data, '\n')
        if !first
            JSON.indent(io)
        end
        first = false
        Base.print(io, line)
    end
end

json(x) = sprint(JSON.show_json, JSSerialization(), x)

You’re right that this isn’t super clear right now; we’ll need to document this better.

1 Like

Unfortunately, this doesn’t seem to provide the correct answer, I’m still seeing the double-quotes around the function.

a = ECharts.JSFunction("function (data) {return Math.sqrt(data[2]) / 5e2;}")
ECharts.JSFunction("function (data) {return Math.sqrt(data[2]) / 5e2;}")

JSON.json(a)
"{\"data\":\"function (data) {return Math.sqrt(data[2]) / 5e2;}\"}"

print(JSON.json(a))
{"data":"function (data) {return Math.sqrt(data[2]) / 5e2;}"}

I pushed a commit to show what I have implemented:

https://github.com/randyzwitch/ECharts.jl/commit/529ae3536ac7e9613268287fb9f4971c4b507a43

Try using the json method that @fengyang.wang defined, not the one in JSON.

1 Like

Thanks, that’s really subtle. I still have an error in my package somewhere, but at the very least, I can get my test example to work.

1 Like

Yes, that’s right. The idea behind it is that different packages will have different needs, and it’s important for custom serializations not to interfere with the standard serialization. The intention is that packages will define and use their own json function.

FWIW, here’s what I was trying to do and why it’s important, and most importantly, THANK YOU!!! This will open up all the goodies in this visualization library.