///|
#derive(Eq, Debug)
struct Item {
id : Int32
note : @jsonkit.Presence[String]
state : String
}
///|
impl FromJson for Item with fn from_json(json, path) {
let obj = @jsonkit.expect_object(json, path)
{
id: @jsonkit.field(obj, "id", path),
note: @jsonkit.presence_field(obj, "note", path),
state: @jsonkit.open_string(
obj.get("state").unwrap_or(Json::null()),
path.add_key("state"),
s => if s == "open" { Some(s) } else { None },
s => "unknown:" + s,
),
}
}
///|
impl ToJson for Item with fn to_json(self) {
@jsonkit.ObjBuilder::new()
.field("id", self.id)
.presence("note", self.note)
.field("state", self.state)
.build()
}
///|
test "a model with a required, a nullable and an open field" {
let item : Item = @json.from_json({
"id": 7,
"note": null,
"state": "archived",
})
assert_eq(item, { id: 7, note: Null, state: "unknown:archived", })
assert_eq(ToJson::to_json(item), {
"id": 7,
"note": null,
"state": "unknown:archived",
})
let missing = try (@json.from_json({ "note": "x" }) : Item) catch {
@json.JsonDecodeError((path, message)) => "\{path}: \{message}"
} noraise {
_ => "decoded"
}
assert_eq(missing, "/id: missing required field")
}pub struct ObjBuilder {
// private fields
}test {
let builder = @jsonkit.ObjBuilder::new()
.field("name", "sample")
.opt("count", (None : Int32?))
.presence("note", (@jsonkit.Null : @jsonkit.Presence[String]))
assert_eq(builder.build(), { "name": "sample", "note": null })
}fn[T : ToJson] ObjBuilder::presence(self : ObjBuilder, key : String, value : Presence[T]) -> ObjBuildertest {
let value = @jsonkit.Presence::from_option(Some(3))
assert_eq(value.map(n => n + 1).to_option(), Some(4))
assert_false(value.is_absent())
}fn[T : FromJson] field(obj : Map[String, Json], key : String, path : JsonPath) -> T raise JsonDecodeErrorfn[T] open_int(json : Json, path : JsonPath, known : (Int) -> T?, unknown : (Int) -> T) -> T raise JsonDecodeErrorfn[T] open_string(json : Json, path : JsonPath, known : (String) -> T?, unknown : (String) -> T) -> T raise JsonDecodeErrorfn[T : FromJson] opt_field(obj : Map[String, Json], key : String, path : JsonPath) -> T? raise JsonDecodeErrorInstall
Download zipHTTP for MoonBit in the style of sttp, on top of gaato/http: a client with retries, rate limits and deadlines, server-sent events, multipart, cookies, endpoints and OpenAPI. Runs on every backend.