use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct StructuredEventLite {
pub event_type: String,
pub event_name: String,
pub filterable: Vec<(String, Vec<u8>)>,
pub remainder_body: Vec<u8>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct NotifyChannelMap {
topics: BTreeMap<String, String>,
}
impl NotifyChannelMap {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn map(&mut self, dds_topic: impl Into<String>, channel: impl Into<String>) {
self.topics.insert(dds_topic.into(), channel.into());
}
#[must_use]
pub fn channel_for(&self, dds_topic: &str) -> Option<&str> {
self.topics.get(dds_topic).map(String::as_str)
}
#[must_use]
pub fn topic_for_channel(&self, channel: &str) -> Option<&str> {
self.topics
.iter()
.find(|(_, c)| c.as_str() == channel)
.map(|(t, _)| t.as_str())
}
#[must_use]
pub fn len(&self) -> usize {
self.topics.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.topics.is_empty()
}
}
#[must_use]
pub fn dds_to_structured_event(topic: &str, payload: &[u8]) -> StructuredEventLite {
StructuredEventLite {
event_type: format!("zerodds::{topic}"),
event_name: "dds.publish".into(),
filterable: Vec::new(),
remainder_body: payload.to_vec(),
}
}
#[must_use]
pub fn structured_event_to_dds(event: &StructuredEventLite) -> Vec<u8> {
event.remainder_body.clone()
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn map_lookup_round_trip() {
let mut m = NotifyChannelMap::new();
m.map("Trade", "ChannelA");
m.map("Quote", "ChannelB");
assert_eq!(m.channel_for("Trade"), Some("ChannelA"));
assert_eq!(m.topic_for_channel("ChannelB"), Some("Quote"));
assert_eq!(m.len(), 2);
}
#[test]
fn unknown_channel_returns_none() {
let m = NotifyChannelMap::new();
assert_eq!(m.channel_for("nope"), None);
assert!(m.is_empty());
}
#[test]
fn dds_to_event_carries_payload_in_remainder() {
let ev = dds_to_structured_event("Trade", b"AAPL@200");
assert_eq!(ev.event_type, "zerodds::Trade");
assert_eq!(ev.event_name, "dds.publish");
assert_eq!(ev.remainder_body, b"AAPL@200");
}
#[test]
fn round_trip_dds_event_dds() {
let payload = b"hello".to_vec();
let ev = dds_to_structured_event("X", &payload);
let back = structured_event_to_dds(&ev);
assert_eq!(back, payload);
}
}