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 {}