use crate::ais::armor::{extract_i32, extract_string, extract_u32};
use super::utils::{decode_latitude, decode_longitude};
#[derive(Debug, Clone, PartialEq)]
pub struct AidToNavigation {
pub mmsi: u32,
pub aid_type: u8,
pub name: String,
pub lat: Option<f64>,
pub lon: Option<f64>,
}
impl AidToNavigation {
pub(crate) fn decode(bits: &[u8]) -> Option<Self> {
if bits.len() < 272 {
return None;
}
let mmsi = extract_u32(bits, 8, 30)?;
let aid_type = extract_u32(bits, 38, 5)? as u8;
let name = extract_string(bits, 43, 20)?;
let lon_raw = extract_i32(bits, 164, 28)?;
let lat_raw = extract_i32(bits, 192, 27)?;
Some(Self {
mmsi,
aid_type,
name,
lat: decode_latitude(lat_raw),
lon: decode_longitude(lon_raw),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ais::messages::test_helpers::set_bits;
#[test]
fn aton_name_preserves_leading_space() {
let mut bits = vec![0u8; 272];
set_bits(&mut bits, 0, 6, 21); set_bits(&mut bits, 43, 6, 32); set_bits(&mut bits, 49, 6, 1); let aton = AidToNavigation::decode(&bits).expect("decode");
assert_eq!(
aton.name, " A",
"leading space must be preserved (trailing-only trim)"
);
}
}