pub trait ContractBody:
Serialize
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ 'static {
type Api: ApiVersion;
const NAME: &'static str;
const VERSION: &'static str;
const CONTRACT: &'static str;
const TOPIC: &'static str;
const ROLE: TopicRole;
}Expand description
The contract primitive traits, re-exported from the phoxal-bus crate (the
ABI floor) so they stay addressable at phoxal_api::ApiVersion /
phoxal_api::ContractBody.
ApiVersionis the marker trait identifying one API version (D60), implemented only by the zero-variantenum Api {}thatphoxal_api_tree!generates inside each revision module; itsIDis the concrete dotted wire identity (for example"v0.1").ContractBodyis a version-local wire body (D61): a plain serde type bound to exactly oneApiVersionand one contract topic. Every body declared inside aphoxal_api_tree!node gets a generated impl; handles,SetupContextbuilders, and theService/Driverderive assertions key off itsApi/TOPIC.TOPICis version-qualified (D1) and is the compatibility key; its serde encoding is the wire payload, with no version envelope (D62). A version-local wire body: a plain serde type bound to exactly oneApiVersionand one contract topic (D61/D1).
Every body declared inside a phoxal_api_tree! node gets a generated impl.
Each body carries its own Api version marker and
version-qualified TOPIC.
Participant setup builders accept these bodies directly and preserve the
contract type through each typed handle.
The serde encoding of an implementor is the wire payload; there is no version envelope (D62).
Wire identity is the key, not a hash (D1). The version is folded into
TOPIC, so v0.1::drive::Target and a
hypothetically re-minted v0.2::drive::Target publish on different Zenoh
keys and physically cannot collide. Two participants interoperate on a
contract iff they use the exact same version-qualified name, which is
realized on the wire by the key.
A receiver’s per-key Zenoh subscription is the
whole fast-reject; the bus decode path validates only the codec.
Required Associated Constants§
Sourceconst NAME: &'static str
const NAME: &'static str
The version-qualified type identity: the dotted wire revision, then the ::-joined node path
(dynamic-node vars are topic params, never type-path segments), then
the PascalCase type leaf, e.g. "v0.1::drive::Target" or
"v0.1::component::motor::Command". This is the contract’s source
identity (D1) - two contracts interoperate iff they share this exact
name - as distinct from TOPIC, the resolved
wire key derived from it. NAME is exactly the "::"-join of
VERSION and
CONTRACT; it stays available for callers
that want the whole identity as one string (e.g. display), while
consumers that must reason about the revision and the contract
independently use the two split consts instead - a joined name is not
machine-parseable without assuming the version naming scheme.
Sourceconst VERSION: &'static str
const VERSION: &'static str
This body’s dotted wire revision alone, e.g. "v0.1" - equal to
<Self::Api as ApiVersion>::ID, but exposed directly on the body so a
metadata or diagnostics recorder can const-splice it without routing
through Self::Api.
Split from CONTRACT so a consumer can read
the revision without parsing a joined name.
Sourceconst CONTRACT: &'static str
const CONTRACT: &'static str
This body’s contract path within its own version: the ::-joined
node path (dynamic-node vars excluded, as with NAME) plus the
PascalCase type leaf, e.g. "drive::Target". The logical
contract - stable across a version bump - is this value alone;
pairing it with VERSION recovers the
full version-qualified identity (NAME).
Sourceconst TOPIC: &'static str
const TOPIC: &'static str
The version-qualified wire key: the dotted wire revision, then the
/-joined node path plus the topic leaf, with each dynamic node
contributing a {var} placeholder, e.g. "v0.1/drive/state" or
"v0.1/component/{instance}/motor/{capability}/command". The concrete
key is produced by the api-local topic builder, which fills the
placeholders.
Required Associated Types§
Sourcetype Api: ApiVersion
type Api: ApiVersion
The single API version this body belongs to. Two bodies from different
versions have different Api, so the type system keeps them apart.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".