Background
A record type T: Linkable has exactly one codec pair —
T::from_bytes / T::to_bytes (aimdb-data-contracts/src/lib.rs:252) — and every
link uses it. The .linked_from(url) / .linked_to(url) verbs
(aimdb-data-contracts/src/linkable.rs:21) default both directions onto that one
pair, which is the right 80% behaviour.
But the mesh templates will want the same record mirrored over two links with
different wire formats — postcard toward a constrained MCU peer and JSON
toward the cloud/dashboard. Today the only way to do that is to bypass the
one-line verbs and hand-write the raw .with_serializer() / .with_deserializer()
builders per link (aimdb-data-contracts/src/linkable.rs:37,43), which drops the
ergonomics and re-introduces exactly the codec boilerplate the Linkable verbs
exist to remove.
Proposal
Let the codec be chosen per link while keeping the default intact. Sketch:
// Default (unchanged): uses T::from_bytes / T::to_bytes
reg.linked_to("mqtt://cloud/telemetry");
// Per-link override: same T, different codec toward the MCU
reg.linked_to_with("serial://mcu", Codec::Postcard);
Shape TBD — a codec selector argument on a *_with variant, or a codec marker
threaded into the link builder that dispatches to the matching (de)serializer.
.linked_from / .linked_to keep defaulting to T::from_bytes / T::to_bytes.
Why it's interesting
- Composes with the existing byte seam — the codecs already exist
(emit_linkable_postcard at aimdb-codegen/src/rust.rs:996, JSON via
linkable-json); this is about selecting one per link, not adding formats.
Constraints / risks
- A record's
Linkable impl is a single trait impl, so "a different codec per
link" cannot live on the type — it has to be expressed at link-wiring time
(builder/registrar level), which is the design question to settle.
- Must not regress the one-line default path or the raw-builder escape hatch.
Scope
Registrar/builder ergonomics only. No change to the self-describing
(AimX/MCP/CLI) paths.
Background
A record type
T: Linkablehas exactly one codec pair —T::from_bytes/T::to_bytes(aimdb-data-contracts/src/lib.rs:252) — and everylink uses it. The
.linked_from(url)/.linked_to(url)verbs(
aimdb-data-contracts/src/linkable.rs:21) default both directions onto that onepair, which is the right 80% behaviour.
But the mesh templates will want the same record mirrored over two links with
different wire formats — postcard toward a constrained MCU peer and JSON
toward the cloud/dashboard. Today the only way to do that is to bypass the
one-line verbs and hand-write the raw
.with_serializer()/.with_deserializer()builders per link (
aimdb-data-contracts/src/linkable.rs:37,43), which drops theergonomics and re-introduces exactly the codec boilerplate the
Linkableverbsexist to remove.
Proposal
Let the codec be chosen per link while keeping the default intact. Sketch:
Shape TBD — a codec selector argument on a
*_withvariant, or a codec markerthreaded into the link builder that dispatches to the matching (de)serializer.
.linked_from/.linked_tokeep defaulting toT::from_bytes/T::to_bytes.Why it's interesting
(
emit_linkable_postcardataimdb-codegen/src/rust.rs:996, JSON vialinkable-json); this is about selecting one per link, not adding formats.Constraints / risks
Linkableimpl is a single trait impl, so "a different codec perlink" cannot live on the type — it has to be expressed at link-wiring time
(builder/registrar level), which is the design question to settle.
Scope
Registrar/builder ergonomics only. No change to the self-describing
(AimX/MCP/CLI) paths.