#![cfg_attr(docsrs, feature(doc_auto_cfg))]
use anyhow::Context as _;
use serde::{Deserialize, Serialize, de::DeserializeOwned};
pub const WIRE_PROTOCOL_VERSION: u16 = 1;
pub const CONTROL_TOPIC: &str = "$ctrl";
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Envelope {
pub topic: String,
pub time_ns: u64,
pub payload: Vec<u8>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ControlMessage {
Hello {
codec: CodecKind,
version: u16,
},
Subscribe { topics: Vec<String> },
Unsubscribe { topics: Vec<String> },
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
pub enum CodecKind {
#[default]
Bincode,
Json,
}
impl CodecKind {
pub fn encode<T: Serialize>(self, value: &T) -> anyhow::Result<Vec<u8>> {
match self {
CodecKind::Bincode => bincode::serialize(value).context("wire codec: bincode encode"),
CodecKind::Json => serde_json::to_vec(value).context("wire codec: json encode"),
}
}
pub fn decode<T: DeserializeOwned>(self, bytes: &[u8]) -> anyhow::Result<T> {
match self {
CodecKind::Bincode => bincode::deserialize(bytes).context("wire codec: bincode decode"),
CodecKind::Json => serde_json::from_slice(bytes).context("wire codec: json decode"),
}
}
}