Announce: A different way to read JSON data, LazyJSON.jl

About LazyJSON.splice:

So, I was thinking about how LazyJSON should do updates.
Since it returns AbstractDict, you can already use Base.merge to create a modified Dict, but that has about the same overhead as JSON.jl.

However, there is an update use case where LazyJOSN can do quite well: you have a largish JSON text and you need to update a few values. LazyJSON.splice works entirely in the text string domain and requires only a few lines of code (currently only replacing values is supported, but inserting new values is possible too):

splice(j::JSON.Value, v::JSON.Value, x) = value(splice(j.s, v.i, x, j.i))

splice(s::AbstractString, i::Int, x, start_i = 1) = 
    string(SubString(s, start_i, i - 1),
           jsonstring(x),
           SubString(s, lastindex_of_value(s, i) + 1))

e.g.

j = """{
    "id": 1296269,
    "owner": {
        "login": "octocat"
    },
    "parent": {
        "name": "test-parent"
    }
}"""

@test LazyJSON.splice(j, ["owner", "login"], "foo") ==
"""{
    "id": 1296269,
    "owner": {
        "login": "foo"
    },
    "parent": {
        "name": "test-parent"
    }
}"""

@test LazyJSON.splice(j, ["owner"], "foo") ==
"""{
    "id": 1296269,
    "owner": "foo",
    "parent": {
        "name": "test-parent"
    }
}"""

j = LazyJSON.value(j)

LazyJSON.splice(j, j.owner.login, "foo")
LazyJSON.Object with 3 entries:
  "id"     => 1296269
  "owner"  => LazyJSON.Object("login"=>"foo")
  "parent" => LazyJSON.Object("name"=>"test-parent")
1 Like