use crate::ais::AisPositionReport;
use crate::error::Nmea2000Error;
use crate::frame::Payload;
use crate::gnss::GnssPosition;
use crate::id::Pgn;
use crate::navigation::{CourseAndSpeed, PositionRapidUpdate, VesselHeading, WaterDepth};
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Message {
PositionRapidUpdate(PositionRapidUpdate),
CourseAndSpeed(CourseAndSpeed),
GnssPosition(GnssPosition),
VesselHeading(VesselHeading),
WaterDepth(WaterDepth),
AisPositionReport(AisPositionReport),
Unsupported {
pgn: Pgn,
},
}
impl Message {
pub fn decode(payload: &Payload) -> Result<Self, Nmea2000Error> {
let pgn = payload.pgn();
Ok(match pgn {
Pgn::POSITION_RAPID_UPDATE => {
Self::PositionRapidUpdate(PositionRapidUpdate::decode(payload)?)
}
Pgn::COG_SOG_RAPID_UPDATE => Self::CourseAndSpeed(CourseAndSpeed::decode(payload)?),
Pgn::GNSS_POSITION_DATA => Self::GnssPosition(GnssPosition::decode(payload)?),
Pgn::VESSEL_HEADING => Self::VesselHeading(VesselHeading::decode(payload)?),
Pgn::WATER_DEPTH => Self::WaterDepth(WaterDepth::decode(payload)?),
Pgn::AIS_CLASS_A_POSITION_REPORT => {
Self::AisPositionReport(AisPositionReport::class_a(payload)?)
}
Pgn::AIS_CLASS_B_POSITION_REPORT => {
Self::AisPositionReport(AisPositionReport::class_b(payload)?)
}
_ => Self::Unsupported { pgn },
})
}
}