use ainl_contracts::{MissionEvent, MissionId, MissionState};
use thiserror::Error;
pub trait MissionEventSink {
fn emit(&self, event: &MissionEvent) -> Result<(), MissionEventError>;
fn emit_state_changed(
&self,
mission_id: &MissionId,
from: MissionState,
to: MissionState,
) -> Result<(), MissionEventError> {
self.emit(&MissionEvent::MissionStateChanged {
mission_id: mission_id.clone(),
from,
to,
})
}
}
#[derive(Debug, Error)]
pub enum MissionEventError {
#[error("emit failed: {0}")]
Emit(String),
}
#[cfg(test)]
mod tests {
use super::*;
use ainl_contracts::MissionEvent;
use std::cell::RefCell;
struct VecSink(RefCell<Vec<MissionEvent>>);
impl MissionEventSink for VecSink {
fn emit(&self, event: &MissionEvent) -> Result<(), MissionEventError> {
self.0.borrow_mut().push(event.clone());
Ok(())
}
}
#[test]
fn state_changed_helper() {
let sink = VecSink(RefCell::new(Vec::new()));
let id = MissionId("m1".into());
sink.emit_state_changed(&id, MissionState::Running, MissionState::Paused)
.unwrap();
let events = sink.0.borrow();
assert!(matches!(
events[0],
MissionEvent::MissionStateChanged { .. }
));
}
}