use alloc::string::String;
use alloc::vec::Vec;
use zerodds_cdr::CorbaAny;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct EventType {
pub domain_name: String,
pub type_name: String,
}
impl EventType {
#[must_use]
pub fn new(domain: impl Into<String>, type_name: impl Into<String>) -> Self {
Self {
domain_name: domain.into(),
type_name: type_name.into(),
}
}
#[must_use]
pub fn matches(&self, pattern: &EventType) -> bool {
let dom = pattern.domain_name == "*" || pattern.domain_name == self.domain_name;
let typ = pattern.type_name == "*" || pattern.type_name == self.type_name;
dom && typ
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Property {
pub name: String,
pub value: CorbaAny,
}
impl Property {
#[must_use]
pub fn new(name: impl Into<String>, value: CorbaAny) -> Self {
Self {
name: name.into(),
value,
}
}
}
pub type PropertySeq = Vec<Property>;
#[derive(Debug, Clone, PartialEq, Default)]
pub struct FixedEventHeader {
pub event_type: EventType,
pub event_name: String,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct EventHeader {
pub fixed_header: FixedEventHeader,
pub variable_header: PropertySeq,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct StructuredEvent {
pub header: EventHeader,
pub filterable_data: PropertySeq,
pub remainder_of_body: CorbaAny,
}
impl StructuredEvent {
#[must_use]
pub fn new(
domain: impl Into<String>,
type_name: impl Into<String>,
event_name: impl Into<String>,
body: CorbaAny,
) -> Self {
Self {
header: EventHeader {
fixed_header: FixedEventHeader {
event_type: EventType::new(domain, type_name),
event_name: event_name.into(),
},
variable_header: PropertySeq::new(),
},
filterable_data: PropertySeq::new(),
remainder_of_body: body,
}
}
#[must_use]
pub fn event_type(&self) -> &EventType {
&self.header.fixed_header.event_type
}
#[must_use]
pub fn with_filterable(mut self, name: impl Into<String>, value: CorbaAny) -> Self {
self.filterable_data.push(Property::new(name, value));
self
}
#[must_use]
pub fn filterable(&self, name: &str) -> Option<&CorbaAny> {
self.filterable_data
.iter()
.find(|p| p.name == name)
.map(|p| &p.value)
}
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests {
use super::*;
use zerodds_cdr::AnyValue;
#[test]
fn event_type_wildcard_match() {
let e = EventType::new("Telecom", "CallEvent");
assert!(e.matches(&EventType::new("Telecom", "CallEvent")));
assert!(e.matches(&EventType::new("*", "CallEvent")));
assert!(e.matches(&EventType::new("Telecom", "*")));
assert!(e.matches(&EventType::new("*", "*")));
assert!(!e.matches(&EventType::new("Finance", "CallEvent")));
}
#[test]
fn structured_event_build_and_query() {
let ev = StructuredEvent::new(
"Telecom",
"CallEvent",
"call-42",
CorbaAny(AnyValue::Str("payload".into())),
)
.with_filterable("priority", CorbaAny(AnyValue::Long(7)));
assert_eq!(ev.event_type(), &EventType::new("Telecom", "CallEvent"));
assert_eq!(ev.header.fixed_header.event_name, "call-42");
assert_eq!(
ev.filterable("priority"),
Some(&CorbaAny(AnyValue::Long(7)))
);
assert_eq!(ev.filterable("missing"), None);
}
}