use core::fmt;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BitError {
UnexpectedEof,
OutOfRange {
field: &'static str,
},
BufferFull,
}
impl fmt::Display for BitError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnexpectedEof => write!(f, "unexpected end of bit stream"),
Self::OutOfRange { field } => write!(f, "field width out of range: {field}"),
Self::BufferFull => write!(f, "output buffer is full"),
}
}
}
impl core::error::Error for BitError {}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NmeaError {
ChecksumMismatch {
expected: u8,
actual: u8,
},
MalformedSentence,
UnsupportedFormatter,
FieldCountMismatch,
InvalidFillBits,
InvalidArmorChar,
BufferTooSmall,
}
impl fmt::Display for NmeaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ChecksumMismatch { expected, actual } => {
write!(
f,
"checksum mismatch: expected {expected:02X}, got {actual:02X}"
)
}
Self::MalformedSentence => write!(f, "malformed NMEA sentence"),
Self::UnsupportedFormatter => write!(f, "unsupported talker/formatter"),
Self::FieldCountMismatch => write!(f, "unexpected number of comma-delimited fields"),
Self::InvalidFillBits => write!(f, "invalid fill-bits field"),
Self::InvalidArmorChar => write!(f, "invalid six-bit armor character"),
Self::BufferTooSmall => write!(f, "output buffer is too small"),
}
}
}
impl core::error::Error for NmeaError {}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FragmentError {
OutOfOrder,
SequenceIdMismatch,
ChannelMismatch,
BufferOverflow,
TooManyFragments,
}
impl fmt::Display for FragmentError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::OutOfOrder => write!(f, "fragment received out of order"),
Self::SequenceIdMismatch => write!(f, "fragment sequence id mismatch"),
Self::ChannelMismatch => write!(f, "fragment channel mismatch"),
Self::BufferOverflow => write!(f, "fragment reassembly buffer overflow"),
Self::TooManyFragments => write!(f, "too many fragments for this assembler"),
}
}
}
impl core::error::Error for FragmentError {}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageError {
UnknownMessageType(u8),
Bit(BitError),
InvalidEnumValue {
field: &'static str,
value: u32,
},
}
impl fmt::Display for MessageError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnknownMessageType(t) => write!(f, "unknown AIS message type: {t}"),
Self::Bit(e) => write!(f, "{e}"),
Self::InvalidEnumValue { field, value } => {
write!(f, "invalid value {value} for field {field}")
}
}
}
}
impl core::error::Error for MessageError {}
impl From<BitError> for MessageError {
fn from(e: BitError) -> Self {
Self::Bit(e)
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AisError {
Nmea(NmeaError),
Fragment(FragmentError),
Bit(BitError),
Message(MessageError),
IncompleteFragment,
}
impl fmt::Display for AisError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Nmea(e) => write!(f, "{e}"),
Self::Fragment(e) => write!(f, "{e}"),
Self::Bit(e) => write!(f, "{e}"),
Self::Message(e) => write!(f, "{e}"),
Self::IncompleteFragment => {
write!(f, "sentence is one fragment of a multi-part message")
}
}
}
}
impl core::error::Error for AisError {}
impl From<NmeaError> for AisError {
fn from(e: NmeaError) -> Self {
Self::Nmea(e)
}
}
impl From<FragmentError> for AisError {
fn from(e: FragmentError) -> Self {
Self::Fragment(e)
}
}
impl From<BitError> for AisError {
fn from(e: BitError) -> Self {
Self::Bit(e)
}
}
impl From<MessageError> for AisError {
fn from(e: MessageError) -> Self {
Self::Message(e)
}
}