Expand description
kanonak-codec — the generic, ontology-independent codec runtime (Rust port).
Given a CodecSchema (the per-package metadata a generated SDK embeds) and a
set of typed nodes, it builds the canonical input model and content-addresses
it via kanonak-canonical (the same content-form the Python/TypeScript
references and the kanonak hash CLI produce). It also (de)serializes the
normalized-JSON wire form. Self-contained: carriers come from the schema’s
datatype URIs, and the resolved foundation URIs are embedded by the generator,
so hashing needs no runtime ontology resolution.
A node is a plain JSON object (serde_json::Map<String, serde_json::Value>) —
the $-envelope plus alias-collapsed local-name fields. A generated typed
model serializes to one. Note: serde_json::Value (the node field model) is
distinct from kanonak_canonical::Value (the canonical-input value enum).
Structs§
- Decimal
- A
decimal, held as its canonical digits, since no Rust type in the standard library holds every value. JSON carries it as a string of those digits, and it reads from a string only, so it can’t have been rounded. - Enum
Member Match - An enumeration member found by
enum_member.#[non_exhaustive]: read its fields; a later 1.x release may add one. - Integer
- An integer of datatype
D, held as its canonical digits, since no Rust integer holds every value. JSON carries it as a string of those digits, and it reads from a string or a whole number within ±(2^53 − 1), insideD’s range. - Kanonak
Node - The
$-envelope as data — composed into a generated struct via#[serde(flatten)], so an instance carries its own identity and serializes straight to the normalized-JSON wire form.extraholds open-world assertions outside the type-model, keyed by predicate URI; being the innermost flatten map, it also collects unknown wire fields on deserialize. - Long
- A
long, which JSON carries as a string of its digits. It reads from a string or a whole number within ±(2^53 − 1). - Negative
Integer xsd:negativeInteger, forInteger.- NonNegative
Integer xsd:nonNegativeInteger, forInteger.- NonPositive
Integer xsd:nonPositiveInteger, forInteger.- Positive
Integer xsd:positiveInteger, forInteger.- Unsigned
Long - An
unsignedLong, which JSON carries as a string of its digits. It reads from a string or a whole number within ±(2^53 − 1). - XsdInteger
xsd:integer, forInteger.
Enums§
- Codec
Error - Errors raised by the codec runtime. Fails loudly — no fallbacks.
- Ref
- An object property’s value: EXACTLY ONE of a reference to a named resource
(its canonical URI) or an embedded node (the value itself, carried inline —
derived identity, no
$id). The typed twin of the wire form’s{"$ref": uri}vs embedded-node distinction; the choice between the arms is authorial and hash-relevant, so it is explicit here, never inferred.
Traits§
- Integer
Datatype integeror one of its four sign-restricted forms, as a marker anIntegeris parameterized by, so the field states which datatype it holds and its range is checked.- Kanonak
Resource - Implemented by generated typed structs (over their flattened
KanonakNode) so the runtime can read/write an instance’s envelope — what letsRef::to_resourceresolve identity andRef::embed_namedcarry the authored dict-key.
Functions§
- build_
package - Build the canonical input model: a subject per node + the synthesized
package-wrapper subject (raw label +
Packagetype), exactly the subject setkanonak hashproduces for the equivalent authored package. - canonical_
form - The canonical form (the
{subjects:[...]}JSON) of a package from nodes. - content_
hash - The
sha256:content hash of a package from nodes — matcheskanonak hash. - deserialize
- Parse normalized JSON into a typed node.
$-envelope keys and fields modeled on the node’s$typestay top-level; every other key is collected into$extraso a strongly-typed consumer round-trips it losslessly. Requires$type(the one field that cannot be inferred) and a class in the schema that can read it: the exact class, or the same class at a compatible later version (runtime#28 — seetype_matchesfor the same rule). The node keeps the$typeit was WRITTEN with; the producer’s bytes are the producer’s. - enum_
member - The enumeration member a
{"$ref": …}names (runtime#28): the exact versioned key first, then the same member at a version that can read the written one — so a member referenced at an earlier compatible version of the package resolves against a later schema.Nonewhen this schema has no such member, which, as forenumsitself, means “not mine”, never “invalid”. - serialize
- Serialize a node to its normalized-JSON wire form.
$extraentries ride as sibling fields after the modeled ones; a modeled field wins a name collision ([JsonExtensionData]semantics). No$extrakey on the wire. Each integer and decimal value is written in its JSON form (kanonak-protocol 4.11.0’snumbers-in-json, runtime#54), through lists and embedded values: a wide integer (integer, its four sign-restricted forms,long,unsignedLong) and a decimal as a string of its canonical digits, a narrow integer (intand narrower) as a number. Takes a wide integer as a string of digits, ani64oru64number, or a whole number within ±(2^53 − 1); a decimal as a string of digits; a narrow integer as a whole number. Anything else, or a value outside its datatype’s range, is refused with an error ending[json-number-form].$typeis required, and its class is found asdeserializefinds it; an embedded value whose class the schema doesn’t hold is carried as given. An invalid$typesenvelope (at any depth) is a producer bug and fails at emit time, as does a fragment reference (runtime#6). - to_node
- A typed instance’s codec node (the dictionary contract). The bridge is
native serde: the instance serializes to its normalized-JSON wire form
(envelope-as-data +
Ref<T>values), and the wire form maps onto the node contract through the SAME splitcrate::deserializedefines — one contract, not two. Its values stay as the instance’s serde writes them. - type_
matches - Whether a node is an instance of the class
class_uri— what a generated type guard asks (runtime#28). Each of the node’s types ($types, else its$type) is resolved through the same compatible lookupdeserializeuses, so a node written at an earlier compatible version satisfies the later version’s guard; it matches when that class ISclass_urior has it among itsancestors. Classes compare by versionless identity. A type this schema cannot read (unknown, newer, another major) never matches. Errors whenclass_uriis not a class coordinate or the schema is malformed. For a typed instance,KanonakNode::type_matchesasks the same question of its envelope.
Type Aliases§
- Node
- A node is a JSON object.