Skip to main content

cortexfs_channels/
wire.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{ChannelError, ChannelHealth, DeliveryReceipt, InboundMessage, OutboundMessage};
4
5/// Versioned JSON ABI shared by channel hosts and agent software.
6pub const CHANNEL_ABI: &str = "cortexfs.channel/v1";
7
8/// One framed event crossing a channel host boundary.
9#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
10pub struct ChannelEnvelope {
11    pub abi: String,
12    pub event: ChannelEvent,
13}
14
15impl ChannelEnvelope {
16    #[must_use]
17    pub fn inbound(message: InboundMessage) -> Self {
18        Self::new(ChannelEvent::Inbound(message))
19    }
20
21    #[must_use]
22    pub fn outbound(message: OutboundMessage) -> Self {
23        Self::new(ChannelEvent::Outbound(message))
24    }
25
26    #[must_use]
27    pub fn receipt(receipt: DeliveryReceipt) -> Self {
28        Self::new(ChannelEvent::Receipt(receipt))
29    }
30
31    #[must_use]
32    pub fn health(health: ChannelHealth) -> Self {
33        Self::new(ChannelEvent::Health(health))
34    }
35
36    #[must_use]
37    pub fn new(event: ChannelEvent) -> Self {
38        Self {
39            abi: CHANNEL_ABI.to_owned(),
40            event,
41        }
42    }
43
44    pub fn validate(&self) -> Result<(), ChannelError> {
45        if self.abi == CHANNEL_ABI {
46            Ok(())
47        } else {
48            Err(ChannelError::Protocol(format!(
49                "unsupported channel ABI: {}",
50                self.abi
51            )))
52        }
53    }
54}
55
56/// Event kinds intentionally remain small; platform details stay in metadata.
57#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
58#[serde(tag = "type", content = "value", rename_all = "snake_case")]
59pub enum ChannelEvent {
60    Inbound(InboundMessage),
61    Outbound(OutboundMessage),
62    Receipt(DeliveryReceipt),
63    Health(ChannelHealth),
64}