Decoding
Profile is a named struct with a fixed JSON shape. Its nickname field
uses Option<String>: the decoder maps JSON null to None and a string
to Some(value). The field must still be present in the JSON object.
mod decoding.profile
@moduledoc """`Profile` is a named struct with a fixed JSON shape. Its `nickname` fielduses `Option<String>`: the decoder maps JSON `null` to `None` and a stringto `Some(value)`. The field must still be present in the JSON object."""
struct { name: String, age: Integer, tags: List<String>, nickname: Option<String>}JSON parsing starts with an unknown Term. A Decoder<A> checks that value
at runtime and returns Result<A, DecodeError>. Successful decoding produces
the Gale type the caller asked for. Encoding is explicit too: Encoder<A>
produces Gale’s closed Json type, so values that are not JSON cannot be
encoded accidentally.
mod decoding
alias gale_std.decodealias gale_std.json as std_json
pub fn profile_decoder() -> decode.Decoder<decoding.profile.Profile> { fn(input) -> { with { name <- decode.field(input, "name", decode.string()) age <- decode.field(input, "age", decode.integer()) tags <- decode.field(input, "tags", decode.list(decode.string())) nickname <- decode.field(input, "nickname", decode.nullable(decode.string())) %decoding.profile.Profile{ name: name, age: age, tags: tags, nickname: nickname } } }}
pub fn profile_encoder() -> std_json.Encoder<decoding.profile.Profile> { fn(profile) -> std_json.object([ {"name", std_json.string(profile.name)}, {"age", std_json.integer(profile.age)}, {"tags", std_json.array(profile.tags, fn(tag) -> std_json.string(tag))}, { "nickname", std_json.nullable(profile.nickname, fn(nickname) -> std_json.string(nickname)) } ])}
pub fn decode_profile(source: String) -> Result<decoding.profile.Profile, std_json.JsonError> { std_json.parse(source, profile_decoder())}
pub fn encode_profile(profile: decoding.profile.Profile) -> String { std_json.encode_with(profile, profile_encoder())}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.
Passing an arbitrary BEAM value is a type error:
pub fn encode_pid(pid: gale_std.process.Pid<Term>) -> String { gale_std.json.encode(pid)}