use async_trait::async_trait;
use futures::Stream;
use peat_protocol::cot::CotEvent;
use std::pin::Pin;
use crate::error::TakError;
use crate::metrics::{QueueDepthMetrics, TakMetrics};
pub type Priority = u8;
pub type CotEventStream = Pin<Box<dyn Stream<Item = Result<CotEvent, TakError>> + Send>>;
#[derive(Debug, Clone, Default)]
pub struct CotFilter {
pub type_prefix: Option<String>,
pub uid_pattern: Option<String>,
pub callsign: Option<String>,
pub max_age_secs: Option<u64>,
}
impl CotFilter {
pub fn all() -> Self {
Self::default()
}
pub fn with_type_prefix(mut self, prefix: impl Into<String>) -> Self {
self.type_prefix = Some(prefix.into());
self
}
pub fn with_uid_pattern(mut self, pattern: impl Into<String>) -> Self {
self.uid_pattern = Some(pattern.into());
self
}
pub fn with_callsign(mut self, callsign: impl Into<String>) -> Self {
self.callsign = Some(callsign.into());
self
}
pub fn with_max_age(mut self, secs: u64) -> Self {
self.max_age_secs = Some(secs);
self
}
pub fn matches(&self, event: &CotEvent) -> bool {
if let Some(prefix) = &self.type_prefix {
if !event.cot_type.as_str().starts_with(prefix) {
return false;
}
}
if let Some(pattern) = &self.uid_pattern {
if !event.uid.contains(pattern) {
return false;
}
}
true
}
}
#[async_trait]
pub trait TakTransport: Send + Sync {
async fn connect(&mut self) -> Result<(), TakError>;
async fn disconnect(&mut self) -> Result<(), TakError>;
async fn send_cot(&self, event: &CotEvent, priority: Priority) -> Result<(), TakError>;
async fn subscribe(&self, filter: CotFilter) -> Result<CotEventStream, TakError>;
fn is_connected(&self) -> bool;
fn metrics(&self) -> TakMetrics;
fn queue_depth(&self) -> QueueDepthMetrics;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cot_filter_all() {
let filter = CotFilter::all();
assert!(filter.type_prefix.is_none());
assert!(filter.uid_pattern.is_none());
}
#[test]
fn test_cot_filter_builder() {
let filter = CotFilter::all()
.with_type_prefix("a-f-")
.with_uid_pattern("Peat-")
.with_max_age(300);
assert_eq!(filter.type_prefix.as_deref(), Some("a-f-"));
assert_eq!(filter.uid_pattern.as_deref(), Some("Peat-"));
assert_eq!(filter.max_age_secs, Some(300));
}
}