1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::convert::From;
use std::error::Error;
use std::fmt;

/// Error type used to convey parsing errors.
#[derive(Debug)]
pub struct ParserError(String);

impl fmt::Display for ParserError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl Error for ParserError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl<T> From<nom::Err<T>> for ParserError
where
    nom::Err<T>: std::fmt::Debug,
{
    fn from(error: nom::Err<T>) -> Self {
        ParserError(format!("{:?}", error))
    }
}

/// Unique 24-bit ICAO address assigned to an aircraft upon national registration.
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub struct ICAOAddress(pub(crate) u8, pub(crate) u8, pub(crate) u8);

impl fmt::Display for ICAOAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:02X}{:02X}{:02X}", self.0, self.1, self.2)
    }
}

/// Horizontal coordinates in the geographic coordinate system.
#[derive(Debug, PartialEq, Clone)]
pub struct Position {
    pub latitude: f64,
    pub longitude: f64,
}

/// Aircraft position is broadcast as a set of alternating odd and even frames
/// which encode position information using Compact Position Reporting (CPR).
#[derive(Debug, PartialEq, Clone)]
pub struct CPRFrame {
    /// Aircraft position in CPR format
    pub position: Position,
    /// Frame parity
    pub parity: Parity,
}

/// Frame parity.
#[derive(Debug, PartialEq, Clone)]
pub enum Parity {
    Even,
    Odd,
}

/// Source for vertical rate information.
#[derive(Debug, PartialEq, Clone)]
pub enum VerticalRateSource {
    /// Barometric pressure altitude change rate
    BarometricPressureAltitude,
    /// Geometric altitude change rate
    GeometricAltitude,
}

/// ADS-B/Mode-S message.
#[derive(Debug)]
pub struct Message {
    /// Downlink Format (DF)
    pub downlink_format: u8,
    /// Kind of message
    pub kind: MessageKind,
}

/// Kind of ADS-B/Mode-S message.
#[derive(Debug, PartialEq, Clone)]
pub enum MessageKind {
    /// ADSB message (DF 17)
    ADSBMessage {
        capability: u8,
        icao_address: ICAOAddress,
        type_code: u8,
        kind: ADSBMessageKind,
    },
    /// Unsupported message
    Unknown,
}

/// Kind of ADSB message.
#[derive(Debug, PartialEq, Clone)]
pub enum ADSBMessageKind {
    /// Aicraft identification and category message (TC 1-4)
    AircraftIdentification {
        /// Emitter category used to determine the type of aircraft
        emitter_category: u8,
        /// Aircraft callsign
        callsign: String,
    },
    /// Airborne position message (TC 9-18)
    AirbornePosition {
        /// Altitude in feet
        altitude: u16,
        /// Odd or even frame encoding position information in CPR format
        cpr_frame: CPRFrame,
    },
    /// Airborne velocity message (TC 19)
    AirborneVelocity {
        /// Heading in degrees
        heading: f64,
        /// Ground speed in knots
        ground_speed: f64,
        /// Vertical rate in feet per minute, positive values indicate an aircraft is climbing and
        /// negative values indicate it is descending
        vertical_rate: i16,
        /// Source for vertical rate information
        vertical_rate_source: VerticalRateSource,
    },
}