use kinavis::event::{AnchorEvent, ClearanceEvent, GuidanceEvent};
use kinavis_kernel::event::{Event, NavigationEvent, NavigationIntegrity, SensorHealth};
use kinavis_traffic::TrafficEvent;
use crate::{AlertKind, Ended};
pub trait Reportable: Event {
fn condition(&self) -> Option<AlertKind>;
fn ends(&self) -> Ended;
}
impl Reportable for NavigationEvent {
fn condition(&self) -> Option<AlertKind> {
match self {
Self::FixLost { source, .. } => Some(AlertKind::FixLost { source: *source }),
Self::IntegrityChanged { to, .. } if *to != NavigationIntegrity::Nominal => {
Some(AlertKind::IntegrityDegraded { to: *to })
}
Self::SensorHealthChanged { sensor, to, .. } if *to != SensorHealth::Healthy => {
Some(AlertKind::SensorSuspect { sensor: *sensor })
}
Self::ObservationRejected { .. } => Some(AlertKind::ObservationRejected),
_ => None,
}
}
fn ends(&self) -> Ended {
match self {
Self::FixAcquired { source, .. } => Ended::One(AlertKind::FixLost { source: *source }),
Self::SensorHealthChanged { sensor, to, .. } if *to == SensorHealth::Healthy => {
Ended::One(AlertKind::SensorSuspect { sensor: *sensor })
}
Self::IntegrityChanged { .. } => Ended::EveryIntegrityDegradation,
_ => Ended::Nothing,
}
}
}
impl Reportable for GuidanceEvent {
fn condition(&self) -> Option<AlertKind> {
match self {
Self::CrossTrackExceeded { .. } => Some(AlertKind::CrossTrackExceeded),
_ => None,
}
}
fn ends(&self) -> Ended {
Ended::Nothing
}
}
impl Reportable for ClearanceEvent {
fn condition(&self) -> Option<AlertKind> {
match self {
Self::UnderKeelClearanceLow { .. } => Some(AlertKind::UnderKeelClearanceLow),
_ => None,
}
}
fn ends(&self) -> Ended {
Ended::Nothing
}
}
impl Reportable for AnchorEvent {
fn condition(&self) -> Option<AlertKind> {
match self {
Self::AnchorDragging { .. } => Some(AlertKind::AnchorDragging),
_ => None,
}
}
fn ends(&self) -> Ended {
Ended::Nothing
}
}
impl Reportable for TrafficEvent {
fn condition(&self) -> Option<AlertKind> {
match self {
Self::CpaAlarm { target, .. } => Some(AlertKind::Cpa { target: *target }),
Self::TargetLost { target, .. } | Self::TargetEvicted { target, .. } => {
Some(AlertKind::TargetLost { target: *target })
}
Self::ObservationRejected { .. } => Some(AlertKind::ObservationRejected),
_ => None,
}
}
fn ends(&self) -> Ended {
match self {
Self::TargetLost { target, .. } | Self::TargetEvicted { target, .. } => {
Ended::One(AlertKind::Cpa { target: *target })
}
Self::TargetAcquired { target, .. } => {
Ended::One(AlertKind::TargetLost { target: *target })
}
_ => Ended::Nothing,
}
}
}