mod airborne_position;
mod airborne_velocity;
mod identification;
mod surface_position;
pub mod cpr;
pub use airborne_position::{AirbornePosition, Altitude, PositionPair};
pub use airborne_velocity::{AirborneVelocity, VelocityData};
pub use cpr::CprFormat;
pub use identification::{CallSign, Identification};
pub use surface_position::{
SurfacePosition, SurfacePositionPair, decode_movement, encode_movement,
};
use crate::bits::{BitReader, BitWriter};
use crate::error::{BitError, MessageError};
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum AdsbMessage {
Identification(Identification),
SurfacePosition(SurfacePosition),
AirbornePosition(AirbornePosition),
AirborneVelocity(AirborneVelocity),
}
impl AdsbMessage {
pub(crate) fn decode(me: &[u8]) -> Result<Self, MessageError> {
let mut r = BitReader::new(me);
let type_code = r.read_u8(5)?;
match type_code {
1..=4 => Ok(Self::Identification(Identification::decode(
type_code, &mut r,
)?)),
5..=8 => Ok(Self::SurfacePosition(SurfacePosition::decode(
type_code, &mut r,
)?)),
9..=18 | 20..=22 => Ok(Self::AirbornePosition(AirbornePosition::decode(
type_code, &mut r,
)?)),
19 => Ok(Self::AirborneVelocity(AirborneVelocity::decode(&mut r)?)),
other => Err(MessageError::UnknownTypeCode(other)),
}
}
pub(crate) fn encode(&self, w: &mut BitWriter<'_>) -> Result<(), BitError> {
match self {
Self::Identification(m) => m.encode(w),
Self::SurfacePosition(m) => m.encode(w),
Self::AirbornePosition(m) => m.encode(w),
Self::AirborneVelocity(m) => m.encode(w),
}
}
}
#[cfg(test)]
mod proptests {
use proptest::prelude::*;
use super::AdsbMessage;
use crate::bits::BitWriter;
proptest! {
#[test]
fn decode_never_panics(me: [u8; 7]) {
let _ = AdsbMessage::decode(&me);
}
#[test]
fn decode_encode_decode_reaches_a_fixed_point(me: [u8; 7]) {
if let Ok(msg) = AdsbMessage::decode(&me) {
let msg2 = encode_then_decode(&msg);
let msg3 = encode_then_decode(&msg2);
prop_assert_eq!(msg2, msg3);
}
}
}
fn encode_then_decode(msg: &AdsbMessage) -> AdsbMessage {
let mut buf = [0u8; 7];
let mut w = BitWriter::new(&mut buf);
msg.encode(&mut w).unwrap();
AdsbMessage::decode(&buf).expect("re-encoded ME must still decode")
}
}