use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ICGEMBody {
Earth,
Moon,
Mars,
Venus,
Ceres,
Other(String),
}
impl ICGEMBody {
pub fn from_name(s: &str) -> Self {
let lower = s.trim().to_lowercase();
match lower.as_str() {
"earth" => ICGEMBody::Earth,
"mars" => ICGEMBody::Mars,
"venus" => ICGEMBody::Venus,
"ceres" => ICGEMBody::Ceres,
other if other == "moon" || other.starts_with("moon ") => ICGEMBody::Moon,
other => ICGEMBody::Other(other.to_string()),
}
}
pub fn as_name(&self) -> &str {
match self {
ICGEMBody::Earth => "Earth",
ICGEMBody::Moon => "Moon",
ICGEMBody::Mars => "Mars",
ICGEMBody::Venus => "Venus",
ICGEMBody::Ceres => "Ceres",
ICGEMBody::Other(name) => name.as_str(),
}
}
pub fn is_earth(&self) -> bool {
matches!(self, ICGEMBody::Earth)
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn test_from_name_known_bodies_case_insensitive() {
assert_eq!(ICGEMBody::from_name("Earth"), ICGEMBody::Earth);
assert_eq!(ICGEMBody::from_name("earth"), ICGEMBody::Earth);
assert_eq!(ICGEMBody::from_name(" MOON "), ICGEMBody::Moon);
assert_eq!(ICGEMBody::from_name("Mars"), ICGEMBody::Mars);
assert_eq!(ICGEMBody::from_name("Venus"), ICGEMBody::Venus);
assert_eq!(ICGEMBody::from_name("Ceres"), ICGEMBody::Ceres);
}
#[test]
fn test_from_name_unknown_falls_through_to_other_lowercased() {
assert_eq!(
ICGEMBody::from_name("Pluto"),
ICGEMBody::Other("pluto".to_string())
);
assert_eq!(
ICGEMBody::from_name("Bennu"),
ICGEMBody::Other("bennu".to_string())
);
}
#[test]
fn test_as_name_round_trip() {
for body in [
ICGEMBody::Earth,
ICGEMBody::Moon,
ICGEMBody::Mars,
ICGEMBody::Venus,
ICGEMBody::Ceres,
ICGEMBody::Other("pluto".to_string()),
] {
assert_eq!(ICGEMBody::from_name(body.as_name()), body);
}
}
#[test]
fn test_is_earth() {
assert!(ICGEMBody::Earth.is_earth());
assert!(!ICGEMBody::Moon.is_earth());
assert!(!ICGEMBody::Other("earth-like".to_string()).is_earth());
}
}