Skip to main content

kinavis_ais/
error.rs

1//! Unarmouring, reassembly and decoding errors.
2
3use core::fmt;
4
5use kinavis_kernel::KernelError;
6
7/// Why a payload could not be unarmoured, reassembled or decoded.
8///
9/// `#[non_exhaustive]`; match with a wildcard arm.
10#[non_exhaustive]
11#[derive(Debug, Clone, PartialEq)]
12pub enum AisError {
13    /// Payload character outside the armouring alphabet.
14    BadArmouring {
15        /// Character offset in the payload.
16        offset: usize,
17    },
18    /// More fill bits than payload bits.
19    BadFill {
20        /// Fill bits declared.
21        fill_bits: u8,
22        /// Payload bits.
23        payload_bits: usize,
24    },
25    /// Longer than any defined message.
26    TooLong {
27        /// Total bits of the fragments.
28        bits: usize,
29        /// Maximum.
30        limit: usize,
31    },
32    /// Message shorter than a field of its type.
33    TooShort {
34        /// Message length in bits.
35        bits: usize,
36        /// Bits required by the type.
37        needed: usize,
38    },
39    /// Fragment not expected by the assembly: out of order, repeated, or
40    /// without a first fragment.
41    UnexpectedFragment {
42        /// Expected fragment number.
43        expected: u8,
44        /// Received fragment number.
45        found: u8,
46    },
47    /// Assembler built with zero slots.
48    NoSlot,
49    /// Field parsed but its value is outside the domain (latitude 95°, heading
50    /// 400°).
51    Value {
52        /// Field name: `"latitude"`, `"heading"`.
53        field: &'static str,
54        /// Domain error.
55        error: KernelError,
56    },
57}
58
59impl fmt::Display for AisError {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        match self {
62            Self::BadArmouring { offset } => {
63                write!(f, "payload character at offset {offset} is not armoured")
64            }
65            Self::BadFill {
66                fill_bits,
67                payload_bits,
68            } => write!(
69                f,
70                "{fill_bits} fill bits claimed of a payload of {payload_bits} bits"
71            ),
72            Self::TooLong { bits, limit } => {
73                write!(f, "message of {bits} bits exceeds the limit of {limit}")
74            }
75            Self::TooShort { bits, needed } => {
76                write!(f, "message of {bits} bits where {needed} are needed")
77            }
78            Self::UnexpectedFragment { expected, found } => {
79                write!(f, "fragment {found} where fragment {expected} was expected")
80            }
81            Self::NoSlot => f.write_str("the assembler has no slot for a message in fragments"),
82            Self::Value { field, error } => write!(f, "{field}: {error}"),
83        }
84    }
85}
86
87impl core::error::Error for AisError {}