nmeasis 26.4.1

A memory-safe NMEA 0183 parser with a C FFI
Documentation
#[cfg_attr(feature = "c", repr(C))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Talker {
    // GNSS
    Gps,                // GP
    Glonass,            // GL
    Galileo,            // GA
    BeiDou,             // GB
    NavIc,              // GI
    Qzss,               // GQ
    MultiConstellation, // GN — combined

    // Autopilot
    AutopilotGeneral,  // AG
    AutopilotMagnetic, // AP

    // Communications
    Dsc,                // CD — Digital Selective Calling
    BeaconReceiver,     // CR
    SatelliteComms,     // CS
    RadioTelephoneMfHf, // CT
    RadioTelephoneVhf,  // CV
    ScanningReceiver,   // CX

    // Navigation
    DirectionFinder,           // DF
    Ecdis,                     // EC — Electronic Chart Display
    Loran,                     // LC
    IntegratedInstrumentation, // II
    IntegratedNavigation,      // IN
    Radar,                     // RA

    // Heading
    MagneticCompass,     // HC
    NorthSeekingGyro,    // HE
    NonNorthSeekingGyro, // HN

    // Depth / Sonar
    SonarDepth,          // SD
    ScanningEchosounder, // SS

    // Speed
    DopplerVelocity,    // VD
    MagneticSpeedLog,   // DM
    MechanicalSpeedLog, // VW

    // Other instruments
    WeatherInstruments, // WI
    Transducer,         // YX
    Epirb,              // EP
    EngineRoom,         // ER
    TurnRateIndicator,  // TI

    // Timekeepers
    AtomicClock, // ZA
    Chronometer, // ZC
    QuartzClock, // ZQ
    RadioClock,  // ZV

    // Proprietary
    Proprietary, // P — no talker, starts with $P

    // Unknown
    Unknown,
}

impl Talker {
    #[must_use]
    pub fn parse(s: &str) -> Self {
        match s {
            "GP" => Talker::Gps,
            "GL" => Talker::Glonass,
            "GA" => Talker::Galileo,
            // BD is legacy, GB is current
            "GB" | "BD" => Talker::BeiDou,
            "GI" => Talker::NavIc,
            "GQ" => Talker::Qzss,
            "GN" => Talker::MultiConstellation,
            "AG" => Talker::AutopilotGeneral,
            "AP" => Talker::AutopilotMagnetic,
            "CD" => Talker::Dsc,
            "CR" => Talker::BeaconReceiver,
            "CS" => Talker::SatelliteComms,
            "CT" => Talker::RadioTelephoneMfHf,
            "CV" => Talker::RadioTelephoneVhf,
            "CX" => Talker::ScanningReceiver,
            "DF" => Talker::DirectionFinder,
            "EC" => Talker::Ecdis,
            "EP" => Talker::Epirb,
            "ER" => Talker::EngineRoom,
            "HC" => Talker::MagneticCompass,
            "HE" => Talker::NorthSeekingGyro,
            "HN" => Talker::NonNorthSeekingGyro,
            "II" => Talker::IntegratedInstrumentation,
            "IN" | "SN" => Talker::IntegratedNavigation,
            "LC" => Talker::Loran,
            "P" => Talker::Proprietary,
            "RA" => Talker::Radar,
            "SD" => Talker::SonarDepth,
            "SS" => Talker::ScanningEchosounder,
            "TI" => Talker::TurnRateIndicator,
            "VD" => Talker::DopplerVelocity,
            "DM" => Talker::MagneticSpeedLog,
            "VW" => Talker::MechanicalSpeedLog,
            "WI" => Talker::WeatherInstruments,
            "YX" => Talker::Transducer,
            "ZA" => Talker::AtomicClock,
            "ZC" => Talker::Chronometer,
            "ZQ" => Talker::QuartzClock,
            "ZV" => Talker::RadioClock,
            _ => Talker::Unknown,
        }
    }

    /// True if this is any GNSS constellation talker
    #[must_use]
    pub fn is_gnss(&self) -> bool {
        matches!(
            self,
            Talker::Gps
                | Talker::Glonass
                | Talker::Galileo
                | Talker::BeiDou
                | Talker::NavIc
                | Talker::Qzss
                | Talker::MultiConstellation
        )
    }
}