pub mod aam;
pub mod gga;
pub mod gll;
pub mod gns;
pub mod gsa;
pub mod gst;
pub mod gsv;
pub mod rmc;
pub mod txt;
pub mod vtg;
pub mod zda;
use crate::encoder::NmeaEncode;
use crate::message::aam::Aam;
use crate::message::gga::Gga;
use crate::message::gll::Gll;
use crate::message::gns::Gns;
use crate::message::gsa::Gsa;
use crate::message::gst::Gst;
use crate::message::gsv::Gsv;
use crate::message::rmc::Rmc;
use crate::message::txt::Txt;
use crate::message::vtg::Vtg;
use crate::message::zda::Zda;
use crate::parser::NmeaParse;
#[derive(Debug, thiserror::Error)]
pub enum NmeaMessageError {
#[error("Message is not UTF8")]
NotUtf8(#[from] core::str::Utf8Error),
#[error("Message is missing field")]
MissingField,
#[error("Message has an invalid field")]
InvalidField,
#[error("Number is malformed")]
MalformedNumber,
}
macro_rules! define_messages {
($($variant:ident => $type:ty, $code:literal),* $(,)?) => {
#[derive(Debug)]
pub enum Message<'a> {
$($variant($type),)*
Unknown(&'a str),
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageType {
$($variant,)*
Unknown,
}
impl<'a> From<&Message<'a>> for MessageType {
fn from(value: &Message<'a>) -> Self {
match value {
$(Message::$variant(_) => Self::$variant,)*
Message::Unknown(_) => Self::Unknown,
}
}
}
impl<'a> Message<'a> {
pub(crate) fn parse(code: &'a str, fields: &'a str) -> Result<Self, NmeaMessageError> {
Ok(match code {
$($code => Message::$variant(<$type>::parse(fields)?),)*
_ => Message::Unknown(code),
})
}
pub fn code(&self) -> &str {
match self {
$(Message::$variant(_) => $code,)*
Message::Unknown(code) => code,
}
}
}
impl NmeaEncode for Message<'_> {
fn encoded_len(&self) -> usize {
match self {
$(Message::$variant(m) => m.encoded_len(),)*
Message::Unknown(_) => 0,
}
}
fn encode(&self, buf: &mut [u8]) -> usize {
match self {
$(Message::$variant(m) => m.encode(buf),)*
Message::Unknown(_) => 0,
}
}
}
}
}
define_messages!(
Aam => Aam<'a>, "AAM",
Gga => Gga<'a>, "GGA",
Gll => Gll<'a>, "GLL",
Gns => Gns<'a>, "GNS",
Gsa => Gsa<'a>, "GSA",
Gst => Gst<'a>, "GST",
Gsv => Gsv<'a>, "GSV",
Rmc => Rmc<'a>, "RMC",
Txt => Txt<'a>, "TXT",
Vtg => Vtg<'a>, "VTG",
Zda => Zda<'a>, "ZDA",
);