Skip to main content

phoxal_bus/
metadata.rs

1//! `BusMetadata` - the per-sample attachment (D43c/D62/D1).
2//!
3//! The wire body is the plain MessagePack payload (D62); provenance +
4//! logical time ride here, in the Zenoh attachment. Identity (which contract,
5//! which version) is no longer carried in the envelope at all - it lives in
6//! the Zenoh key itself (the version is folded into
7//! `<Body as ContractBody>::TOPIC`, D1), so a receiver's per-key subscription is
8//! the whole fast-reject. `produced_at_ns`/`epoch`/`source` give logical-time +
9//! causality.
10
11use serde::{Deserialize, Serialize};
12
13use crate::abi::CodecId;
14
15/// Per-sample metadata carried in the Zenoh attachment (MessagePack-encoded).
16///
17/// Forward-compatibility: new fields are added as `Option`/defaulted so older
18/// decoders ignore them.
19#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
20pub struct BusMetadata {
21    /// The codec used for the body payload.
22    pub codec: u8,
23    /// Logical production time in nanoseconds (the clock's `time_ns`).
24    pub produced_at_ns: u64,
25    /// The clock epoch the timestamp belongs to (reset/restart counter).
26    pub epoch: u64,
27    /// The producing participant + sequence.
28    pub source: Source,
29}
30
31/// Producer identity + monotonic sequence (D43c).
32#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
33pub struct Source {
34    /// The participant id (`ParticipantLaunch.participant_id`, never the static
35    /// participant/artifact id - repeated component drivers must not collide, D53).
36    pub participant: String,
37    /// Per-process incarnation (bumped on restart).
38    pub incarnation: u64,
39    /// Per-producer monotonically increasing sample sequence.
40    pub sequence: u64,
41}
42
43impl BusMetadata {
44    /// Encode to the MessagePack attachment bytes.
45    pub fn encode(&self) -> Vec<u8> {
46        rmp_serde::to_vec_named(self).expect("BusMetadata is always serializable")
47    }
48
49    /// Decode from the MessagePack attachment bytes.
50    pub fn decode(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error> {
51        rmp_serde::from_slice(bytes)
52    }
53
54    /// The codec id, if recognized by this wire ABI.
55    pub fn codec_id(&self) -> Option<CodecId> {
56        CodecId::from_u8(self.codec)
57    }
58}