1#[non_exhaustive]
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum FrameError {
5 Empty,
7 InvalidPrefix(char),
9 MalformedChecksum,
11 BadChecksum { expected: u8, computed: u8 },
13 MalformedTagBlock,
15 BadTagChecksum { expected: u8, computed: u8 },
17 TooShort,
20 NonAsciiAddress,
22}
23
24impl core::fmt::Display for FrameError {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 match self {
27 Self::Empty => write!(f, "empty input"),
28 Self::InvalidPrefix(c) => write!(f, "invalid prefix '{c}', expected '$' or '!'"),
29 Self::MalformedChecksum => write!(f, "checksum is not valid hexadecimal"),
30 Self::BadChecksum { expected, computed } => {
31 write!(
32 f,
33 "checksum mismatch: expected {expected:02X}, computed {computed:02X}"
34 )
35 }
36 Self::MalformedTagBlock => write!(f, "malformed IEC 61162-450 tag block"),
37 Self::BadTagChecksum { expected, computed } => {
38 write!(
39 f,
40 "tag block checksum mismatch: expected {expected:02X}, computed {computed:02X}"
41 )
42 }
43 Self::TooShort => write!(f, "sentence too short"),
44 Self::NonAsciiAddress => write!(f, "address field contains non-ASCII bytes"),
45 }
46 }
47}
48
49impl std::error::Error for FrameError {}
50
51#[non_exhaustive]
53#[derive(Debug, Clone, PartialEq, Eq)]
54pub enum EncodeError {
55 InvalidPrefix(char),
57 NonAsciiAddress,
59 EmptySentenceType,
61 InvalidFieldCharacter(char),
63 InvalidCoordinate,
65 InvalidAisField(&'static str),
67 AisTextTooLong {
69 field: &'static str,
70 max_chars: usize,
71 actual_chars: usize,
72 },
73 MissingAisSequenceId,
75 TooManyAisFragments,
77}
78
79impl core::fmt::Display for EncodeError {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 match self {
82 Self::InvalidPrefix(c) => write!(f, "invalid prefix '{c}', expected '$' or '!'"),
83 Self::NonAsciiAddress => write!(f, "talker or sentence type is not ASCII"),
84 Self::EmptySentenceType => write!(f, "sentence type is empty"),
85 Self::InvalidFieldCharacter(c) => {
86 write!(f, "field contains invalid character {c:?}")
87 }
88 Self::InvalidCoordinate => {
89 write!(f, "coordinate magnitude is NaN, infinite, or negative")
90 }
91 Self::InvalidAisField(field) => write!(f, "invalid AIS field {field}"),
92 Self::AisTextTooLong {
93 field,
94 max_chars,
95 actual_chars,
96 } => write!(
97 f,
98 "AIS field {field} is too long: {actual_chars} characters, maximum {max_chars}"
99 ),
100 Self::MissingAisSequenceId => {
101 write!(
102 f,
103 "multi-fragment AIS payload requires a sequential message ID"
104 )
105 }
106 Self::TooManyAisFragments => {
107 write!(
108 f,
109 "AIS payload exceeds the five-fragment transmission limit"
110 )
111 }
112 }
113 }
114}
115
116impl std::error::Error for EncodeError {}