use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fmt;
use anyhow::{Error, Result};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::from_slice;
use strum::EnumIter;
use variant_count::VariantCount;
use super::dec::date_format;
use super::RootEntry;
use super::util::DisplayViaSerde;
use crate::display_via_serde;
pub trait BodyT {
fn id(&self) -> u64;
fn id64(&self) -> Option<u64>;
fn body_id(&self) -> Option<u64>;
fn system_id(&self) -> Option<u64>;
fn system_id64(&self) -> Option<u64>;
fn update_time(&self) -> DateTime<Utc>;
fn name(&self) -> &str;
fn system_name(&self) -> Option<&str>;
fn axial_tilt(&self) -> Option<f32>;
fn distance_to_arrival(&self) -> Option<u64>;
fn orbital_eccentricity(&self) -> Option<f32>;
fn orbital_inclination(&self) -> Option<f32>;
fn orbital_period(&self) -> Option<f32>;
fn parents(&self) -> Option<&[Parent]>;
fn rotational_period(&self) -> Option<f32>;
fn rotational_period_tidally_locked(&self) -> Option<bool>;
fn semi_major_axis(&self) -> Option<f32>;
fn surface_temperature(&self) -> Option<u64>;
}
macro_rules! deref_impl {
($n:ident, $t:ty) => {
fn $n(&self) -> $t {
(*self).$n()
}
};
}
impl<T: BodyT> BodyT for &T {
deref_impl!(id, u64);
deref_impl!(id64, Option<u64>);
deref_impl!(body_id, Option<u64>);
deref_impl!(system_id, Option<u64>);
deref_impl!(system_id64, Option<u64>);
deref_impl!(update_time, DateTime<Utc>);
deref_impl!(name, &str);
deref_impl!(system_name, Option<&str>);
deref_impl!(axial_tilt, Option<f32>);
deref_impl!(distance_to_arrival, Option<u64>);
deref_impl!(orbital_eccentricity, Option<f32>);
deref_impl!(orbital_inclination, Option<f32>);
deref_impl!(orbital_period, Option<f32>);
deref_impl!(parents, Option<&[Parent]>);
deref_impl!(rotational_period, Option<f32>);
deref_impl!(rotational_period_tidally_locked, Option<bool>);
deref_impl!(semi_major_axis, Option<f32>);
deref_impl!(surface_temperature, Option<u64>);
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
#[serde(tag = "type")]
#[allow(clippy::large_enum_variant)]
pub enum Body {
Planet(Planet),
Star(Star),
#[serde(rename = "null")]
Unknown(Unknown),
}
macro_rules! body_common_field {
($f:ident, $ty:ty ) => {
fn $f(&self) -> $ty {
match self {
Body::Planet(x) => x.$f(),
Body::Star(x) => x.$f(),
Body::Unknown(x) => x.$f(),
}
}
};
}
impl BodyT for Body {
body_common_field!(id, u64);
body_common_field!(id64, Option<u64>);
body_common_field!(body_id, Option<u64>);
body_common_field!(system_id, Option<u64>);
body_common_field!(system_id64, Option<u64>);
body_common_field!(update_time, DateTime<Utc>);
body_common_field!(name, &str);
body_common_field!(system_name, Option<&str>);
body_common_field!(axial_tilt, Option<f32>);
body_common_field!(distance_to_arrival, Option<u64>);
body_common_field!(orbital_eccentricity, Option<f32>);
body_common_field!(orbital_inclination, Option<f32>);
body_common_field!(orbital_period, Option<f32>);
body_common_field!(parents, Option<&[Parent]>);
body_common_field!(rotational_period, Option<f32>);
body_common_field!(rotational_period_tidally_locked, Option<bool>);
body_common_field!(semi_major_axis, Option<f32>);
body_common_field!(surface_temperature, Option<u64>);
}
impl RootEntry for Body {
fn entry_id(&self) -> u64 {
self.id()
}
fn type_name() -> &'static str {
"body"
}
fn time(&self) -> DateTime<Utc> {
match self {
Body::Planet(x) => x.update_time,
Body::Star(x) => x.update_time,
Body::Unknown(x) => x.update_time,
}
}
fn parse_dump_json(bs: &[u8]) -> Result<Self> {
match from_slice(bs) {
Ok(v) => Ok(v),
Err(e) => match from_slice(bs) {
Ok(v) => Ok(Body::Unknown(v)),
Err(_) => Err(Error::new(e)),
},
}
}
fn pre_filter(s: &str) -> Cow<'_, str> {
let null_pos = s.find(r#""type":null"#);
let first_compound = match (s.find(":{"), s.find('[')) {
(None, None) => None,
(Some(x), None) => Some(x),
(None, Some(y)) => Some(y),
(Some(x), Some(y)) => Some(x.min(y)),
};
let type_is_null = match (null_pos, first_compound) {
(None, _) => false,
(Some(_), None) => true,
(Some(n), Some(o)) => n < o,
};
if type_is_null {
Cow::Owned(s.replacen(r#""type":null"#, r#""type":"null""#, 1))
} else {
Cow::Borrowed(s)
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
#[allow(clippy::large_enum_variant)]
pub enum BodyS {
Planet(Planet),
Star(Star),
#[serde(rename = "null")]
Unknown(Unknown),
}
macro_rules! body_s_common_field {
($f:ident, $ty:ty ) => {
fn $f(&self) -> $ty {
match self {
BodyS::Planet(x) => x.$f(),
BodyS::Star(x) => x.$f(),
BodyS::Unknown(x) => x.$f(),
}
}
};
}
impl BodyT for BodyS {
body_s_common_field!(id, u64);
body_s_common_field!(id64, Option<u64>);
body_s_common_field!(body_id, Option<u64>);
body_s_common_field!(system_id, Option<u64>);
body_s_common_field!(system_id64, Option<u64>);
body_s_common_field!(update_time, DateTime<Utc>);
body_s_common_field!(name, &str);
body_s_common_field!(system_name, Option<&str>);
body_s_common_field!(axial_tilt, Option<f32>);
body_s_common_field!(distance_to_arrival, Option<u64>);
body_s_common_field!(orbital_eccentricity, Option<f32>);
body_s_common_field!(orbital_inclination, Option<f32>);
body_s_common_field!(orbital_period, Option<f32>);
body_s_common_field!(parents, Option<&[Parent]>);
body_s_common_field!(rotational_period, Option<f32>);
body_s_common_field!(rotational_period_tidally_locked, Option<bool>);
body_s_common_field!(semi_major_axis, Option<f32>);
body_s_common_field!(surface_temperature, Option<u64>);
}
impl From<Body> for BodyS {
fn from(body: Body) -> BodyS {
match body {
Body::Planet(x) => BodyS::Planet(x),
Body::Star(x) => BodyS::Star(x),
Body::Unknown(x) => BodyS::Unknown(x),
}
}
}
impl From<BodyS> for Body {
fn from(body: BodyS) -> Body {
match body {
BodyS::Planet(x) => Body::Planet(x),
BodyS::Star(x) => Body::Star(x),
BodyS::Unknown(x) => Body::Unknown(x),
}
}
}
impl RootEntry for BodyS {
fn entry_id(&self) -> u64 {
self.id()
}
fn type_name() -> &'static str {
"body"
}
fn time(&self) -> DateTime<Utc> {
match self {
BodyS::Planet(x) => x.update_time,
BodyS::Star(x) => x.update_time,
BodyS::Unknown(x) => x.update_time,
}
}
}
macro_rules! body_t_impl {
($n:ident, $t:ty) => {
fn $n(&self) -> $t {
self.$n
}
};
}
macro_rules! body_t_impl_some {
($n:ident, $t:ty) => {
fn $n(&self) -> $t {
Some(self.$n)
}
};
}
macro_rules! body_t_impl_none {
($n:ident, $t:ty) => {
fn $n(&self) -> $t {
None
}
};
}
macro_rules! body_t_impl_deref {
($n:ident, $t:ty) => {
fn $n(&self) -> $t {
self.$n.as_deref()
}
};
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Planet {
pub id: u64,
pub arg_of_periapsis: Option<f32>,
pub atmosphere_composition: Option<AtmosphereComposition>,
pub atmosphere_type: Option<AtmosphereType>,
pub axial_tilt: Option<f32>,
pub belts: Option<Vec<Belt>>,
pub body_id: Option<u64>,
pub discovery: Option<Discovery>,
pub distance_to_arrival: u64,
pub earth_masses: f32,
pub gravity: Option<f32>,
pub id64: Option<u64>,
pub is_landable: bool,
pub materials: Option<Materials>,
pub name: String,
pub orbital_eccentricity: Option<f32>,
pub orbital_inclination: Option<f32>,
pub orbital_period: Option<f32>,
pub parents: Option<Vec<Parent>>,
pub radius: f32,
pub reserve_level: Option<ReserveLevel>,
pub rings: Option<Vec<Ring>>,
pub rotational_period: Option<f32>,
pub rotational_period_tidally_locked: bool,
pub semi_major_axis: Option<f32>,
pub solid_composition: Option<SolidComposition>,
pub sub_type: PlanetSubType,
pub surface_pressure: Option<f32>,
pub surface_temperature: u64,
pub system_id: Option<u64>,
pub system_id64: Option<u64>,
pub system_name: Option<String>,
pub terraforming_state: Option<TerraformingState>,
pub volcanism_type: Option<VolcanismType>,
#[serde(with = "date_format")]
#[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
pub update_time: DateTime<Utc>,
}
impl BodyT for Planet {
body_t_impl!(id, u64);
body_t_impl!(id64, Option<u64>);
body_t_impl!(body_id, Option<u64>);
body_t_impl!(system_id, Option<u64>);
body_t_impl!(system_id64, Option<u64>);
body_t_impl!(update_time, DateTime<Utc>);
fn name(&self) -> &str {
self.name.as_str()
}
body_t_impl_deref!(system_name, Option<&str>);
body_t_impl!(axial_tilt, Option<f32>);
body_t_impl_some!(distance_to_arrival, Option<u64>);
body_t_impl!(orbital_eccentricity, Option<f32>);
body_t_impl!(orbital_inclination, Option<f32>);
body_t_impl!(orbital_period, Option<f32>);
body_t_impl_deref!(parents, Option<&[Parent]>);
body_t_impl!(rotational_period, Option<f32>);
body_t_impl_some!(rotational_period_tidally_locked, Option<bool>);
body_t_impl!(semi_major_axis, Option<f32>);
body_t_impl_some!(surface_temperature, Option<u64>);
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Star {
pub id: u64,
pub absolute_magnitude: Option<f32>,
pub age: u64,
pub arg_of_periapsis: Option<f32>,
pub axial_tilt: Option<f32>,
pub belts: Option<Vec<Belt>>,
pub body_id: Option<u64>,
pub discovery: Option<Discovery>,
pub distance_to_arrival: u64,
pub id64: Option<u64>,
pub is_main_star: bool,
pub is_scoopable: bool,
pub luminosity: Option<Luminosity>,
pub name: String,
pub orbital_eccentricity: Option<f32>,
pub orbital_inclination: Option<f32>,
pub orbital_period: Option<f32>,
pub parents: Option<Vec<Parent>>,
pub reserve_level: Option<ReserveLevel>,
pub rings: Option<Vec<Ring>>,
pub rotational_period: Option<f32>,
pub rotational_period_tidally_locked: bool,
pub semi_major_axis: Option<f32>,
pub solar_masses: f32,
pub solar_radius: f32,
pub spectral_class: Option<SpectralClass>,
pub sub_type: StarSubType,
pub surface_temperature: u64,
pub system_id: Option<u64>,
pub system_id64: Option<u64>,
pub system_name: Option<String>,
#[serde(with = "date_format")]
#[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
pub update_time: DateTime<Utc>,
}
impl BodyT for Star {
body_t_impl!(id, u64);
body_t_impl!(id64, Option<u64>);
body_t_impl!(body_id, Option<u64>);
body_t_impl!(system_id, Option<u64>);
body_t_impl!(system_id64, Option<u64>);
body_t_impl!(update_time, DateTime<Utc>);
fn name(&self) -> &str {
self.name.as_str()
}
body_t_impl_deref!(system_name, Option<&str>);
body_t_impl!(axial_tilt, Option<f32>);
body_t_impl_some!(distance_to_arrival, Option<u64>);
body_t_impl!(orbital_eccentricity, Option<f32>);
body_t_impl!(orbital_inclination, Option<f32>);
body_t_impl!(orbital_period, Option<f32>);
body_t_impl_deref!(parents, Option<&[Parent]>);
body_t_impl!(rotational_period, Option<f32>);
body_t_impl_some!(rotational_period_tidally_locked, Option<bool>);
body_t_impl!(semi_major_axis, Option<f32>);
body_t_impl_some!(surface_temperature, Option<u64>);
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
pub struct Unknown {
pub id: u64,
pub id64: Option<u64>,
pub name: String,
pub system_id: Option<u64>,
pub system_id64: Option<u64>,
pub system_name: Option<String>,
#[serde(with = "date_format")]
#[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
pub update_time: DateTime<Utc>,
}
impl BodyT for Unknown {
body_t_impl!(id, u64);
body_t_impl!(id64, Option<u64>);
body_t_impl_none!(body_id, Option<u64>);
body_t_impl!(system_id, Option<u64>);
body_t_impl!(system_id64, Option<u64>);
body_t_impl!(update_time, DateTime<Utc>);
fn name(&self) -> &str {
self.name.as_str()
}
body_t_impl_deref!(system_name, Option<&str>);
body_t_impl_none!(axial_tilt, Option<f32>);
body_t_impl_none!(distance_to_arrival, Option<u64>);
body_t_impl_none!(orbital_eccentricity, Option<f32>);
body_t_impl_none!(orbital_inclination, Option<f32>);
body_t_impl_none!(orbital_period, Option<f32>);
body_t_impl_none!(parents, Option<&[Parent]>);
body_t_impl_none!(rotational_period, Option<f32>);
body_t_impl_none!(rotational_period_tidally_locked, Option<bool>);
body_t_impl_none!(semi_major_axis, Option<f32>);
body_t_impl_none!(surface_temperature, Option<u64>);
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum AsteroidType {
Icy,
Rocky,
#[serde(rename = "Metal Rich")]
MetalRich,
Metallic,
}
display_via_serde!(AsteroidType);
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "PascalCase")]
pub struct AtmosphereComposition(BTreeMap<AtmosphereCompositionKey, f32>);
impl AtmosphereComposition {
pub fn get(&self, key: AtmosphereCompositionKey) -> Option<f32> {
self.0.get(&key).copied()
}
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
pub enum AtmosphereCompositionKey {
Ammonia,
Argon,
#[serde(rename = "Carbon dioxide")]
CarbonDioxide,
Helium,
Hydrogen,
Iron,
Methane,
Neon,
Nitrogen,
Oxygen,
Silicates,
#[serde(rename = "Sulphur dioxide")]
SulphurDioxide,
Water,
}
impl AtmosphereCompositionKey {
pub const VARIANTS: usize = 13;
}
display_via_serde!(AtmosphereCompositionKey);
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
pub enum AtmosphereType {
Ammonia,
#[serde(rename = "Ammonia and Oxygen")]
AmmoniaAndOxygen,
#[serde(rename = "Ammonia-rich")]
AmmoniaRich,
Argon,
#[serde(rename = "Argon-rich")]
ArgonRich,
#[serde(rename = "Carbon dioxide")]
CarbonDioxide,
#[serde(rename = "Carbon dioxide-rich")]
CarbonDioxideRich,
Helium,
#[serde(rename = "Metallic vapour")]
MetallicVapour,
Methane,
#[serde(rename = "Methane-rich")]
MethaneRich,
Neon,
#[serde(rename = "Neon-rich")]
NeonRich,
Nitrogen,
#[serde(rename = "No atmosphere")]
NoAtmosphere,
Oxygen,
#[serde(rename = "Silicate vapour")]
SilicateVapour,
#[serde(rename = "Suitable for water-based life")]
SuitableForWaterBasedLife,
#[serde(rename = "Sulphur dioxide")]
SulphurDioxide,
Water,
#[serde(rename = "Water-rich")]
WaterRich,
#[serde(rename = "Hot Argon")]
HotArgon,
#[serde(rename = "Hot Argon-rich")]
HotArgonRich,
#[serde(rename = "Hot Carbon dioxide")]
HotCarbonDioxide,
#[serde(rename = "Hot Carbon dioxide-rich")]
HotCarbonDioxideRich,
#[serde(rename = "Hot Metallic vapour")]
HotMetallicVapour,
#[serde(rename = "Hot Silicate vapour")]
HotSilicateVapour,
#[serde(rename = "Hot Sulphur dioxide")]
HotSulphurDioxide,
#[serde(rename = "Hot Water")]
HotWater,
#[serde(rename = "Hot Water-rich")]
HotWaterRich,
#[serde(rename = "Hot thick Ammonia")]
HotThickAmmonia,
#[serde(rename = "Hot thick Ammonia-rich")]
HotThickAmmoniaRich,
#[serde(rename = "Hot thick Argon")]
HotThickArgon,
#[serde(rename = "Hot thick Argon-rich")]
HotThickArgonRich,
#[serde(rename = "Hot thick Carbon dioxide")]
HotThickCarbonDioxide,
#[serde(rename = "Hot thick Carbon dioxide-rich")]
HotThickCarbonDioxideRich,
#[serde(rename = "Hot thick Metallic vapour")]
HotThickMetallicVapour,
#[serde(rename = "Hot thick Methane")]
HotThickMethane,
#[serde(rename = "Hot thick Methane-rich")]
HotThickMethaneRich,
#[serde(rename = "Hot thick Nitrogen")]
HotThickNitrogen,
#[serde(rename = "Hot thick No atmosphere")]
HotThickNoAtmosphere,
#[serde(rename = "Hot thick Silicate vapour")]
HotThickSilicateVapour,
#[serde(rename = "Hot thick Sulphur dioxide")]
HotThickSulphurDioxide,
#[serde(rename = "Hot thick Water")]
HotThickWater,
#[serde(rename = "Hot thick Water-rich")]
HotThickWaterRich,
#[serde(rename = "Hot thin Carbon dioxide")]
HotThinCarbonDioxide,
#[serde(rename = "Hot thin Metallic vapour")]
HotThinMetallicVapour,
#[serde(rename = "Hot thin Silicate vapour")]
HotThinSilicateVapour,
#[serde(rename = "Hot thin Sulphur dioxide")]
HotThinSulphurDioxide,
#[serde(rename = "Thick Ammonia")]
ThickAmmonia,
#[serde(rename = "Thick Ammonia and Oxygen")]
ThickAmmoniaAndOxygen,
#[serde(rename = "Thick Ammonia-rich")]
ThickAmmoniaRich,
#[serde(rename = "Thick Argon")]
ThickArgon,
#[serde(rename = "Thick Argon-rich")]
ThickArgonRich,
#[serde(rename = "Thick Carbon dioxide")]
ThickCarbonDioxide,
#[serde(rename = "Thick Carbon dioxide-rich")]
ThickCarbonDioxideRich,
#[serde(rename = "Thick Helium")]
ThickHelium,
#[serde(rename = "Thick Methane")]
ThickMethane,
#[serde(rename = "Thick Methane-rich")]
ThickMethaneRich,
#[serde(rename = "Thick Nitrogen")]
ThickNitrogen,
#[serde(rename = "Thick No atmosphere")]
ThickNoAtmosphere,
#[serde(rename = "Thick Suitable for water-based life")]
ThickSuitableForWaterBasedLife,
#[serde(rename = "Thick Sulphur dioxide")]
ThickSulphurDioxide,
#[serde(rename = "Thick Water")]
ThickWater,
#[serde(rename = "Thick Water-rich")]
ThickWaterRich,
#[serde(rename = "Thin Ammonia")]
ThinAmmonia,
#[serde(rename = "Thin Ammonia and Oxygen")]
ThinAmmoniaAndOxygen,
#[serde(rename = "Thin Ammonia-rich")]
ThinAmmoniaRich,
#[serde(rename = "Thin Argon")]
ThinArgon,
#[serde(rename = "Thin Argon-rich")]
ThinArgonRich,
#[serde(rename = "Thin Carbon dioxide")]
ThinCarbonDioxide,
#[serde(rename = "Thin Carbon dioxide-rich")]
ThinCarbonDioxideRich,
#[serde(rename = "Thin Helium")]
ThinHelium,
#[serde(rename = "Thin Methane")]
ThinMethane,
#[serde(rename = "Thin Methane-rich")]
ThinMethaneRich,
#[serde(rename = "Thin Neon")]
ThinNeon,
#[serde(rename = "Thin Neon-rich")]
ThinNeonRich,
#[serde(rename = "Thin Nitrogen")]
ThinNitrogen,
#[serde(rename = "Thin No atmosphere")]
ThinNoAtmosphere,
#[serde(rename = "Thin Oxygen")]
ThinOxygen,
#[serde(rename = "Thin Sulphur dioxide")]
ThinSulphurDioxide,
#[serde(rename = "Thin Water")]
ThinWater,
#[serde(rename = "Thin Water-rich")]
ThinWaterRich,
}
impl AtmosphereType {
pub const VARIANTS: usize = 83;
}
display_via_serde!(AtmosphereType);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Belt {
pub inner_radius: f32,
pub mass: f32,
pub name: String,
pub outer_radius: f32,
#[serde(rename = "type")]
pub typ: Option<AsteroidType>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Discovery {
pub commander: String,
#[serde(with = "date_format")]
#[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
pub date: DateTime<Utc>,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum Luminosity {
VII,
VI,
Vz,
Vb,
Vab,
Va,
V,
IVb,
IVab,
IVa,
IV,
IIIb,
IIIab,
IIIa,
III,
IIb,
IIab,
IIa,
II,
Ib,
Iab,
Ia0,
Ia,
I,
O,
}
impl Luminosity {
pub const VARIANTS: usize = 25;
}
display_via_serde!(Luminosity);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "PascalCase")]
#[serde(deny_unknown_fields)]
pub struct Materials(BTreeMap<MaterialsKey, f32>);
impl Materials {
pub fn get(&self, key: MaterialsKey) -> Option<f32> {
self.0.get(&key).copied()
}
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
pub enum MaterialsKey {
Antimony,
Arsenic,
Cadmium,
Carbon,
Chromium,
Germanium,
Iron,
Manganese,
Mercury,
Molybdenum,
Nickel,
Niobium,
Phosphorus,
Polonium,
Ruthenium,
Selenium,
Sulphur,
Technetium,
Tellurium,
Tin,
Tungsten,
Vanadium,
Yttrium,
Zinc,
Zirconium,
}
impl MaterialsKey {
pub const VARIANTS: usize = 25;
}
display_via_serde!(MaterialsKey);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum Parent {
Null(u64),
Planet(u64),
Star(u64),
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum PlanetSubType {
#[serde(rename = "Class I gas giant")]
ClassIGasGiant,
#[serde(rename = "Class II gas giant")]
ClassIiGasGiant,
#[serde(rename = "Class III gas giant")]
ClassIiiGasGiant,
#[serde(rename = "Class IV gas giant")]
ClassIvGasGiant,
#[serde(rename = "Class V gas giant")]
ClassVGasGiant,
#[serde(rename = "Gas giant with ammonia-based life")]
GasGiantWithAmmoniaBasedLife,
#[serde(rename = "Gas giant with water-based life")]
GasGiantWithWaterBasedLife,
#[serde(rename = "Helium gas giant")]
HeliumGasGiant,
#[serde(rename = "Helium-rich gas giant")]
HeliumRichGasGiant,
#[serde(rename = "Water giant")]
WaterGiant,
#[serde(rename = "Ammonia world")]
AmmoniaWorld,
#[serde(rename = "Earth-like world")]
EarthLikeWorld,
#[serde(rename = "High metal content world")]
HighMetalContentWorld,
#[serde(rename = "Icy body")]
IcyBody,
#[serde(rename = "Metal-rich body")]
MetalRichBody,
#[serde(rename = "Rocky Ice world")]
RockyIceWorld,
#[serde(rename = "Rocky body")]
RockyBody,
#[serde(rename = "Water world")]
WaterWorld,
}
impl PlanetSubType {
pub const VARIANTS: usize = 18;
pub fn short(self) -> &'static str {
match self {
PlanetSubType::ClassIGasGiant => "C1GG",
PlanetSubType::ClassIiGasGiant => "C2GG",
PlanetSubType::ClassIiiGasGiant => "C3GG",
PlanetSubType::ClassIvGasGiant => "C4GG",
PlanetSubType::ClassVGasGiant => "C5GG",
PlanetSubType::GasGiantWithAmmoniaBasedLife => "GGwABL",
PlanetSubType::GasGiantWithWaterBasedLife => "GGwWBL",
PlanetSubType::HeliumGasGiant => "HGG",
PlanetSubType::HeliumRichGasGiant => "HRGG",
PlanetSubType::WaterGiant => "WG",
PlanetSubType::AmmoniaWorld => "AW",
PlanetSubType::EarthLikeWorld => "ELW",
PlanetSubType::HighMetalContentWorld => "HMC",
PlanetSubType::IcyBody => "I",
PlanetSubType::MetalRichBody => "MR",
PlanetSubType::RockyIceWorld => "RI",
PlanetSubType::RockyBody => "R",
PlanetSubType::WaterWorld => "WW",
}
}
}
display_via_serde!(PlanetSubType);
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum ReserveLevel {
Depleted,
Low,
Common,
Major,
Pristine,
}
impl ReserveLevel {
pub const VARIANTS: usize = 5;
}
display_via_serde!(ReserveLevel);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Ring {
pub inner_radius: f32,
pub mass: f32,
pub name: String,
pub outer_radius: f32,
#[serde(rename = "type")]
pub typ: Option<AsteroidType>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(rename_all = "PascalCase")]
#[serde(deny_unknown_fields)]
pub struct SolidComposition {
#[serde(default)]
pub ice: f32,
#[serde(default)]
pub metal: f32,
#[serde(default)]
pub rock: f32,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
pub enum StarClass {
OTypeStars,
BTypeStars,
ATypeStars,
FTypeStars,
GTypeStars,
KTypeStars,
MTypeStars,
LTypeStars,
TTypeStars,
YTypeStars,
ProtoStars,
CarbonStars,
WolfRayetStars,
WhiteDwarfStars,
NonSequenceStars,
}
impl StarClass {
pub const VARIANTS: usize = 15;
pub fn short(self) -> &'static str {
match self {
StarClass::OTypeStars => "O",
StarClass::BTypeStars => "B",
StarClass::ATypeStars => "A",
StarClass::FTypeStars => "F",
StarClass::GTypeStars => "G",
StarClass::KTypeStars => "K",
StarClass::MTypeStars => "M",
StarClass::LTypeStars => "L",
StarClass::TTypeStars => "T",
StarClass::YTypeStars => "Y",
StarClass::ProtoStars => "P",
StarClass::CarbonStars => "C",
StarClass::WolfRayetStars => "W",
StarClass::WhiteDwarfStars => "WD",
StarClass::NonSequenceStars => "NS",
}
}
}
impl fmt::Display for StarClass {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
StarClass::OTypeStars => "O-Type Stars",
StarClass::BTypeStars => "B-Type Stars",
StarClass::ATypeStars => "A-Type Stars",
StarClass::FTypeStars => "F-Type Stars",
StarClass::GTypeStars => "G-Type Stars",
StarClass::KTypeStars => "K-Type Stars",
StarClass::MTypeStars => "M-Type Stars",
StarClass::LTypeStars => "L-Type Stars",
StarClass::TTypeStars => "T-Type Stars",
StarClass::YTypeStars => "Y-Type Stars",
StarClass::ProtoStars => "Proto Stars",
StarClass::CarbonStars => "Carbon Stars",
StarClass::WolfRayetStars => "Wolf-Rayet Stars",
StarClass::WhiteDwarfStars => "White Dwarf Stars",
StarClass::NonSequenceStars => "Non Sequence Stars",
};
write!(f, "{}", s)
}
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum SpectralClass {
O,
O0,
O1,
O2,
O3,
O4,
O5,
O6,
O7,
O8,
O9,
B,
B0,
B1,
B2,
B3,
B4,
B5,
B6,
B7,
B8,
B9,
A,
A0,
A1,
A2,
A3,
A4,
A5,
A6,
A7,
A8,
A9,
F,
F0,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
G,
G0,
G1,
G2,
G3,
G4,
G5,
G6,
G7,
G8,
G9,
K,
K0,
K1,
K2,
K3,
K4,
K5,
K6,
K7,
K8,
K9,
M,
M0,
M1,
M2,
M3,
M4,
M5,
M6,
M7,
M8,
M9,
L,
L0,
L1,
L2,
L3,
L4,
L5,
L6,
L7,
L8,
L9,
T,
T0,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
Y0,
Y1,
Y2,
Y3,
Y4,
Y5,
Y6,
Y7,
Y8,
AeBe0,
AeBe1,
AeBe2,
AeBe3,
AeBe4,
AeBe5,
AeBe6,
AeBe7,
AeBe8,
AeBe9,
TTS0,
TTS1,
TTS2,
TTS3,
TTS4,
TTS5,
TTS6,
TTS7,
TTS8,
TTS9,
}
impl SpectralClass {
pub const VARIANTS: usize = 128;
}
display_via_serde!(SpectralClass);
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum StarSubType {
#[serde(rename = "O (Blue-White) Star")]
OBlueWhiteStar,
#[serde(rename = "B (Blue-White) Star")]
BBlueWhiteStar,
#[serde(rename = "A (Blue-White) Star")]
ABlueWhiteStar,
#[serde(rename = "F (White) Star")]
FWhiteStar,
#[serde(rename = "G (White-Yellow) Star")]
GWhiteYellowStar,
#[serde(rename = "K (Yellow-Orange) Star")]
KYellowOrangeStar,
#[serde(rename = "M (Red dwarf) Star")]
MRedDwarfStar,
#[serde(rename = "K (Yellow-Orange giant) Star")]
KYellowOrangeGiantStar,
#[serde(rename = "M (Red giant) Star")]
MRedGiantStar,
#[serde(rename = "B (Blue-White super giant) Star")]
BBlueWhiteSuperGiantStar,
#[serde(rename = "A (Blue-White super giant) Star")]
ABlueWhiteSuperGiantStar,
#[serde(rename = "F (White super giant) Star")]
FWhiteSuperGiantStar,
#[serde(rename = "G (White-Yellow super giant) Star")]
GWhiteYellowSuperGiantStar,
#[serde(rename = "M (Red super giant) Star")]
MRedSuperGiantStar,
#[serde(rename = "L (Brown dwarf) Star")]
LBrownDwarfStar,
#[serde(rename = "T (Brown dwarf) Star")]
TBrownDwarfStar,
#[serde(rename = "Y (Brown dwarf) Star")]
YBrownDwarfStar,
#[serde(rename = "Herbig Ae/Be Star")]
HerbigAeBeStar,
#[serde(rename = "T Tauri Star")]
TTauriStar,
#[serde(rename = "C Star")]
CStar,
#[serde(rename = "CJ Star")]
CJStar,
#[serde(rename = "CN Star")]
CNStar,
#[serde(rename = "MS-type Star")]
MSTypeStar,
#[serde(rename = "S-type Star")]
STypeStar,
#[serde(rename = "Wolf-Rayet Star")]
WolfRayetStar,
#[serde(rename = "Wolf-Rayet C Star")]
WolfRayetCStar,
#[serde(rename = "Wolf-Rayet N Star")]
WolfRayetNStar,
#[serde(rename = "Wolf-Rayet NC Star")]
WolfRayetNCStar,
#[serde(rename = "Wolf-Rayet O Star")]
WolfRayetOStar,
#[serde(rename = "White Dwarf (D) Star")]
WhiteDwarfDStar,
#[serde(rename = "White Dwarf (DA) Star")]
WhiteDwarfDAStar,
#[serde(rename = "White Dwarf (DAB) Star")]
WhiteDwarfDABStar,
#[serde(rename = "White Dwarf (DAV) Star")]
WhiteDwarfDAVStar,
#[serde(rename = "White Dwarf (DAZ) Star")]
WhiteDwarfDAZStar,
#[serde(rename = "White Dwarf (DB) Star")]
WhiteDwarfDBStar,
#[serde(rename = "White Dwarf (DBV) Star")]
WhiteDwarfDBVStar,
#[serde(rename = "White Dwarf (DBZ) Star")]
WhiteDwarfDBZStar,
#[serde(rename = "White Dwarf (DC) Star")]
WhiteDwarfDCStar,
#[serde(rename = "White Dwarf (DCV) Star")]
WhiteDwarfDCVStar,
#[serde(rename = "White Dwarf (DQ) Star")]
WhiteDwarfDQStar,
#[serde(rename = "Neutron Star")]
NeutronStar,
#[serde(rename = "Black Hole")]
BlackHole,
#[serde(rename = "Supermassive Black Hole")]
SupermassiveBlackHole,
}
impl StarSubType {
pub const VARIANTS: usize = 43;
pub fn short(self) -> &'static str {
match self {
StarSubType::OBlueWhiteStar => "O",
StarSubType::BBlueWhiteStar => "B",
StarSubType::ABlueWhiteStar => "A",
StarSubType::FWhiteStar => "F",
StarSubType::GWhiteYellowStar => "G",
StarSubType::KYellowOrangeStar => "K",
StarSubType::MRedDwarfStar => "M",
StarSubType::KYellowOrangeGiantStar => "Kg",
StarSubType::MRedGiantStar => "Mg",
StarSubType::BBlueWhiteSuperGiantStar => "Bsg",
StarSubType::ABlueWhiteSuperGiantStar => "Asg",
StarSubType::FWhiteSuperGiantStar => "Fsg",
StarSubType::GWhiteYellowSuperGiantStar => "Gsg",
StarSubType::MRedSuperGiantStar => "Msg",
StarSubType::LBrownDwarfStar => "L",
StarSubType::TBrownDwarfStar => "T",
StarSubType::YBrownDwarfStar => "Y",
StarSubType::HerbigAeBeStar => "HeBe",
StarSubType::TTauriStar => "TTS",
StarSubType::CStar => "C",
StarSubType::CJStar => "CJ",
StarSubType::CNStar => "CN",
StarSubType::MSTypeStar => "MS",
StarSubType::STypeStar => "S",
StarSubType::WolfRayetStar => "W",
StarSubType::WolfRayetCStar => "WC",
StarSubType::WolfRayetNStar => "WN",
StarSubType::WolfRayetNCStar => "WNC",
StarSubType::WolfRayetOStar => "WO",
StarSubType::WhiteDwarfDStar => "D",
StarSubType::WhiteDwarfDAStar => "Da",
StarSubType::WhiteDwarfDABStar => "Dab",
StarSubType::WhiteDwarfDAVStar => "Dv",
StarSubType::WhiteDwarfDAZStar => "Daz",
StarSubType::WhiteDwarfDBStar => "Db",
StarSubType::WhiteDwarfDBVStar => "Dbv",
StarSubType::WhiteDwarfDBZStar => "Dbz",
StarSubType::WhiteDwarfDCStar => "Dc",
StarSubType::WhiteDwarfDCVStar => "Dcv",
StarSubType::WhiteDwarfDQStar => "Dq",
StarSubType::NeutronStar => "N",
StarSubType::BlackHole => "BH",
StarSubType::SupermassiveBlackHole => "sBH",
}
}
}
display_via_serde!(StarSubType);
impl StarSubType {
pub fn filter_star_class(self) -> StarClass {
match self {
StarSubType::OBlueWhiteStar => StarClass::OTypeStars,
StarSubType::BBlueWhiteSuperGiantStar => StarClass::BTypeStars,
StarSubType::BBlueWhiteStar => StarClass::BTypeStars,
StarSubType::ABlueWhiteSuperGiantStar => StarClass::ATypeStars,
StarSubType::ABlueWhiteStar => StarClass::ATypeStars,
StarSubType::FWhiteSuperGiantStar => StarClass::FTypeStars,
StarSubType::FWhiteStar => StarClass::FTypeStars,
StarSubType::GWhiteYellowSuperGiantStar => StarClass::GTypeStars,
StarSubType::GWhiteYellowStar => StarClass::GTypeStars,
StarSubType::KYellowOrangeGiantStar => StarClass::KTypeStars,
StarSubType::KYellowOrangeStar => StarClass::KTypeStars,
StarSubType::MRedDwarfStar => StarClass::MTypeStars,
StarSubType::MRedGiantStar => StarClass::MTypeStars,
StarSubType::MRedSuperGiantStar => StarClass::MTypeStars,
StarSubType::LBrownDwarfStar => StarClass::LTypeStars,
StarSubType::TBrownDwarfStar => StarClass::TTypeStars,
StarSubType::YBrownDwarfStar => StarClass::YTypeStars,
StarSubType::HerbigAeBeStar => StarClass::ProtoStars,
StarSubType::TTauriStar => StarClass::ProtoStars,
StarSubType::CStar => StarClass::CarbonStars,
StarSubType::CJStar => StarClass::CarbonStars,
StarSubType::CNStar => StarClass::CarbonStars,
StarSubType::MSTypeStar => StarClass::CarbonStars,
StarSubType::STypeStar => StarClass::CarbonStars,
StarSubType::WolfRayetStar => StarClass::WolfRayetStars,
StarSubType::WolfRayetCStar => StarClass::WolfRayetStars,
StarSubType::WolfRayetNStar => StarClass::WolfRayetStars,
StarSubType::WolfRayetNCStar => StarClass::WolfRayetStars,
StarSubType::WolfRayetOStar => StarClass::WolfRayetStars,
StarSubType::WhiteDwarfDStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDAStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDABStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDAVStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDAZStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDBStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDBVStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDBZStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDCStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDCVStar => StarClass::WhiteDwarfStars,
StarSubType::WhiteDwarfDQStar => StarClass::WhiteDwarfStars,
StarSubType::NeutronStar => StarClass::NonSequenceStars,
StarSubType::BlackHole => StarClass::NonSequenceStars,
StarSubType::SupermassiveBlackHole => StarClass::NonSequenceStars,
}
}
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum TerraformingState {
#[serde(rename = "Candidate for terraforming")]
CandidateForTerraforming,
#[serde(rename = "Not terraformable")]
NotTerraformable,
Terraformed,
Terraforming,
}
impl TerraformingState {
pub const VARIANTS: usize = 4;
}
display_via_serde!(TerraformingState);
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
EnumIter,
VariantCount,
)]
#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
#[serde(deny_unknown_fields)]
pub enum VolcanismType {
#[serde(rename = "Ammonia Magma")]
AmmoniaMagma,
#[serde(rename = "Carbon Dioxide Geysers")]
CarbonDioxideGeysers,
#[serde(rename = "Major Carbon Dioxide Geysers")]
MajorCarbonDioxideGeysers,
#[serde(rename = "Major Metallic Magma")]
MajorMetallicMagma,
#[serde(rename = "Major Rocky Magma")]
MajorRockyMagma,
#[serde(rename = "Major Silicate Vapour Geysers")]
MajorSilicateVapourGeysers,
#[serde(rename = "Major Water Geysers")]
MajorWaterGeysers,
#[serde(rename = "Major Water Magma")]
MajorWaterMagma,
#[serde(rename = "Metallic Magma")]
MetallicMagma,
#[serde(rename = "Methane Magma")]
MethaneMagma,
#[serde(rename = "Minor Ammonia Magma")]
MinorAmmoniaMagma,
#[serde(rename = "Minor Carbon Dioxide Geysers")]
MinorCarbonDioxideGeysers,
#[serde(rename = "Minor Metallic Magma")]
MinorMetallicMagma,
#[serde(rename = "Minor Methane Magma")]
MinorMethaneMagma,
#[serde(rename = "Minor Nitrogen Magma")]
MinorNitrogenMagma,
#[serde(rename = "Minor Rocky Magma")]
MinorRockyMagma,
#[serde(rename = "Minor Silicate Vapour Geysers")]
MinorSilicateVapourGeysers,
#[serde(rename = "Minor Water Geysers")]
MinorWaterGeysers,
#[serde(rename = "Minor Water Magma")]
MinorWaterMagma,
#[serde(rename = "Nitrogen Magma")]
NitrogenMagma,
#[serde(rename = "No volcanism")]
NoVolcanism,
#[serde(rename = "Rocky Magma")]
RockyMagma,
#[serde(rename = "Silicate Vapour Geysers")]
SilicateVapourGeysers,
#[serde(rename = "Water Geysers")]
WaterGeysers,
#[serde(rename = "Water Magma")]
WaterMagma,
}
impl VolcanismType {
pub const VARIANTS: usize = 25;
}
display_via_serde!(VolcanismType);
#[cfg(test)]
mod tests {
use super::*;
use strum::IntoEnumIterator;
#[test]
fn atmosphere_composition_key_check_variants_count() {
let mut max = 0;
let n = AtmosphereCompositionKey::VARIANTS;
for v in AtmosphereCompositionKey::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn atmosphere_type_check_variants_count() {
let mut max = 0;
let n = AtmosphereType::VARIANTS;
for v in AtmosphereType::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn luminosity_check_variants_count() {
let mut max = 0;
let n = Luminosity::VARIANTS;
for v in Luminosity::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn materials_key_check_variants_count() {
let mut max = 0;
let n = MaterialsKey::VARIANTS;
for v in MaterialsKey::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn planet_sub_type_check_variants_count() {
let mut max = 0;
let n = PlanetSubType::VARIANTS;
for v in PlanetSubType::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn reserve_level_check_variants_count() {
let mut max = 0;
let n = ReserveLevel::VARIANTS;
for v in ReserveLevel::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn star_class_check_variants_count() {
let mut max = 0;
let n = StarClass::VARIANTS;
for v in StarClass::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn spectral_class_check_variants_count() {
let mut max = 0;
let n = SpectralClass::VARIANTS;
for v in SpectralClass::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn star_sub_type_check_variants_count() {
let mut max = 0;
let n = StarSubType::VARIANTS;
for v in StarSubType::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn terraforming_state_check_variants_count() {
let mut max = 0;
let n = TerraformingState::VARIANTS;
for v in TerraformingState::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
#[test]
fn volcanism_type_check_variants_count() {
let mut max = 0;
let n = VolcanismType::VARIANTS;
for v in VolcanismType::iter() {
let x = v as usize;
assert!(
x < n,
"type index ({}) should be smaller than variants count ({})",
x,
n
);
max = max.max(x);
}
assert_eq!(n, max + 1);
}
}