use crate::utilities::take_or_empty;
use std::num::ParseIntError;
use thiserror::Error;
#[derive(Debug, PartialEq, Eq)]
pub struct MajorBody {
pub id: i32,
pub name: String,
}
#[derive(Error, Debug, PartialEq, Eq)]
pub enum MajorBodyParseError {
#[error("invalid id")]
InvalidId(#[source] ParseIntError),
}
impl TryFrom<&str> for MajorBody {
type Error = MajorBodyParseError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let (id, value) = take_or_empty(value, 9);
let (name, _) = take_or_empty(value, 35);
Ok(Self {
id: id.trim().parse().map_err(MajorBodyParseError::InvalidId)?,
name: name.trim().to_string(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::num::ParseIntError;
#[test]
fn reading_major_bodies() {
assert_eq!(
MajorBody {
id: 0,
name: "Solar System Barycenter".to_string()
},
MajorBody::try_from(" 0 Solar System Barycenter SSB")
.unwrap()
);
assert_eq!(
MajorBody {
id: 699,
name: "Saturn".to_string()
},
MajorBody::try_from(" 699 Saturn").unwrap()
);
assert_eq!(
MajorBody {
id: -78000,
name: "Chang'e_5-T1_booster (spacecraft)".to_string()
},
MajorBody::try_from(
" -78000 Chang'e_5-T1_booster (spacecraft) WE0913A 2014-065B"
)
.unwrap()
);
}
#[test]
fn error_cases_when_parsing_major_bodies() {
assert!(matches!(
MajorBody::try_from("****************").unwrap_err(),
MajorBodyParseError::InvalidId(ParseIntError { .. })
));
assert!(matches!(
MajorBody::try_from("").unwrap_err(),
MajorBodyParseError::InvalidId(ParseIntError { .. })
));
}
}