use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ZrecHeader {
pub zrec: u32,
pub selectors: Vec<String>,
pub base: String,
pub captured_at: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct RecordReport {
pub header: ZrecHeader,
#[serde(skip_serializing_if = "Option::is_none")]
pub out: Option<String>,
pub samples: u64,
pub dropped: u64,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct ReplayReport {
pub header: ZrecHeader,
pub dry_run: bool,
pub speed: f64,
pub published: u64,
pub tombstones: u64,
pub malformed: u64,
pub refused: u64,
pub capture_dropped: u64,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub first_errors: Vec<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize)]
pub struct SampleRow {
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub t: Option<u64>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub type_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub typed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub encoding: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub qos: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub qos_axes: Option<String>,
pub delete: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub bytes: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub payload_bytes: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachment: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachment_b64: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachment_bytes: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub verdict: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub violations: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub decode_error: Option<String>,
}
pub fn qos_axes_token(
priority: zenoh::qos::Priority,
congestion_control: zenoh::qos::CongestionControl,
reliability: zenoh::qos::Reliability,
express: bool,
) -> String {
use zenoh::qos::{CongestionControl as Cc, Priority as P, Reliability as R};
let p = match priority {
P::RealTime => "real_time",
P::InteractiveHigh => "interactive_high",
P::InteractiveLow => "interactive_low",
P::DataHigh => "data_high",
P::Data => "data",
P::DataLow => "data_low",
P::Background => "background",
};
let c = match congestion_control {
Cc::Drop => "drop",
Cc::Block => "block",
_ => "other",
};
let r = match reliability {
R::BestEffort => "best_effort",
R::Reliable => "reliable",
};
format!("{p}/{c}/{r}{}", if express { "+express" } else { "" })
}
#[cfg(test)]
mod qos_axes_tests {
use super::*;
use zenoh::qos::{CongestionControl as Cc, Priority as P, Reliability as R};
#[test]
fn the_axes_token_is_stable() {
assert_eq!(
qos_axes_token(P::Data, Cc::Drop, R::BestEffort, false),
"data/drop/best_effort"
);
assert_eq!(
qos_axes_token(P::RealTime, Cc::Block, R::Reliable, true),
"real_time/block/reliable+express"
);
assert_eq!(
qos_axes_token(P::InteractiveHigh, Cc::Block, R::Reliable, false),
"interactive_high/block/reliable"
);
assert_eq!(
qos_axes_token(P::Background, Cc::Drop, R::BestEffort, true),
"background/drop/best_effort+express"
);
}
#[test]
fn every_qos_profile_has_a_distinct_axes_token() {
let tokens: Vec<String> = zenkey::QosProfile::ALL
.iter()
.map(|p| {
qos_axes_token(
p.priority(),
p.congestion_control(),
p.reliability(),
p.express(),
)
})
.collect();
let mut unique = tokens.clone();
unique.sort();
unique.dedup();
assert_eq!(unique.len(), tokens.len(), "{tokens:?}");
}
}