Skip to content
This repository was archived by the owner on Mar 12, 2026. It is now read-only.
This repository was archived by the owner on Mar 12, 2026. It is now read-only.

Pony JSON - difficult to modify iso JsonDoc #16

@sgebbie

Description

@sgebbie

Currently json.JsonDoc provides accessors via the data field. However, if one has an iso reference to a JsonDoc that has already been populated, then it is difficult to modify the data after the fact.

Background

For example, the following code will work (where a ref alias is recovered):

be dostuff(jdoc: JsonDoc iso) =>
    let jdoc': JsonDoc ref = recover ref consume jdoc end
    try
        (jdoc'.data as JsonObject).data("seq") = I64(123)
    end

But then jdoc' is no longer iso.

One could replace jdoc.data altogether:

    let jom = recover iso Map[String, JsonType] end
    jom("seq") = I64(123)
    jdoc.data = recover iso JsonObject.from_map(consume jom) end

But then the full map would need to be recreated.

Proposal

Based on feedback from Borja o'Cook we could instead introduce "getters" into JsonDoc and JsonObject (and JsonArray) such that viewpoint adaptation could be applied to help achieve the desired access to the data while satisfying the reference capability constraints.

class JsonDoc
  // ....
  fun get_data(): this->JsonType! =>
    data

// ...

class JsonObject
  // ...
  fun get_data(): this->Map[String, JsonType]! =>
    data

// ---

actor Main
  let _env: Env

  new create(env: Env) =>
    _env = env
    try
      let json_string = "{\"key\":\"value\"}"
      let sendable_doc: JsonDoc iso = recover iso JsonDoc.>parse(json_string)? end
      this.dostuff(consume sendable_doc)
    end

  be dostuff(jdoc: JsonDoc iso) =>
    try
      let new_doc: JsonDoc iso = recover
        let doc_ref = consume ref jdoc
        let obj: JsonObject ref = doc_ref.get_data() as JsonObject
        let data = obj.get_data()
        data("seq") = I64(123)
        doc_ref
      end
      this.morestuff(consume new_doc)
    end

  be morestuff(jdoc: JsonDoc iso) =>
   _env.out.print(jdoc.string(where indent="  ", pretty_print=true))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions