use super::consts;
#[derive(
Debug,
Copy,
Clone,
Ord,
PartialOrd,
Eq,
PartialEq,
Hash,
strum::AsRefStr,
strum::Display,
strum::EnumIter,
strum::EnumString,
strum::FromRepr,
strum::IntoStaticStr,
)]
#[repr(u8)]
#[strum(serialize_all = "UPPERCASE")]
pub enum Constellation {
Gps,
Sbas,
Glo,
Bds,
Qzs,
Gal,
}
impl Constellation {
#[must_use]
pub fn sat_count(self) -> u16 {
match self {
Constellation::Gps => consts::NUM_SATS_GPS,
Constellation::Sbas => consts::NUM_SATS_SBAS,
Constellation::Glo => consts::NUM_SATS_GLO,
Constellation::Bds => consts::NUM_SATS_BDS,
Constellation::Gal => consts::NUM_SATS_GAL,
Constellation::Qzs => consts::NUM_SATS_QZS,
}
}
#[must_use]
pub fn first_prn(self) -> u16 {
match self {
Constellation::Gps => consts::GPS_FIRST_PRN,
Constellation::Sbas => consts::SBAS_FIRST_PRN,
Constellation::Glo => consts::GLO_FIRST_PRN,
Constellation::Bds => consts::BDS_FIRST_PRN,
Constellation::Gal => consts::GAL_FIRST_PRN,
Constellation::Qzs => consts::QZS_FIRST_PRN,
}
}
#[must_use]
pub fn iter() -> ConstellationIter {
<Self as strum::IntoEnumIterator>::iter()
}
}
#[derive(thiserror::Error, Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[error("Invalid integer for GNSS Constellation ({0})")]
pub struct InvalidConstellationInt(u8);
impl std::convert::TryFrom<u8> for Constellation {
type Error = InvalidConstellationInt;
fn try_from(value: u8) -> Result<Constellation, Self::Error> {
Constellation::from_repr(value).ok_or(InvalidConstellationInt(value))
}
}
impl std::convert::From<Constellation> for char {
fn from(c: Constellation) -> char {
match c {
Constellation::Gps => 'G',
Constellation::Sbas => 'S',
Constellation::Glo => 'R',
Constellation::Bds => 'C',
Constellation::Gal => 'E',
Constellation::Qzs => 'J',
}
}
}
#[derive(thiserror::Error, Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[error("Invalid character for GNSS Constellation ({0})")]
pub struct InvalidConstellationChar(char);
impl std::convert::TryFrom<char> for Constellation {
type Error = InvalidConstellationChar;
fn try_from(c: char) -> Result<Constellation, Self::Error> {
match c {
'G' => Ok(Constellation::Gps),
'S' => Ok(Constellation::Sbas),
'R' => Ok(Constellation::Glo),
'C' => Ok(Constellation::Bds),
'E' => Ok(Constellation::Gal),
'J' => Ok(Constellation::Qzs),
_ => Err(InvalidConstellationChar(c)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sat_count() {
assert_eq!(Constellation::Gps.sat_count(), 32);
assert_eq!(Constellation::Sbas.sat_count(), 19);
assert_eq!(Constellation::Glo.sat_count(), 28);
assert_eq!(Constellation::Bds.sat_count(), 64);
assert_eq!(Constellation::Gal.sat_count(), 36);
assert_eq!(Constellation::Qzs.sat_count(), 10);
}
#[test]
fn constellation_chars() {
use std::convert::TryInto;
assert_eq!('G', Constellation::Gps.into());
assert_eq!('S', Constellation::Sbas.into());
assert_eq!('R', Constellation::Glo.into());
assert_eq!('C', Constellation::Bds.into());
assert_eq!('J', Constellation::Qzs.into());
assert_eq!('E', Constellation::Gal.into());
assert_eq!('G'.try_into(), Ok(Constellation::Gps));
assert_eq!('S'.try_into(), Ok(Constellation::Sbas));
assert_eq!('R'.try_into(), Ok(Constellation::Glo));
assert_eq!('C'.try_into(), Ok(Constellation::Bds));
assert_eq!('J'.try_into(), Ok(Constellation::Qzs));
assert_eq!('E'.try_into(), Ok(Constellation::Gal));
}
#[test]
fn constellation_strings() {
use std::str::FromStr;
assert_eq!(Constellation::Gps.to_string(), "GPS");
assert_eq!(Constellation::Sbas.to_string(), "SBAS");
assert_eq!(Constellation::Glo.to_string(), "GLO");
assert_eq!(Constellation::Bds.to_string(), "BDS");
assert_eq!(Constellation::Qzs.to_string(), "QZS");
assert_eq!(Constellation::Gal.to_string(), "GAL");
assert_eq!(Constellation::from_str("GPS").unwrap(), Constellation::Gps);
assert_eq!(
Constellation::from_str("SBAS").unwrap(),
Constellation::Sbas
);
assert_eq!(Constellation::from_str("GLO").unwrap(), Constellation::Glo);
assert_eq!(Constellation::from_str("BDS").unwrap(), Constellation::Bds);
assert_eq!(Constellation::from_str("QZS").unwrap(), Constellation::Qzs);
assert_eq!(Constellation::from_str("GAL").unwrap(), Constellation::Gal);
{
let result = Constellation::from_str("Bad String");
assert!(result.is_err());
}
{
let result = Constellation::from_str("Nul\0String");
assert!(result.is_err());
}
{
let result = Constellation::from_str("💩💩💩💩");
assert!(result.is_err());
}
}
}