nmea_kit/ais/messages/
assignment_mode.rs1use crate::ais::armor::extract_u32;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Assignment {
8 pub destination_mmsi: u32,
9 pub offset: u16,
10 pub increment: u16,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct AssignmentModeCommand {
16 pub repeat_indicator: u8,
17 pub mmsi: u32,
18 pub assignments: Vec<Assignment>,
20}
21
22impl AssignmentModeCommand {
23 pub(crate) fn decode(bits: &[u8]) -> Option<Self> {
24 if bits.len() < 96 {
25 return None;
26 }
27 let mut assignments = vec![decode_assignment(bits, 40)?];
28 if bits.len() >= 144 {
29 assignments.push(decode_assignment(bits, 92)?);
30 }
31 Some(Self {
32 repeat_indicator: extract_u32(bits, 6, 2)? as u8,
33 mmsi: extract_u32(bits, 8, 30)?,
34 assignments,
35 })
36 }
37}
38
39fn decode_assignment(bits: &[u8], offset: usize) -> Option<Assignment> {
40 Some(Assignment {
41 destination_mmsi: extract_u32(bits, offset, 30)?,
42 offset: extract_u32(bits, offset + 30, 12)? as u16,
43 increment: extract_u32(bits, offset + 42, 10)? as u16,
44 })
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use crate::ais::messages::test_helpers::set_bits;
51
52 #[test]
53 fn decodes_two_assignments() {
54 let mut bits = vec![0; 144];
55 set_bits(&mut bits, 0, 6, 16);
56 set_bits(&mut bits, 6, 2, 1);
57 set_bits(&mut bits, 8, 30, 123_456_789);
58 set_bits(&mut bits, 40, 30, 111_111_111);
59 set_bits(&mut bits, 70, 12, 100);
60 set_bits(&mut bits, 82, 10, 25);
61 set_bits(&mut bits, 92, 30, 222_222_222);
62 set_bits(&mut bits, 122, 12, 200);
63 set_bits(&mut bits, 134, 10, 50);
64
65 let message = AssignmentModeCommand::decode(&bits).expect("decode");
66 assert_eq!(message.repeat_indicator, 1);
67 assert_eq!(message.mmsi, 123_456_789);
68 assert_eq!(
69 message.assignments,
70 vec![
71 Assignment {
72 destination_mmsi: 111_111_111,
73 offset: 100,
74 increment: 25,
75 },
76 Assignment {
77 destination_mmsi: 222_222_222,
78 offset: 200,
79 increment: 50,
80 },
81 ]
82 );
83 }
84}