json
JSON parsing and encoding for Donna.
Backed by the yyjson C library for fast, correct parsing.
import json
let result = json.parse("{\"name\": \"Donna\", \"version\": 1}")
case result:
json.Err(_) -> "parse error"
json.Ok(value) ->
case json.get(value, "name"):
json.Err(_) -> ""
json.Ok(name) -> json.unwrap_string(json.as_string(name))
Types
pub type JsonA JSON value.
import json
pub fn make_object() -> json.Json:
json.Object([#("ok", json.Bool(True)), #("count", json.Int(3))])
NullBool(Bool)Int(Int)Float(Float)Str(String)Array(List(Json))Object(List(#(String, Json)))pub type Parsed(a)Result of a parse or lookup operation.
import json
pub fn is_ok() -> Bool:
json.parse("{}") |> json.is_ok
Ok(a)Err(String)pub type DocA handle to a C-backed yyjson document.
Use open to create a document and close when you are finished with it.
Querying a document is faster than materializing the whole JSON tree with
parse.
import json
pub fn read_name(src: String) -> String:
case json.open(src):
json.Err(_) -> ""
json.Ok(doc) ->
let name = json.unwrap_string(json.query_string(doc, "user.name"))
let _ = json.close(doc)
name
Doc(Int)Functions
pub fn parse(input: String) -> Parsed(Json)Parse a JSON string into a Json value.
import json
pub fn example() -> json.Parsed(json.Json):
json.parse("[1, 2, 3]")
pub fn is_valid(input: String) -> BoolReturn True when a string contains valid JSON.
This uses yyjson directly and does not allocate a Donna Json tree, so it
is the fastest way to check whether input is JSON.
import json
pub fn example() -> Bool:
json.is_valid("{\"ok\": true}")
pub fn open(input: String) -> Parsed(Doc)Open a JSON document as a C-backed handle.
The returned document must be closed with json.close.
import json
pub fn example(src: String) -> json.Parsed(json.Doc):
json.open(src)
pub fn close(doc: Doc) -> NilClose a C-backed JSON document.
import json
pub fn example(doc: json.Doc) -> Nil:
json.close(doc)
pub fn query(doc: Doc, path: String) -> Parsed(Json)Query a value from a C-backed document by path.
Paths are dot-separated. Object keys use their name and array indexes use
numeric segments, for example user.name or items.0.title.
import json
pub fn first_item(doc: json.Doc) -> json.Parsed(json.Json):
json.query(doc, "items.0")
pub fn query_string(doc: Doc, path: String) -> Parsed(String)Query a string value from a C-backed document.
import json
pub fn read(doc: json.Doc) -> json.Parsed(String):
json.query_string(doc, "name")
pub fn query_int(doc: Doc, path: String) -> Parsed(Int)Query an integer value from a C-backed document.
import json
pub fn read(doc: json.Doc) -> json.Parsed(Int):
json.query_int(doc, "version")
pub fn query_float(doc: Doc, path: String) -> Parsed(Float)Query a float value from a C-backed document.
import json
pub fn read(doc: json.Doc) -> json.Parsed(Float):
json.query_float(doc, "ratio")
pub fn query_bool(doc: Doc, path: String) -> Parsed(Bool)Query a boolean value from a C-backed document.
import json
pub fn read(doc: json.Doc) -> json.Parsed(Bool):
json.query_bool(doc, "ok")
pub fn get(obj: Json, key: String) -> Parsed(Json)Get a value from a JSON object by key.
import json
pub fn read_name(obj: json.Json) -> String:
case json.get(obj, "name"):
json.Err(_) -> ""
json.Ok(v) -> json.unwrap_string(json.as_string(v))
pub fn at(arr: Json, index: Int) -> Parsed(Json)Get an element from a JSON array by index (zero-based).
import json
pub fn first(arr: json.Json) -> json.Parsed(json.Json):
json.at(arr, 0)
pub fn as_string(j: Json) -> Parsed(String)Extract a string from a Json value.
import json
pub fn read(v: json.Json) -> json.Parsed(String):
json.as_string(v)
pub fn as_int(j: Json) -> Parsed(Int)Extract an integer from a Json value.
import json
pub fn read(v: json.Json) -> json.Parsed(Int):
json.as_int(v)
pub fn as_float(j: Json) -> Parsed(Float)Extract a float from a Json value.
import json
pub fn read(v: json.Json) -> json.Parsed(Float):
json.as_float(v)
pub fn as_bool(j: Json) -> Parsed(Bool)Extract a boolean from a Json value.
import json
pub fn read(v: json.Json) -> json.Parsed(Bool):
json.as_bool(v)
pub fn as_array(j: Json) -> Parsed(List(Json))Extract the list of elements from a Json array.
import json
pub fn read(v: json.Json) -> json.Parsed(List(json.Json)):
json.as_array(v)
pub fn as_object(j: Json) -> Parsed(List(#(String, Json)))Extract the list of key-value pairs from a Json object.
import json
pub fn read(v: json.Json) -> json.Parsed(List(#(String, json.Json))):
json.as_object(v)
pub fn is_null(j: Json) -> BoolReturn True when a Json value is Null.
import json
pub fn example() -> Bool:
json.is_null(json.Null)
pub fn is_ok(r: Parsed(a)) -> BoolReturn True when a Parsed result is Ok.
import json
pub fn example() -> Bool:
json.is_ok(json.Ok(json.Null))
pub fn is_err(r: Parsed(a)) -> BoolReturn True when a Parsed result is Err.
import json
pub fn example() -> Bool:
json.is_err(json.Err("nope"))
pub fn unwrap_string(r: Parsed(String)) -> StringExtract a string from a Parsed(String), returning a fallback on error.
import json
pub fn example() -> String:
json.unwrap_string(json.Ok("Donna"))
pub fn unwrap_int(r: Parsed(Int)) -> IntExtract an integer from a Parsed(Int), returning 0 on error.
import json
pub fn example() -> Int:
json.unwrap_int(json.Ok(42))
pub fn unwrap_bool(r: Parsed(Bool)) -> BoolExtract a boolean from a Parsed(Bool), returning False on error.
import json
pub fn example() -> Bool:
json.unwrap_bool(json.Ok(True))
pub fn encode(j: Json) -> StringEncode a Json value to a JSON string.
import json
pub fn round_trip(j: json.Json) -> String:
json.encode(j)