use std::sync::Arc;
use crate::ports::EventSink;
pub struct CompositeSink {
sinks: Vec<Arc<dyn EventSink>>,
}
impl CompositeSink {
pub fn new(sinks: Vec<Arc<dyn EventSink>>) -> Self {
Self { sinks }
}
pub fn empty() -> Self {
Self { sinks: Vec::new() }
}
}
impl EventSink for CompositeSink {
fn emit(&self, payload: &str) {
for sink in &self.sinks {
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
sink.emit(payload);
}));
}
}
fn flush(&self) {
for sink in &self.sinks {
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
sink.flush();
}));
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::MemoryEventSink;
struct ContractHarness {
composite: CompositeSink,
inner: Arc<MemoryEventSink>,
}
impl ContractHarness {
fn new() -> Self {
let inner = Arc::new(MemoryEventSink::new());
let composite = CompositeSink::new(vec![inner.clone()]);
Self { composite, inner }
}
fn drain(&self) -> Vec<String> {
self.inner.drain()
}
}
impl EventSink for ContractHarness {
fn emit(&self, payload: &str) {
self.composite.emit(payload);
}
fn flush(&self) {
self.composite.flush();
}
}
crate::event_sink_contract_tests!(composite_contract, ContractHarness::new());
}