JSON Package¶
The json
package provides the JsonDoc class both as a container for a JSON
document and as means of parsing from and writing to String.
JSON Representation¶
JSON is represented in Pony as the following types:
- object - JsonObject
- array - JsonArray
- string - String
- integer - I64
- float - F64
- boolean - Bool
- null - None
The collection types JsonObject and JsonArray can contain any other JSON structures arbitrarily nested.
JsonType is used to subsume all possible JSON types. It can also be used to describe everything that can be serialized using this package.
Parsing JSON¶
For getting JSON from a String into proper Pony data structures,
JsonDoc.parse needs to be used. This will populate the
public field JsonDoc.data
, which is None, if parse has
not been called yet.
Every call to parse overwrites the data
field, so one
JsonDoc instance can be used to parse multiple JSON Strings one by one.
let doc = JsonDoc
// parsing
doc.parse("{\"key\":\"value\", \"property\": true, \"array\":[1, 2.5, false]}")?
// extracting values from a JSON structure
let json: JsonObject = doc.data as JsonObject
let key: String = json.data("key")? as String
let property: Bool = json.data("property")? as Bool
let array: JsonArray = json.data("array")? as JsonArray
let first: I64 = array.data(0)? as I64
let second: F64 = array.data(1)? as F64
let last: Bool = array.data(2)? as Bool
Sending JSON¶
JsonDoc has the ref
reference capability, which means it is
not sendable by default. If you need to send it to another actor you need to
recover it to a sendable reference capability (either val
or iso
). For the
sake of simplicity it is recommended to do the parsing already in the recover
block:
// sending an iso doc
let json_string = "{\"array\":[1, true, null]}"
let sendable_doc: JsonDoc iso = recover iso JsonDoc.>parse(json_string)? end
some_actor.send(consume sendable_doc)
// sending a val doc
let val_doc: JsonDoc val = recover val JsonDoc.>parse(json_string)? end
some_actor.send_val(val_doc)
When sending an iso
JsonDoc it is important to recover it to a ref
on the
receiving side in order to be able to properly access the json structures in
data
.
Writing JSON¶
JSON is written using the JsonDoc.string method. This
will serialize the contents of the data
field to String.
// building up the JSON data structure
let doc = JsonDoc
let obj = JsonObject
obj.data("key") = "value"
obj.data("property") = true
obj.data("array") = JsonArray.from_array([ as JsonType: I64(1); F64(2.5); false])
doc.data = obj
// writing to String
env.out.print(
doc.string(where indent=" ", pretty_print=true)
)