JSON
JSON parsing starts with an unknown Term. A Decoder<A> checks that value at
runtime and returns Result<A, DecodeError>, so successful decoding produces the
exact Gale type requested by the caller. Encoding is explicit too:
Encoder<A> produces Gale’s closed Json type, so values outside JSON’s data
model cannot be encoded accidentally.
Profile is a nominal struct with a statically known JSON shape. Nullable
JSON data is represented explicitly with Option<A>.
module json_example.profile
@moduledoc """`Profile` is a nominal struct with a statically known JSON shape. NullableJSON data is represented explicitly with `Option<A>`."""
struct { name: Binary, age: Integer, tags: List<Binary>, nickname: Option<Binary>}
pub fn profile_decoder() -> gale_std.decode.Decoder<Profile> { fn(input) => { with { name <- gale_std.decode.field(input, "name", gale_std.decode.binary()) age <- gale_std.decode.field(input, "age", gale_std.decode.integer()) tags <- gale_std.decode.field( input, "tags", gale_std.decode.list(gale_std.decode.binary()) ) nickname <- gale_std.decode.field( input, "nickname", gale_std.decode.nullable(gale_std.decode.binary()) ) let profile = Profile { name: name, age: age, tags: tags, nickname: nickname } profile } }}
pub fn profile_encoder() -> gale_std.json.Encoder<Profile> { fn(profile) => gale_std.json.object([ ("name", gale_std.json.string(profile.name)), ("age", gale_std.json.integer(profile.age)), ( "tags", gale_std.json.array( profile.tags, fn(tag) => gale_std.json.string(tag) ) ), ( "nickname", gale_std.json.nullable( profile.nickname, fn(nickname) => gale_std.json.string(nickname) ) ) ])}Encoding is explicit too. Encoder<A> produces Gale’s closed Json type;
values outside JSON’s data model, such as PIDs, cannot be encoded accidentally.
Passing an arbitrary BEAM value is a type error:
pub fn encode_pid(pid: gale_std.process.Pid<Term>) -> Binary { gale_std.json.encode(pid)}gale_std.json.parse(source, profile_decoder()) separates malformed JSON with
JsonSyntaxError from a valid JSON value of the wrong shape with
JsonValueError. Decode errors carry DecodeField and DecodeIndex paths.