gargamelle/encoding
Explicit typed JSON encoding, independently of structural definitions.
encode_json produces admitted JSON. encode additionally checks a stored
Contract. Typed output boundaries are provided by gargamelle/boundary.
Encoding and decoding need not be inverses. Getters and projections are trusted
application functions: exceptions propagate as operational failures.
Types
Codec
opaqueAn explicit encoder and its authoritative output Contract. Equal output types do not establish schema agreement; checked encoding enforces the Contract.
pub opaque type Codec(a)
Encoding stops at its first failure. Runtime paths are JSON Pointers into the would-be encoded JSON, empty at the root. Field declaration errors identify the supplied key separately; their containing location is not yet known. Contract failures retain their own structural and semantic diagnostics. Callback exceptions and resource failures are not caught.
pub type EncodingError {
InvalidValue(path: String, problem: ValueProblem)
InvalidField(name: String, problem: FieldProblem)
Admission(path: String, error: gargamelle.AdmissionError)
Contract(gargamelle.ContractError)
}
Constructors
-
InvalidValue(path: String, problem: ValueProblem) -
InvalidField(name: String, problem: FieldProblem) -
Admission(path: String, error: gargamelle.AdmissionError) -
Contract(gargamelle.ContractError)
A rejected record field declaration. Construction has no containing JSON path.
pub type FieldProblem {
DuplicateKey
NonScalarKey
}
Constructors
-
DuplicateKey -
NonScalarKey
Plan
opaqueAn encoding plan under recursion environment r. Only completed encoders,
Plan(a, Nil), can be executed. Construction references cannot escape as
runnable encoders; recursive builders execute once.
pub opaque type Plan(a, r)
Record
opaqueA record encoder under construction, with explicit field getters.
pub opaque type Record(a, r)
Recursive
opaqueOpaque environment supplied to a self-recursive encoding plan.
pub opaque type Recursive(a)
A rejected primitive encoding value.
pub type ValueProblem {
NonFiniteNumber
UnsafeInteger
NonScalarString
}
Constructors
-
NonFiniteNumber -
UnsafeInteger -
NonScalarString
Values
pub fn array(encoder: Plan(a, r)) -> Plan(List(a), r)
Encode list elements in order, stopping at the first encoding failure.
pub fn choice(
first: Plan(a, r),
second: Plan(b, r),
) -> Plan(Result(a, b), r)
Encode the selected Result branch. A projection can adapt an application sum type.
pub fn codec(
encoder: Plan(a, Nil),
contract: gargamelle.Contract(a),
) -> Codec(a)
Pair an encoder with a Contract without running either. This is an explicit pair, not encoder derivation or a claim that encoding and decoding are inverses.
pub fn codec_contract(codec: Codec(a)) -> gargamelle.Contract(a)
Inspect the exact Contract used by checked encoding, without callbacks.
pub fn contramap(
encoder: Plan(a, r),
get: fn(b) -> a,
) -> Plan(b, r)
Adapt an encoder with a trusted getter or projection. The callback runs once.
pub fn encode(
codec: Codec(a),
value: a,
) -> Result(gargamelle.VerifiedJson(a), EncodingError)
Encode once, then verify the stored Contract once. A check-free Contract validates without decoding; semantic requirements cause one decoding pass. Checks inspect that decoded output, which need not equal the original input.
pub fn encode_json(
encoder: Plan(a, Nil),
value: a,
) -> Result(gargamelle.Json, EncodingError)
Encode to admitted JSON without checking a definition or Contract. Encoding serializes an intermediate JSON tree and admits its text once. The result contains no certificate and claims no schema conformance.
pub fn field(
record: Record(a, r),
name: String,
encoder: Plan(b, r),
get: fn(a) -> b,
) -> Result(Record(a, r), EncodingError)
Add a required field with a getter. Duplicate and non-scalar keys fail construction.
pub fn finish(record: Record(a, r)) -> Plan(a, r)
Complete a record encoder. Getters execute in declaration order at encoding time.
pub fn json() -> Plan(gargamelle.Json, r)
Encode an already admitted Gargamelle Json value. This composes arbitrary metadata with typed field encoders; it does not certify a Contract. The usual serialization/admission path applies, preserving canonical JSON rather than original source formatting or object declaration order.
pub fn lift(encoder: Plan(a, Nil)) -> Plan(a, r)
Use a completed encoder inside a plan with any recursion environment.
pub fn nullable(encoder: Plan(a, r)) -> Plan(option.Option(a), r)
Encode None as JSON null and Some through the child encoder.
pub fn number() -> Plan(Float, r)
Encode a finite binary64 Float. Reject nonfinite values before serialization.
pub fn optional_field(
record: Record(a, r),
name: String,
encoder: Plan(b, r),
get: fn(a) -> option.Option(b),
) -> Result(Record(a, r), EncodingError)
Add a field omitted when its getter returns None. Some uses the child encoder.
pub fn recursive(
build: fn(Plan(a, Recursive(a))) -> Result(
Plan(a, Recursive(a)),
EncodingError,
),
) -> Result(Plan(a, Nil), EncodingError)
Build a completed self-recursive encoder using an immutable body. The builder runs once. Recursion must descend through the input; immediate self-calls can diverge.
pub fn safe_integer() -> Plan(Int, r)
Encode an Int in the common safe-integer range. Reject out-of-range values.