Skip to main content

nmea_kit/ais/messages/
common.rs

1//! Common AIS types: NavigationStatus, ShipType.
2
3/// AIS Navigation Status (4 bits, 0-15).
4#[non_exhaustive]
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum NavigationStatus {
7    UnderWayEngine,
8    AtAnchor,
9    NotUnderCommand,
10    RestrictedManeuverability,
11    ConstrainedByDraught,
12    Moored,
13    Aground,
14    EngagedInFishing,
15    UnderWaySailing,
16    ReservedHsc,
17    ReservedWig,
18    Reserved(u8),
19    AisSartActive,
20    Undefined,
21}
22
23impl From<u8> for NavigationStatus {
24    fn from(val: u8) -> Self {
25        match val {
26            0 => Self::UnderWayEngine,
27            1 => Self::AtAnchor,
28            2 => Self::NotUnderCommand,
29            3 => Self::RestrictedManeuverability,
30            4 => Self::ConstrainedByDraught,
31            5 => Self::Moored,
32            6 => Self::Aground,
33            7 => Self::EngagedInFishing,
34            8 => Self::UnderWaySailing,
35            9 => Self::ReservedHsc,
36            10 => Self::ReservedWig,
37            14 => Self::AisSartActive,
38            15 => Self::Undefined,
39            other => Self::Reserved(other),
40        }
41    }
42}
43
44impl From<NavigationStatus> for u8 {
45    fn from(val: NavigationStatus) -> Self {
46        match val {
47            NavigationStatus::UnderWayEngine => 0,
48            NavigationStatus::AtAnchor => 1,
49            NavigationStatus::NotUnderCommand => 2,
50            NavigationStatus::RestrictedManeuverability => 3,
51            NavigationStatus::ConstrainedByDraught => 4,
52            NavigationStatus::Moored => 5,
53            NavigationStatus::Aground => 6,
54            NavigationStatus::EngagedInFishing => 7,
55            NavigationStatus::UnderWaySailing => 8,
56            NavigationStatus::ReservedHsc => 9,
57            NavigationStatus::ReservedWig => 10,
58            NavigationStatus::AisSartActive => 14,
59            NavigationStatus::Undefined => 15,
60            NavigationStatus::Reserved(v) => v,
61        }
62    }
63}
64
65/// AIS transceiver class, inferred from message type.
66#[non_exhaustive]
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum AisClass {
69    /// Class A — SOLAS vessels (Types 1/2/3/5)
70    A,
71    /// Class B "SO" — leisure/small craft (Type 18/24)
72    B,
73    /// Class B+ "CS" — enhanced Class B (Type 19)
74    BPlus,
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn nav_status_known_values() {
83        assert_eq!(NavigationStatus::from(0), NavigationStatus::UnderWayEngine);
84        assert_eq!(NavigationStatus::from(1), NavigationStatus::AtAnchor);
85        assert_eq!(NavigationStatus::from(5), NavigationStatus::Moored);
86        assert_eq!(NavigationStatus::from(8), NavigationStatus::UnderWaySailing);
87        assert_eq!(u8::from(NavigationStatus::Moored), 5);
88    }
89
90    #[test]
91    fn nav_status_roundtrip() {
92        for val in 0..=15u8 {
93            let status = NavigationStatus::from(val);
94            let back: u8 = status.into();
95            assert_eq!(val, back);
96        }
97    }
98}