From aace0900795242d0a58e538a0a44f3c3dc6a3697 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 17:46:19 +0100 Subject: [PATCH 001/150] Add generated xml-schema-derive results --- crates/lox-utils/src/lib.rs | 1 + crates/lox-utils/src/odm.rs | 5 + crates/lox-utils/src/odm/common.rs | 848 +++++++++++++++++++++++++++++ crates/lox-utils/src/odm/ocm.rs | 423 ++++++++++++++ crates/lox-utils/src/odm/oem.rs | 61 +++ crates/lox-utils/src/odm/omm.rs | 156 ++++++ crates/lox-utils/src/odm/opm.rs | 94 ++++ 7 files changed, 1588 insertions(+) create mode 100644 crates/lox-utils/src/odm.rs create mode 100644 crates/lox-utils/src/odm/common.rs create mode 100644 crates/lox-utils/src/odm/ocm.rs create mode 100644 crates/lox-utils/src/odm/oem.rs create mode 100644 crates/lox-utils/src/odm/omm.rs create mode 100644 crates/lox-utils/src/odm/opm.rs diff --git a/crates/lox-utils/src/lib.rs b/crates/lox-utils/src/lib.rs index 474d0f63..8a1065d4 100644 --- a/crates/lox-utils/src/lib.rs +++ b/crates/lox-utils/src/lib.rs @@ -10,6 +10,7 @@ pub mod constants; pub mod is_close; pub mod linear_algebra; pub mod math; +pub mod odm; pub mod series; pub mod slices; pub mod types; diff --git a/crates/lox-utils/src/odm.rs b/crates/lox-utils/src/odm.rs new file mode 100644 index 00000000..eea3ebd2 --- /dev/null +++ b/crates/lox-utils/src/odm.rs @@ -0,0 +1,5 @@ +pub mod common; +pub mod ocm; +pub mod oem; +pub mod omm; +pub mod opm; diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs new file mode 100644 index 00000000..3421be80 --- /dev/null +++ b/crates/lox-utils/src/odm/common.rs @@ -0,0 +1,848 @@ +mod schema_common +{ + pub mod xml_schema_types + { + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AccUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngleUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngleRange(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngleRateUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngMomentumUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngVelFrameType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AreaUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + DayIntervalUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + FrequencyUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + GmUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + InclinationRange(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + LengthUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + MassUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + MomentUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + WkgUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ObjectDescriptionType(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Ms2Units(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Km2Units(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Km2sUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Km2s2Units(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PositionUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + VelocityUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq)] pub struct VecDouble + { pub items : Vec < f64 > } impl yaserde :: YaDeserialize for + VecDouble + { + fn deserialize < R : std :: io :: Read > + (reader : & mut yaserde :: de :: Deserializer < R >) -> Result < + Self, String > + { + loop + { + match reader.next_event() ? + { + xml :: reader :: XmlEvent :: StartElement { .. } => {} xml + :: reader :: XmlEvent :: Characters(ref text_content) => + { + let items : Vec < f64 > = + text_content.split(' ').map(| item | + item.to_owned()).map(| item | + item.parse().unwrap()).collect() ; return + Ok(VecDouble { items }) ; + } _ => { break ; } + } + } Err("Unable to parse attribute".to_string()) + } + } impl yaserde :: YaSerialize for VecDouble + { + fn serialize < W : std :: io :: Write > + (& self, writer : & mut yaserde :: ser :: Serializer < W >) -> + Result < (), String > + { + let content = + self.items.iter().map(| item | item.to_string()).collect :: < + Vec < String >> ().join(" ") ; let data_event = xml :: writer + :: XmlEvent :: characters(& content) ; + writer.write(data_event).map_err(| e | e.to_string()) ? ; + Ok(()) + } fn + serialize_attributes(& self, mut source_attributes : Vec < xml :: + attribute :: OwnedAttribute >, mut source_namespace : xml :: + namespace :: Namespace) -> Result < + (Vec < xml :: attribute :: OwnedAttribute >, xml :: namespace :: + Namespace), String > { Ok((source_attributes, source_namespace)) } + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Vec3Double(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Vec6Double(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Vec9Double(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + EpochType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + TimeUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + TimeSystemType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + NegativeDouble(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + NonNegativeDouble(#[serde(rename = "$text")] std :: string :: String) + ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + NonPositiveDouble(#[serde(rename = "$text")] std :: string :: String) + ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PercentType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PositiveDouble(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + Range100Type(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ProbabilityType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PercentageUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + YesNoType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + TrajBasisType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RevNumBasisType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + CovBasisType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ManBasisType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ManDcType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + NumPerYearUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ThrustUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + CovOrderType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + GeomagUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + SolarFluxUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PositionCovarianceUnits(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + VelocityCovarianceUnits(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std :: + string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + BallisticCoeffUnitsType(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + LatRange(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AltRange(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + LonRange(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + LatLonUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ControlledType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + DisintegrationType(#[serde(rename = "$text")] std :: string :: String) + ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ImpactUncertaintyType(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ReentryUncertaintyMethodType(#[serde(rename = "$text")] std :: string + :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + QuaternionComponentType(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + QuaternionDotUnits(#[serde(rename = "$text")] std :: string :: String) + ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RotDirectionType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RotseqType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngleKeywordType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AngleRateKeywordType(#[serde(rename = "$text")] std :: string :: + String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ApmRateFrameType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + TorqueUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct NdmHeader + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "CREATION_DATE")] pub creation_date : EpochType, + #[serde(rename = "ORIGINATOR")] pub originator : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AdmHeader + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "CREATION_DATE")] pub creation_date : EpochType, + #[serde(rename = "ORIGINATOR")] pub originator : String, + #[serde(rename = "MESSAGE_ID")] pub message_id : Option < String + >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OdmHeader + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "CLASSIFICATION")] pub classification_list : Vec + < String >, #[serde(rename = "CREATION_DATE")] pub creation_date : + EpochType, #[serde(rename = "ORIGINATOR")] pub originator : + String, #[serde(rename = "MESSAGE_ID")] pub message_id : Option < + String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AccType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < AccUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngleType + { + #[serde(rename = "$text")] pub base : AngleRange, + #[serde(rename = "@units")] pub units : Option < AngleUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngleRateType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngMomentumType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : AngMomentumUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngVelComponentType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngVelStateType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "REF_FRAME_A")] pub ref_frame_a : String, + #[serde(rename = "REF_FRAME_B")] pub ref_frame_b : String, + #[serde(rename = "ANGVEL_FRAME")] pub angvel_frame : + AngVelFrameType, #[serde(rename = "ANGVEL_X")] pub angvel_x : + AngVelComponentType, #[serde(rename = "ANGVEL_Y")] pub angvel_y : + AngVelComponentType, #[serde(rename = "ANGVEL_Z")] pub angvel_z : + AngVelComponentType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AngVelType + { + #[serde(rename = "ANGVEL_X")] pub angvel_x : AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] pub angvel_y : AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] pub angvel_z : AngVelComponentType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AreaType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < AreaUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DayIntervalType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : DayIntervalUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmDayIntervalType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < DayIntervalUnits + >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DeltamassType + { + #[serde(rename = "$text")] pub base : NegativeDouble, + #[serde(rename = "@units")] pub units : Option < MassUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DeltamassTypeZ + { + #[serde(rename = "$text")] pub base : NonPositiveDouble, + #[serde(rename = "@units")] pub units : Option < MassUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct FrequencyType + { + #[serde(rename = "$text")] pub base : PositiveDouble, + #[serde(rename = "@units")] pub units : Option < FrequencyUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct GmType + { + #[serde(rename = "$text")] pub base : PositiveDouble, + #[serde(rename = "@units")] pub units : Option < GmUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct InclinationType + { + #[serde(rename = "$text")] pub base : InclinationRange, + #[serde(rename = "@units")] pub units : Option < AngleUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct LengthType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : LengthUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmLengthType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < LengthUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct MassType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < MassUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct MomentType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < MomentUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct WkgType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : WkgUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OdParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "TIME_LASTOB_START")] pub time_lastob_start : + Option < EpochType >, #[serde(rename = "TIME_LASTOB_END")] pub + time_lastob_end : Option < EpochType >, + #[serde(rename = "RECOMMENDED_OD_SPAN")] pub recommended_od_span : + Option < DayIntervalType >, #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span : Option < DayIntervalType >, + #[serde(rename = "OBS_AVAILABLE")] pub obs_available : Option < + u64 >, #[serde(rename = "OBS_USED")] pub obs_used : Option < u64 + >, #[serde(rename = "TRACKS_AVAILABLE")] pub tracks_available : + Option < u64 >, #[serde(rename = "TRACKS_USED")] pub tracks_used : + Option < u64 >, #[serde(rename = "RESIDUALS_ACCEPTED")] pub + residuals_accepted : Option < PercentageType >, + #[serde(rename = "WEIGHTED_RMS")] pub weighted_rms : Option < + NonNegativeDouble >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct SpacecraftParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "MASS")] pub mass : Option < MassType >, + #[serde(rename = "SOLAR_RAD_AREA")] pub solar_rad_area : Option < + AreaType >, #[serde(rename = "SOLAR_RAD_COEFF")] pub + solar_rad_coeff : Option < NonNegativeDouble >, + #[serde(rename = "DRAG_AREA")] pub drag_area : Option < AreaType + >, #[serde(rename = "DRAG_COEFF")] pub drag_coeff : Option < + NonNegativeDouble >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct StateVectorType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "EPOCH")] pub epoch : EpochType, + #[serde(rename = "X")] pub x : PositionType, + #[serde(rename = "Y")] pub y : PositionType, + #[serde(rename = "Z")] pub z : PositionType, + #[serde(rename = "X_DOT")] pub x_dot : VelocityType, + #[serde(rename = "Y_DOT")] pub y_dot : VelocityType, + #[serde(rename = "Z_DOT")] pub z_dot : VelocityType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct StateVectorAccType + { + #[serde(rename = "EPOCH")] pub epoch : EpochType, + #[serde(rename = "X")] pub x : PositionType, + #[serde(rename = "Y")] pub y : PositionType, + #[serde(rename = "Z")] pub z : PositionType, + #[serde(rename = "X_DOT")] pub x_dot : VelocityType, + #[serde(rename = "Y_DOT")] pub y_dot : VelocityType, + #[serde(rename = "Z_DOT")] pub z_dot : VelocityType, + #[serde(rename = "X_DDOT")] pub x_ddot : Option < AccType >, + #[serde(rename = "Y_DDOT")] pub y_ddot : Option < AccType >, + #[serde(rename = "Z_DDOT")] pub z_ddot : Option < AccType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct Ms2Type + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Ms2Units, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct Km2Type + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < Km2Units >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct Km2sType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < Km2sUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct Km2s2Type + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < Km2s2Units >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DistanceType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < PositionUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct PositionType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < PositionUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RdmPositionType + { #[serde(rename = "$text")] pub base : String, } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct VelocityType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < VelocityUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RdmVelocityType + { #[serde(rename = "$text")] pub base : String, } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DurationType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < TimeUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RelTimeType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < TimeUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct TimeOffsetType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < TimeUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct PercentageType + { + #[serde(rename = "$text")] pub base : Range100Type, + #[serde(rename = "@units")] pub units : Option < PercentageUnits + >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct ManeuverFreqType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < NumPerYearUnits + >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct ThrustType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < ThrustUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct GeomagType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < GeomagUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct SolarFluxType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < SolarFluxUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + OpmCovarianceMatrixAbstractType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : Option < + String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + OemCovarianceMatrixAbstractType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "EPOCH")] pub epoch : EpochType, + #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : Option < + String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemCovarianceMatrixType + { #[serde(flatten)] pub base : OemCovarianceMatrixAbstractType, } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmCovarianceMatrixType + { + #[serde(flatten)] pub base : OpmCovarianceMatrixAbstractType, + #[serde(flatten)] pub extension : CovarianceMatrixElementsGroup, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct PositionCovarianceType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < + PositionCovarianceUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct VelocityCovarianceType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < + VelocityCovarianceUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + PositionVelocityCovarianceType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < + PositionVelocityCovarianceUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AtmosphericReentryParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "ORBIT_LIFETIME")] pub orbit_lifetime : + DayIntervalType, #[serde(rename = "REENTRY_ALTITUDE")] pub + reentry_altitude : PositionType, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] pub + orbit_lifetime_window_start : Option < DayIntervalType >, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] pub + orbit_lifetime_window_end : Option < DayIntervalType >, + #[serde(rename = "NOMINAL_REENTRY_EPOCH")] pub + nominal_reentry_epoch : Option < EpochType >, + #[serde(rename = "REENTRY_WINDOW_START")] pub reentry_window_start + : Option < EpochType >, #[serde(rename = "REENTRY_WINDOW_END")] + pub reentry_window_end : Option < EpochType >, + #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] pub + orbit_lifetime_confidence_level : Option < PercentageType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct GroundImpactParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "PROBABILITY_OF_IMPACT")] pub + probability_of_impact : Option < ProbabilityType >, + #[serde(rename = "PROBABILITY_OF_BURN_UP")] pub + probability_of_burn_up : Option < ProbabilityType >, + #[serde(rename = "PROBABILITY_OF_BREAK_UP")] pub + probability_of_break_up : Option < ProbabilityType >, + #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] pub + probability_of_land_impact : Option < ProbabilityType >, + #[serde(rename = "PROBABILITY_OF_CASUALTY")] pub + probability_of_casualty : Option < ProbabilityType >, + #[serde(rename = "NOMINAL_IMPACT_EPOCH")] pub nominal_impact_epoch + : Option < EpochType >, #[serde(rename = "IMPACT_WINDOW_START")] + pub impact_window_start : Option < EpochType >, + #[serde(rename = "IMPACT_WINDOW_END")] pub impact_window_end : + Option < EpochType >, #[serde(rename = "IMPACT_REF_FRAME")] pub + impact_ref_frame : Option < String >, + #[serde(rename = "NOMINAL_IMPACT_LON")] pub nominal_impact_lon : + Option < LonType >, #[serde(rename = "NOMINAL_IMPACT_LAT")] pub + nominal_impact_lat : Option < LatType >, + #[serde(rename = "NOMINAL_IMPACT_ALT")] pub nominal_impact_alt : + Option < AltType >, #[serde(rename = "IMPACT_1_CONFIDENCE")] pub + impact_1_confidence : Option < PercentageType >, + #[serde(rename = "IMPACT_1_START_LON")] pub impact_1_start_lon : + Option < LonType >, #[serde(rename = "IMPACT_1_START_LAT")] pub + impact_1_start_lat : Option < LatType >, + #[serde(rename = "IMPACT_1_STOP_LON")] pub impact_1_stop_lon : + Option < LonType >, #[serde(rename = "IMPACT_1_STOP_LAT")] pub + impact_1_stop_lat : Option < LatType >, + #[serde(rename = "IMPACT_1_CROSS_TRACK")] pub impact_1_cross_track + : Option < DistanceType >, + #[serde(rename = "IMPACT_2_CONFIDENCE")] pub impact_2_confidence : + Option < PercentageType >, #[serde(rename = "IMPACT_2_START_LON")] + pub impact_2_start_lon : Option < LonType >, + #[serde(rename = "IMPACT_2_START_LAT")] pub impact_2_start_lat : + Option < LatType >, #[serde(rename = "IMPACT_2_STOP_LON")] pub + impact_2_stop_lon : Option < LonType >, + #[serde(rename = "IMPACT_2_STOP_LAT")] pub impact_2_stop_lat : + Option < LatType >, #[serde(rename = "IMPACT_2_CROSS_TRACK")] pub + impact_2_cross_track : Option < DistanceType >, + #[serde(rename = "IMPACT_3_CONFIDENCE")] pub impact_3_confidence : + Option < PercentageType >, #[serde(rename = "IMPACT_3_START_LON")] + pub impact_3_start_lon : Option < LonType >, + #[serde(rename = "IMPACT_3_START_LAT")] pub impact_3_start_lat : + Option < LatType >, #[serde(rename = "IMPACT_3_STOP_LON")] pub + impact_3_stop_lon : Option < LonType >, + #[serde(rename = "IMPACT_3_STOP_LAT")] pub impact_3_stop_lat : + Option < LatType >, #[serde(rename = "IMPACT_3_CROSS_TRACK")] pub + impact_3_cross_track : Option < DistanceType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RdmSpacecraftParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "WET_MASS")] pub wet_mass : Option < MassType >, + #[serde(rename = "DRY_MASS")] pub dry_mass : Option < MassType >, + #[serde(rename = "HAZARDOUS_SUBSTANCES")] pub hazardous_substances + : Option < String >, #[serde(rename = "SOLAR_RAD_AREA")] pub + solar_rad_area : Option < AreaType >, + #[serde(rename = "SOLAR_RAD_COEFF")] pub solar_rad_coeff : Option + < NonNegativeDouble >, #[serde(rename = "DRAG_AREA")] pub + drag_area : Option < AreaType >, #[serde(rename = "DRAG_COEFF")] + pub drag_coeff : Option < NonNegativeDouble >, + #[serde(rename = "RCS")] pub rcs : Option < AreaType >, + #[serde(rename = "BALLISTIC_COEFF")] pub ballistic_coeff : Option + < BallisticCoeffType >, #[serde(rename = "THRUST_ACCELERATION")] + pub thrust_acceleration : Option < Ms2Type >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AltType + { + #[serde(rename = "$text")] pub base : AltRange, + #[serde(rename = "@units")] pub units : Option < LengthUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct BallisticCoeffType + { + #[serde(rename = "$text")] pub base : NonNegativeDouble, + #[serde(rename = "@units")] pub units : Option < + BallisticCoeffUnitsType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct LatType + { + #[serde(rename = "$text")] pub base : LatRange, + #[serde(rename = "@units")] pub units : LatLonUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct LonType + { + #[serde(rename = "$text")] pub base : LonRange, + #[serde(rename = "@units")] pub units : LatLonUnits, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct UserDefinedType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "USER_DEFINED")] pub user_defined_list : Vec < + UserDefinedParameterType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct UserDefinedParameterType + { + #[serde(rename = "$text")] pub base : String, + #[serde(rename = "@parameter")] pub parameter : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct QuaternionType {} + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct QuaternionRateType {} + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct QuaternionDotType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < + QuaternionDotUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RotationAngleType + { + #[serde(rename = "rotation1")] pub rotation1 : + RotationAngleComponentType, #[serde(rename = "rotation2")] pub + rotation2 : RotationAngleComponentType, + #[serde(rename = "rotation3")] pub rotation3 : + RotationAngleComponentType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RotationAngleComponentTypeold + { + #[serde(rename = "@units")] pub units : Option < AngleUnits >, + #[serde(rename = "@angle")] pub angle : AngleKeywordType, + #[serde(rename = "@value")] pub value : AngleRange, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RotationAngleComponentType + { + #[serde(rename = "$text")] pub base : AngleRange, + #[serde(rename = "@angle")] pub angle : AngleKeywordType, + #[serde(rename = "@units")] pub units : Option < AngleUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RotationRateType + { + #[serde(rename = "rotation1")] pub rotation1 : + RotationRateComponentType, #[serde(rename = "rotation2")] pub + rotation2 : RotationRateComponentType, + #[serde(rename = "rotation3")] pub rotation3 : + RotationRateComponentType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RotationRateComponentTypeOld + { + #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, + #[serde(rename = "@rate")] pub rate : AngleRateKeywordType, + #[serde(rename = "@value")] pub value : f64, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RotationRateComponentType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@rate")] pub rate : AngleRateKeywordType, + #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct TorqueType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < TorqueUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + CovarianceMatrixElementsGroup + { + #[serde(rename = "CX_X")] pub cx_x : PositionCovarianceType, + #[serde(rename = "CY_X")] pub cy_x : PositionCovarianceType, + #[serde(rename = "CY_Y")] pub cy_y : PositionCovarianceType, + #[serde(rename = "CZ_X")] pub cz_x : PositionCovarianceType, + #[serde(rename = "CZ_Y")] pub cz_y : PositionCovarianceType, + #[serde(rename = "CZ_Z")] pub cz_z : PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] pub cx_dot_x : + PositionVelocityCovarianceType, #[serde(rename = "CX_DOT_Y")] pub + cx_dot_y : PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] pub cx_dot_z : + PositionVelocityCovarianceType, #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot : VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] pub cy_dot_x : + PositionVelocityCovarianceType, #[serde(rename = "CY_DOT_Y")] pub + cy_dot_y : PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] pub cy_dot_z : + PositionVelocityCovarianceType, #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot : VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] pub cy_dot_y_dot : + VelocityCovarianceType, #[serde(rename = "CZ_DOT_X")] pub cz_dot_x + : PositionVelocityCovarianceType, #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y : PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] pub cz_dot_z : + PositionVelocityCovarianceType, #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot : VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] pub cz_dot_y_dot : + VelocityCovarianceType, #[serde(rename = "CZ_DOT_Z_DOT")] pub + cz_dot_z_dot : VelocityCovarianceType, + } + } +} pub use schema_common :: * ; \ No newline at end of file diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs new file mode 100644 index 00000000..4fc94bf3 --- /dev/null +++ b/crates/lox-utils/src/odm/ocm.rs @@ -0,0 +1,423 @@ +mod schema_ocm +{ + pub mod xml_schema_types + { + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmType + { + #[serde(rename = "header")] pub header : schema_common :: + xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body + : schema_common :: xml_schema_types :: OcmBody, + #[serde(rename = "@id")] pub id : String, + #[serde(rename = "@version")] pub version : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmBody + { + #[serde(rename = "segment")] pub segment : schema_common :: + xml_schema_types :: OcmSegment, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmSegment + { + #[serde(rename = "metadata")] pub metadata : schema_common :: + xml_schema_types :: OcmMetadata, #[serde(rename = "data")] pub + data : schema_common :: xml_schema_types :: OcmData, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmMetadata + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "OBJECT_NAME")] pub object_name : Option < String + >, #[serde(rename = "INTERNATIONAL_DESIGNATOR")] pub + international_designator : Option < String >, + #[serde(rename = "CATALOG_NAME")] pub catalog_name : Option < + String >, #[serde(rename = "OBJECT_DESIGNATOR")] pub + object_designator : Option < String >, + #[serde(rename = "ALTERNATE_NAMES")] pub alternate_names : Option + < String >, #[serde(rename = "ORIGINATOR_POC")] pub originator_poc + : Option < String >, #[serde(rename = "ORIGINATOR_POSITION")] pub + originator_position : Option < String >, + #[serde(rename = "ORIGINATOR_PHONE")] pub originator_phone : + Option < String >, #[serde(rename = "ORIGINATOR_EMAIL")] pub + originator_email : Option < String >, + #[serde(rename = "ORIGINATOR_ADDRESS")] pub originator_address : + Option < String >, #[serde(rename = "TECH_ORG")] pub tech_org : + Option < String >, #[serde(rename = "TECH_POC")] pub tech_poc : + Option < String >, #[serde(rename = "TECH_POSITION")] pub + tech_position : Option < String >, #[serde(rename = "TECH_PHONE")] + pub tech_phone : Option < String >, + #[serde(rename = "TECH_EMAIL")] pub tech_email : Option < String + >, #[serde(rename = "TECH_ADDRESS")] pub tech_address : Option < + String >, #[serde(rename = "PREVIOUS_MESSAGE_ID")] pub + previous_message_id : Option < String >, + #[serde(rename = "NEXT_MESSAGE_ID")] pub next_message_id : Option + < String >, #[serde(rename = "ADM_MSG_LINK")] pub adm_msg_link : + Option < String >, #[serde(rename = "CDM_MSG_LINK")] pub + cdm_msg_link : Option < String >, + #[serde(rename = "PRM_MSG_LINK")] pub prm_msg_link : Option < + String >, #[serde(rename = "RDM_MSG_LINK")] pub rdm_msg_link : + Option < String >, #[serde(rename = "TDM_MSG_LINK")] pub + tdm_msg_link : Option < String >, #[serde(rename = "OPERATOR")] + pub operator : Option < String >, #[serde(rename = "OWNER")] pub + owner : Option < String >, #[serde(rename = "COUNTRY")] pub + country : Option < String >, #[serde(rename = "CONSTELLATION")] + pub constellation : Option < String >, + #[serde(rename = "OBJECT_TYPE")] pub object_type : Option < + schema_common :: xml_schema_types :: ObjectDescriptionType >, + #[serde(rename = "TIME_SYSTEM")] pub time_system : String, + #[serde(rename = "EPOCH_TZERO")] pub epoch_tzero : schema_common + :: xml_schema_types :: EpochType, #[serde(rename = "OPS_STATUS")] + pub ops_status : Option < String >, + #[serde(rename = "ORBIT_CATEGORY")] pub orbit_category : Option < + String >, #[serde(rename = "OCM_DATA_ELEMENTS")] pub + ocm_data_elements : Option < String >, + #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] pub sclk_offset_at_epoch + : Option < schema_common :: xml_schema_types :: TimeOffsetType >, + #[serde(rename = "SCLK_SEC_PER_SI_SEC")] pub sclk_sec_per_si_sec : + Option < schema_common :: xml_schema_types :: DurationType >, + #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] pub + previous_message_epoch : Option < schema_common :: + xml_schema_types :: EpochType >, + #[serde(rename = "NEXT_MESSAGE_EPOCH")] pub next_message_epoch : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "START_TIME")] pub start_time : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "STOP_TIME")] pub stop_time : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "TIME_SPAN")] pub time_span : Option < + schema_common :: xml_schema_types :: OcmDayIntervalType >, + #[serde(rename = "TAIMUTC_AT_TZERO")] pub taimutc_at_tzero : + Option < schema_common :: xml_schema_types :: TimeOffsetType >, + #[serde(rename = "NEXT_LEAP_EPOCH")] pub next_leap_epoch : Option + < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "NEXT_LEAP_TAIMUTC")] pub next_leap_taimutc : + Option < schema_common :: xml_schema_types :: TimeOffsetType >, + #[serde(rename = "UT1MUTC_AT_TZERO")] pub ut1mutc_at_tzero : + Option < schema_common :: xml_schema_types :: TimeOffsetType >, + #[serde(rename = "EOP_SOURCE")] pub eop_source : Option < String + >, #[serde(rename = "INTERP_METHOD_EOP")] pub interp_method_eop : + Option < String >, #[serde(rename = "CELESTIAL_SOURCE")] pub + celestial_source : Option < String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmData + { + #[serde(rename = "traj")] pub traj_list : Vec < schema_common :: + xml_schema_types :: OcmTrajStateType >, #[serde(rename = "phys")] + pub phys : Option < schema_common :: xml_schema_types :: + OcmPhysicalDescriptionType >, #[serde(rename = "cov")] pub + cov_list : Vec < schema_common :: xml_schema_types :: + OcmCovarianceMatrixType >, #[serde(rename = "man")] pub man_list : + Vec < schema_common :: xml_schema_types :: + OcmManeuverParametersType >, #[serde(rename = "pert")] pub pert : + Option < schema_common :: xml_schema_types :: OcmPerturbationsType + >, #[serde(rename = "od")] pub od : Option < schema_common :: + xml_schema_types :: OcmOdParametersType >, + #[serde(rename = "user")] pub user : Option < schema_common :: + xml_schema_types :: UserDefinedType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmTrajStateType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "TRAJ_ID")] pub traj_id : Option < String >, + #[serde(rename = "TRAJ_PREV_ID")] pub traj_prev_id : Option < + String >, #[serde(rename = "TRAJ_NEXT_ID")] pub traj_next_id : + Option < String >, #[serde(rename = "TRAJ_BASIS")] pub traj_basis + : Option < schema_common :: xml_schema_types :: TrajBasisType >, + #[serde(rename = "TRAJ_BASIS_ID")] pub traj_basis_id : Option < + String >, #[serde(rename = "INTERPOLATION")] pub interpolation : + Option < String >, #[serde(rename = "INTERPOLATION_DEGREE")] pub + interpolation_degree : Option < u64 >, + #[serde(rename = "PROPAGATOR")] pub propagator : Option < String + >, #[serde(rename = "CENTER_NAME")] pub center_name : String, + #[serde(rename = "TRAJ_REF_FRAME")] pub traj_ref_frame : String, + #[serde(rename = "TRAJ_FRAME_EPOCH")] pub traj_frame_epoch : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "USEABLE_START_TIME")] pub useable_start_time : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "USEABLE_STOP_TIME")] pub useable_stop_time : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "ORB_REVNUM")] pub orb_revnum : Option < + schema_common :: xml_schema_types :: NonNegativeDouble >, + #[serde(rename = "ORB_REVNUM_BASIS")] pub orb_revnum_basis : + Option < schema_common :: xml_schema_types :: RevNumBasisType >, + #[serde(rename = "TRAJ_TYPE")] pub traj_type : String, + #[serde(rename = "ORB_AVERAGING")] pub orb_averaging : Option < + String >, #[serde(rename = "TRAJ_UNITS")] pub traj_units : Option + < String >, #[serde(rename = "trajLine")] pub traj_line_list : Vec + < String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmPhysicalDescriptionType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "MANUFACTURER")] pub manufacturer : Option < + String >, #[serde(rename = "BUS_MODEL")] pub bus_model : Option < + String >, #[serde(rename = "DOCKED_WITH")] pub docked_with : + Option < String >, #[serde(rename = "DRAG_CONST_AREA")] pub + drag_const_area : Option < schema_common :: xml_schema_types :: + AreaType >, #[serde(rename = "DRAG_COEFF_NOM")] pub drag_coeff_nom + : Option < schema_common :: xml_schema_types :: PositiveDouble >, + #[serde(rename = "DRAG_UNCERTAINTY")] pub drag_uncertainty : + Option < schema_common :: xml_schema_types :: PercentageType >, + #[serde(rename = "INITIAL_WET_MASS")] pub initial_wet_mass : + Option < schema_common :: xml_schema_types :: MassType >, + #[serde(rename = "WET_MASS")] pub wet_mass : Option < + schema_common :: xml_schema_types :: MassType >, + #[serde(rename = "DRY_MASS")] pub dry_mass : Option < + schema_common :: xml_schema_types :: MassType >, + #[serde(rename = "OEB_PARENT_FRAME")] pub oeb_parent_frame : + Option < String >, #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] pub + oeb_parent_frame_epoch : Option < schema_common :: + xml_schema_types :: EpochType >, #[serde(rename = "OEB_Q1")] pub + oeb_q1 : Option < f64 >, #[serde(rename = "OEB_Q2")] pub oeb_q2 : + Option < f64 >, #[serde(rename = "OEB_Q3")] pub oeb_q3 : Option < + f64 >, #[serde(rename = "OEB_QC")] pub oeb_qc : Option < f64 >, + #[serde(rename = "OEB_MAX")] pub oeb_max : Option < schema_common + :: xml_schema_types :: OcmLengthType >, + #[serde(rename = "OEB_INT")] pub oeb_int : Option < schema_common + :: xml_schema_types :: OcmLengthType >, + #[serde(rename = "OEB_MIN")] pub oeb_min : Option < schema_common + :: xml_schema_types :: OcmLengthType >, + #[serde(rename = "AREA_ALONG_OEB_MAX")] pub area_along_oeb_max : + Option < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "AREA_ALONG_OEB_INT")] pub area_along_oeb_int : + Option < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "AREA_ALONG_OEB_MIN")] pub area_along_oeb_min : + Option < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "AREA_MIN_FOR_PC")] pub area_min_for_pc : Option + < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "AREA_MAX_FOR_PC")] pub area_max_for_pc : Option + < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "AREA_TYP_FOR_PC")] pub area_typ_for_pc : Option + < schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "RCS")] pub rcs : Option < schema_common :: + xml_schema_types :: AreaType >, #[serde(rename = "RCS_MIN")] pub + rcs_min : Option < schema_common :: xml_schema_types :: AreaType + >, #[serde(rename = "RCS_MAX")] pub rcs_max : Option < + schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "SRP_CONST_AREA")] pub srp_const_area : Option < + schema_common :: xml_schema_types :: AreaType >, + #[serde(rename = "SOLAR_RAD_COEFF")] pub solar_rad_coeff : Option + < f64 >, #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] pub + solar_rad_uncertainty : Option < schema_common :: xml_schema_types + :: PercentageType >, #[serde(rename = "VM_ABSOLUTE")] pub + vm_absolute : Option < f64 >, #[serde(rename = "VM_APPARENT_MIN")] + pub vm_apparent_min : Option < f64 >, + #[serde(rename = "VM_APPARENT")] pub vm_apparent : Option < f64 >, + #[serde(rename = "VM_APPARENT_MAX")] pub vm_apparent_max : Option + < f64 >, #[serde(rename = "REFLECTANCE")] pub reflectance : Option + < schema_common :: xml_schema_types :: ProbabilityType >, + #[serde(rename = "ATT_CONTROL_MODE")] pub att_control_mode : + Option < String >, #[serde(rename = "ATT_ACTUATOR_TYPE")] pub + att_actuator_type : Option < String >, + #[serde(rename = "ATT_KNOWLEDGE")] pub att_knowledge : Option < + schema_common :: xml_schema_types :: AngleType >, + #[serde(rename = "ATT_CONTROL")] pub att_control : Option < + schema_common :: xml_schema_types :: AngleType >, + #[serde(rename = "ATT_POINTING")] pub att_pointing : Option < + schema_common :: xml_schema_types :: AngleType >, + #[serde(rename = "AVG_MANEUVER_FREQ")] pub avg_maneuver_freq : + Option < schema_common :: xml_schema_types :: ManeuverFreqType >, + #[serde(rename = "MAX_THRUST")] pub max_thrust : Option < + schema_common :: xml_schema_types :: ThrustType >, + #[serde(rename = "DV_BOL")] pub dv_bol : Option < schema_common :: + xml_schema_types :: VelocityType >, + #[serde(rename = "DV_REMAINING")] pub dv_remaining : Option < + schema_common :: xml_schema_types :: VelocityType >, + #[serde(rename = "IXX")] pub ixx : Option < schema_common :: + xml_schema_types :: MomentType >, #[serde(rename = "IYY")] pub iyy + : Option < schema_common :: xml_schema_types :: MomentType >, + #[serde(rename = "IZZ")] pub izz : Option < schema_common :: + xml_schema_types :: MomentType >, #[serde(rename = "IXY")] pub ixy + : Option < schema_common :: xml_schema_types :: MomentType >, + #[serde(rename = "IXZ")] pub ixz : Option < schema_common :: + xml_schema_types :: MomentType >, #[serde(rename = "IYZ")] pub iyz + : Option < schema_common :: xml_schema_types :: MomentType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmCovarianceMatrixType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "COV_ID")] pub cov_id : Option < String >, + #[serde(rename = "COV_PREV_ID")] pub cov_prev_id : Option < String + >, #[serde(rename = "COV_NEXT_ID")] pub cov_next_id : Option < + String >, #[serde(rename = "COV_BASIS")] pub cov_basis : Option < + schema_common :: xml_schema_types :: CovBasisType >, + #[serde(rename = "COV_BASIS_ID")] pub cov_basis_id : Option < + String >, #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : + String, #[serde(rename = "COV_FRAME_EPOCH")] pub cov_frame_epoch : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "COV_SCALE_MIN")] pub cov_scale_min : Option < + f64 >, #[serde(rename = "COV_SCALE_MAX")] pub cov_scale_max : + Option < f64 >, #[serde(rename = "COV_CONFIDENCE")] pub + cov_confidence : Option < schema_common :: xml_schema_types :: + PercentageType >, #[serde(rename = "COV_TYPE")] pub cov_type : + String, #[serde(rename = "COV_ORDERING")] pub cov_ordering : + schema_common :: xml_schema_types :: CovOrderType, + #[serde(rename = "COV_UNITS")] pub cov_units : Option < String >, + #[serde(rename = "covLine")] pub cov_line_list : Vec < String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmManeuverParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "MAN_ID")] pub man_id : String, + #[serde(rename = "MAN_PREV_ID")] pub man_prev_id : Option < String + >, #[serde(rename = "MAN_NEXT_ID")] pub man_next_id : Option < + String >, #[serde(rename = "MAN_BASIS")] pub man_basis : Option < + schema_common :: xml_schema_types :: ManBasisType >, + #[serde(rename = "MAN_BASIS_ID")] pub man_basis_id : Option < + String >, #[serde(rename = "MAN_DEVICE_ID")] pub man_device_id : + String, #[serde(rename = "MAN_PREV_EPOCH")] pub man_prev_epoch : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "MAN_NEXT_EPOCH")] pub man_next_epoch : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "MAN_PURPOSE")] pub man_purpose : Option < String + >, #[serde(rename = "MAN_PRED_SOURCE")] pub man_pred_source : + Option < String >, #[serde(rename = "MAN_REF_FRAME")] pub + man_ref_frame : String, #[serde(rename = "MAN_FRAME_EPOCH")] pub + man_frame_epoch : Option < schema_common :: xml_schema_types :: + EpochType >, #[serde(rename = "GRAV_ASSIST_NAME")] pub + grav_assist_name : Option < String >, #[serde(rename = "DC_TYPE")] + pub dc_type : schema_common :: xml_schema_types :: ManDcType, + #[serde(rename = "DC_WIN_OPEN")] pub dc_win_open : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "DC_WIN_CLOSE")] pub dc_win_close : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "DC_MIN_CYCLES")] pub dc_min_cycles : Option < + u64 >, #[serde(rename = "DC_MAX_CYCLES")] pub dc_max_cycles : + Option < u64 >, #[serde(rename = "DC_EXEC_START")] pub + dc_exec_start : Option < schema_common :: xml_schema_types :: + EpochType >, #[serde(rename = "DC_EXEC_STOP")] pub dc_exec_stop : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "DC_REF_TIME")] pub dc_ref_time : Option < + schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "DC_TIME_PULSE_DURATION")] pub + dc_time_pulse_duration : Option < schema_common :: + xml_schema_types :: DurationType >, + #[serde(rename = "DC_TIME_PULSE_PERIOD")] pub dc_time_pulse_period + : Option < schema_common :: xml_schema_types :: DurationType >, + #[serde(rename = "DC_REF_DIR")] pub dc_ref_dir : Option < + schema_common :: xml_schema_types :: Vec3Double >, + #[serde(rename = "DC_BODY_FRAME")] pub dc_body_frame : Option < + String >, #[serde(rename = "DC_BODY_TRIGGER")] pub dc_body_trigger + : Option < schema_common :: xml_schema_types :: Vec3Double >, + #[serde(rename = "DC_PA_START_ANGLE")] pub dc_pa_start_angle : + Option < schema_common :: xml_schema_types :: AngleType >, + #[serde(rename = "DC_PA_STOP_ANGLE")] pub dc_pa_stop_angle : + Option < schema_common :: xml_schema_types :: AngleType >, + #[serde(rename = "MAN_COMPOSITION")] pub man_composition : String, + #[serde(rename = "MAN_UNITS")] pub man_units : Option < String >, + #[serde(rename = "manLine")] pub man_line_list : Vec < String >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmPerturbationsType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "ATMOSPHERIC_MODEL")] pub atmospheric_model : + Option < String >, #[serde(rename = "GRAVITY_MODEL")] pub + gravity_model : Option < String >, + #[serde(rename = "EQUATORIAL_RADIUS")] pub equatorial_radius : + Option < schema_common :: xml_schema_types :: PositionType >, + #[serde(rename = "GM")] pub gm : Option < schema_common :: + xml_schema_types :: GmType >, + #[serde(rename = "N_BODY_PERTURBATIONS")] pub n_body_perturbations + : Option < String >, #[serde(rename = "CENTRAL_BODY_ROTATION")] + pub central_body_rotation : Option < schema_common :: + xml_schema_types :: AngleRateType >, + #[serde(rename = "OBLATE_FLATTENING")] pub oblate_flattening : + Option < schema_common :: xml_schema_types :: PositiveDouble >, + #[serde(rename = "OCEAN_TIDES_MODEL")] pub ocean_tides_model : + Option < String >, #[serde(rename = "SOLID_TIDES_MODEL")] pub + solid_tides_model : Option < String >, + #[serde(rename = "REDUCTION_THEORY")] pub reduction_theory : + Option < String >, #[serde(rename = "ALBEDO_MODEL")] pub + albedo_model : Option < String >, + #[serde(rename = "ALBEDO_GRID_SIZE")] pub albedo_grid_size : + Option < u64 >, #[serde(rename = "SHADOW_MODEL")] pub shadow_model + : Option < String >, #[serde(rename = "SHADOW_BODIES")] pub + shadow_bodies : Option < String >, #[serde(rename = "SRP_MODEL")] + pub srp_model : Option < String >, + #[serde(rename = "SW_DATA_SOURCE")] pub sw_data_source : Option < + String >, #[serde(rename = "SW_DATA_EPOCH")] pub sw_data_epoch : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "SW_INTERP_METHOD")] pub sw_interp_method : + Option < String >, #[serde(rename = "FIXED_GEOMAG_KP")] pub + fixed_geomag_kp : Option < schema_common :: xml_schema_types :: + GeomagType >, #[serde(rename = "FIXED_GEOMAG_AP")] pub + fixed_geomag_ap : Option < schema_common :: xml_schema_types :: + GeomagType >, #[serde(rename = "FIXED_GEOMAG_DST")] pub + fixed_geomag_dst : Option < schema_common :: xml_schema_types :: + GeomagType >, #[serde(rename = "FIXED_F10P7")] pub fixed_f10p7 : + Option < schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_F10P7_MEAN")] pub fixed_f10p7_mean : + Option < schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_M10P7")] pub fixed_m10p7 : Option < + schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_M10P7_MEAN")] pub fixed_m10p7_mean : + Option < schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_S10P7")] pub fixed_s10p7 : Option < + schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_S10P7_MEAN")] pub fixed_s10p7_mean : + Option < schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_Y10P7")] pub fixed_y10p7 : Option < + schema_common :: xml_schema_types :: SolarFluxType >, + #[serde(rename = "FIXED_Y10P7_MEAN")] pub fixed_y10p7_mean : + Option < schema_common :: xml_schema_types :: SolarFluxType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OcmOdParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "OD_ID")] pub od_id : String, + #[serde(rename = "OD_PREV_ID")] pub od_prev_id : Option < String + >, #[serde(rename = "OD_METHOD")] pub od_method : String, + #[serde(rename = "OD_EPOCH")] pub od_epoch : schema_common :: + xml_schema_types :: EpochType, + #[serde(rename = "DAYS_SINCE_FIRST_OBS")] pub days_since_first_obs + : Option < schema_common :: xml_schema_types :: OcmDayIntervalType + >, #[serde(rename = "DAYS_SINCE_LAST_OBS")] pub + days_since_last_obs : Option < schema_common :: xml_schema_types + :: OcmDayIntervalType >, #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span : Option < schema_common :: + xml_schema_types :: OcmDayIntervalType >, + #[serde(rename = "ACTUAL_OD_SPAN")] pub actual_od_span : Option < + schema_common :: xml_schema_types :: OcmDayIntervalType >, + #[serde(rename = "OBS_AVAILABLE")] pub obs_available : Option < + u64 >, #[serde(rename = "OBS_USED")] pub obs_used : Option < u64 + >, #[serde(rename = "TRACKS_AVAILABLE")] pub tracks_available : + Option < u64 >, #[serde(rename = "TRACKS_USED")] pub tracks_used : + Option < u64 >, #[serde(rename = "MAXIMUM_OBS_GAP")] pub + maximum_obs_gap : Option < schema_common :: xml_schema_types :: + OcmDayIntervalType >, #[serde(rename = "OD_EPOCH_EIGMAJ")] pub + od_epoch_eigmaj : Option < schema_common :: xml_schema_types :: + OcmLengthType >, #[serde(rename = "OD_EPOCH_EIGINT")] pub + od_epoch_eigint : Option < schema_common :: xml_schema_types :: + OcmLengthType >, #[serde(rename = "OD_EPOCH_EIGMIN")] pub + od_epoch_eigmin : Option < schema_common :: xml_schema_types :: + OcmLengthType >, #[serde(rename = "OD_MAX_PRED_EIGMAJ")] pub + od_max_pred_eigmaj : Option < schema_common :: xml_schema_types :: + OcmLengthType >, #[serde(rename = "OD_MIN_PRED_EIGMIN")] pub + od_min_pred_eigmin : Option < schema_common :: xml_schema_types :: + OcmLengthType >, #[serde(rename = "OD_CONFIDENCE")] pub + od_confidence : Option < schema_common :: xml_schema_types :: + PercentageType >, #[serde(rename = "GDOP")] pub gdop : Option < + schema_common :: xml_schema_types :: NonNegativeDouble >, + #[serde(rename = "SOLVE_N")] pub solve_n : Option < u64 >, + #[serde(rename = "SOLVE_STATES")] pub solve_states : Option < + String >, #[serde(rename = "CONSIDER_N")] pub consider_n : Option + < u64 >, #[serde(rename = "CONSIDER_PARAMS")] pub consider_params + : Option < String >, #[serde(rename = "SEDR")] pub sedr : Option < + schema_common :: xml_schema_types :: WkgType >, + #[serde(rename = "SENSORS_N")] pub sensors_n : Option < u64 >, + #[serde(rename = "SENSORS")] pub sensors : Option < String >, + #[serde(rename = "WEIGHTED_RMS")] pub weighted_rms : Option < + schema_common :: xml_schema_types :: NonNegativeDouble >, + #[serde(rename = "DATA_TYPES")] pub data_types : Option < String + >, + } + } +} pub use schema_ocm :: * ; \ No newline at end of file diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs new file mode 100644 index 00000000..501472ce --- /dev/null +++ b/crates/lox-utils/src/odm/oem.rs @@ -0,0 +1,61 @@ +mod schema_oem +{ + pub mod xml_schema_types + { + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemType + { + #[serde(rename = "header")] pub header : schema_common :: + xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body + : schema_common :: xml_schema_types :: OemBody, + #[serde(rename = "@id")] pub id : String, + #[serde(rename = "@version")] pub version : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemBody + { + #[serde(rename = "segment")] pub segment_list : Vec < + schema_common :: xml_schema_types :: OemSegment >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemSegment + { + #[serde(rename = "metadata")] pub metadata : schema_common :: + xml_schema_types :: OemMetadata, #[serde(rename = "data")] pub + data : schema_common :: xml_schema_types :: OemData, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemMetadata + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "OBJECT_NAME")] pub object_name : String, + #[serde(rename = "OBJECT_ID")] pub object_id : String, + #[serde(rename = "CENTER_NAME")] pub center_name : String, + #[serde(rename = "REF_FRAME")] pub ref_frame : String, + #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option + < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "TIME_SYSTEM")] pub time_system : String, + #[serde(rename = "START_TIME")] pub start_time : schema_common :: + xml_schema_types :: EpochType, + #[serde(rename = "USEABLE_START_TIME")] pub useable_start_time : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "USEABLE_STOP_TIME")] pub useable_stop_time : + Option < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "STOP_TIME")] pub stop_time : schema_common :: + xml_schema_types :: EpochType, #[serde(rename = "INTERPOLATION")] + pub interpolation : Option < String >, + #[serde(rename = "INTERPOLATION_DEGREE")] pub interpolation_degree + : Option < u64 >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OemData + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "stateVector")] pub state_vector_list : Vec < + schema_common :: xml_schema_types :: StateVectorAccType >, + #[serde(rename = "covarianceMatrix")] pub covariance_matrix_list : + Vec < schema_common :: xml_schema_types :: OemCovarianceMatrixType + >, + } + } +} pub use schema_oem :: * ; \ No newline at end of file diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs new file mode 100644 index 00000000..859bf178 --- /dev/null +++ b/crates/lox-utils/src/odm/omm.rs @@ -0,0 +1,156 @@ +mod schema_omm +{ + pub mod xml_schema_types + { + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + BStarUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + BTermUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + AgomUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + ElementSetNoType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + RevUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + DRevUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + DdRevUnits(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct + SpacewarnType(#[serde(rename = "$text")] std :: string :: String) ; + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OmmType + { + #[serde(rename = "header")] pub header : schema_common :: + xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body + : schema_common :: xml_schema_types :: OmmBody, + #[serde(rename = "@id")] pub id : String, + #[serde(rename = "@version")] pub version : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OmmBody + { + #[serde(rename = "segment")] pub segment : schema_common :: + xml_schema_types :: OmmSegment, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OmmSegment + { + #[serde(rename = "metadata")] pub metadata : schema_common :: + xml_schema_types :: OmmMetadata, #[serde(rename = "data")] pub + data : schema_common :: xml_schema_types :: OmmData, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OmmMetadata + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "OBJECT_NAME")] pub object_name : String, + #[serde(rename = "OBJECT_ID")] pub object_id : String, + #[serde(rename = "CENTER_NAME")] pub center_name : String, + #[serde(rename = "REF_FRAME")] pub ref_frame : String, + #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option + < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "TIME_SYSTEM")] pub time_system : String, + #[serde(rename = "MEAN_ELEMENT_THEORY")] pub mean_element_theory : + String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OmmData + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "meanElements")] pub mean_elements : + schema_common :: xml_schema_types :: MeanElementsType, + #[serde(rename = "spacecraftParameters")] pub + spacecraft_parameters : Option < schema_common :: xml_schema_types + :: SpacecraftParametersType >, #[serde(rename = "tleParameters")] + pub tle_parameters : Option < schema_common :: xml_schema_types :: + TleParametersType >, #[serde(rename = "covarianceMatrix")] pub + covariance_matrix : Option < schema_common :: xml_schema_types :: + OpmCovarianceMatrixType >, + #[serde(rename = "userDefinedParameters")] pub + user_defined_parameters : Option < schema_common :: + xml_schema_types :: UserDefinedType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct MeanElementsType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "EPOCH")] pub epoch : schema_common :: + xml_schema_types :: EpochType, #[serde(rename = "ECCENTRICITY")] + pub eccentricity : schema_common :: xml_schema_types :: + NonNegativeDouble, #[serde(rename = "INCLINATION")] pub + inclination : schema_common :: xml_schema_types :: + InclinationType, #[serde(rename = "RA_OF_ASC_NODE")] pub + ra_of_asc_node : schema_common :: xml_schema_types :: AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] pub arg_of_pericenter : + schema_common :: xml_schema_types :: AngleType, + #[serde(rename = "MEAN_ANOMALY")] pub mean_anomaly : schema_common + :: xml_schema_types :: AngleType, #[serde(rename = "GM")] pub gm : + Option < schema_common :: xml_schema_types :: GmType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct TleParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "EPHEMERIS_TYPE")] pub ephemeris_type : Option < + i32 >, #[serde(rename = "CLASSIFICATION_TYPE")] pub + classification_type : Option < String >, + #[serde(rename = "NORAD_CAT_ID")] pub norad_cat_id : Option < i32 + >, #[serde(rename = "ELEMENT_SET_NO")] pub element_set_no : Option + < schema_common :: xml_schema_types :: ElementSetNoType >, + #[serde(rename = "REV_AT_EPOCH")] pub rev_at_epoch : Option < u64 + >, #[serde(rename = "MEAN_MOTION_DOT")] pub mean_motion_dot : + schema_common :: xml_schema_types :: DRevType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct BStarType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: BStarUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct BTermType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: BTermUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct AgomType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: AgomUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct RevType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: RevUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DRevType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: DRevUnits >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct DdRevType + { + #[serde(rename = "$text")] pub base : f64, + #[serde(rename = "@units")] pub units : Option < schema_common :: + xml_schema_types :: DdRevUnits >, + } + } +} pub use schema_omm :: * ; \ No newline at end of file diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs new file mode 100644 index 00000000..4ecb63be --- /dev/null +++ b/crates/lox-utils/src/odm/opm.rs @@ -0,0 +1,94 @@ +mod schema_opm +{ + pub mod xml_schema_types + { + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmType + { + #[serde(rename = "header")] pub header : schema_common :: + xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body + : schema_common :: xml_schema_types :: OpmBody, + #[serde(rename = "@id")] pub id : String, + #[serde(rename = "@version")] pub version : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmBody + { + #[serde(rename = "segment")] pub segment : schema_common :: + xml_schema_types :: OpmSegment, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmSegment + { + #[serde(rename = "metadata")] pub metadata : schema_common :: + xml_schema_types :: OpmMetadata, #[serde(rename = "data")] pub + data : schema_common :: xml_schema_types :: OpmData, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmMetadata + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "OBJECT_NAME")] pub object_name : String, + #[serde(rename = "OBJECT_ID")] pub object_id : String, + #[serde(rename = "CENTER_NAME")] pub center_name : String, + #[serde(rename = "REF_FRAME")] pub ref_frame : String, + #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option + < schema_common :: xml_schema_types :: EpochType >, + #[serde(rename = "TIME_SYSTEM")] pub time_system : String, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct OpmData + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "stateVector")] pub state_vector : schema_common + :: xml_schema_types :: StateVectorType, + #[serde(rename = "keplerianElements")] pub keplerian_elements : + Option < schema_common :: xml_schema_types :: + KeplerianElementsType >, #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters : Option < schema_common :: + xml_schema_types :: SpacecraftParametersType >, + #[serde(rename = "covarianceMatrix")] pub covariance_matrix : + Option < schema_common :: xml_schema_types :: + OpmCovarianceMatrixType >, #[serde(rename = "maneuverParameters")] + pub maneuver_parameters_list : Vec < schema_common :: + xml_schema_types :: ManeuverParametersType >, + #[serde(rename = "userDefinedParameters")] pub + user_defined_parameters : Option < schema_common :: + xml_schema_types :: UserDefinedType >, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct KeplerianElementsType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "SEMI_MAJOR_AXIS")] pub semi_major_axis : + schema_common :: xml_schema_types :: DistanceType, + #[serde(rename = "ECCENTRICITY")] pub eccentricity : schema_common + :: xml_schema_types :: NonNegativeDouble, + #[serde(rename = "INCLINATION")] pub inclination : schema_common + :: xml_schema_types :: InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] pub ra_of_asc_node : + schema_common :: xml_schema_types :: AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] pub arg_of_pericenter : + schema_common :: xml_schema_types :: AngleType, + #[serde(rename = "GM")] pub gm : schema_common :: xml_schema_types + :: GmType, + } + #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde + :: Serialize)] #[serde(default)] pub struct ManeuverParametersType + { + #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, + #[serde(rename = "MAN_EPOCH_IGNITION")] pub man_epoch_ignition : + schema_common :: xml_schema_types :: EpochType, + #[serde(rename = "MAN_DURATION")] pub man_duration : schema_common + :: xml_schema_types :: DurationType, + #[serde(rename = "MAN_DELTA_MASS")] pub man_delta_mass : + schema_common :: xml_schema_types :: DeltamassType, + #[serde(rename = "MAN_REF_FRAME")] pub man_ref_frame : String, + #[serde(rename = "MAN_DV_1")] pub man_dv_1 : schema_common :: + xml_schema_types :: VelocityType, #[serde(rename = "MAN_DV_2")] + pub man_dv_2 : schema_common :: xml_schema_types :: VelocityType, + #[serde(rename = "MAN_DV_3")] pub man_dv_3 : schema_common :: + xml_schema_types :: VelocityType, + } + } +} pub use schema_opm :: * ; \ No newline at end of file From f6af862e798e9fd25831a1ff8873ce893cf5ba56 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 17:50:10 +0100 Subject: [PATCH 002/150] Fix whitespace --- crates/lox-utils/src/odm/common.rs | 2011 ++++++++++++++++------------ crates/lox-utils/src/odm/ocm.rs | 938 +++++++------ crates/lox-utils/src/odm/oem.rs | 125 +- crates/lox-utils/src/odm/omm.rs | 326 +++-- crates/lox-utils/src/odm/opm.rs | 191 +-- 5 files changed, 2054 insertions(+), 1537 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 3421be80..3ba53990 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -1,848 +1,1173 @@ -mod schema_common -{ - pub mod xml_schema_types - { - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AccUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngleUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngleRange(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngleRateUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngMomentumUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngVelFrameType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AreaUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - DayIntervalUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - FrequencyUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - GmUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - InclinationRange(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - LengthUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - MassUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - MomentUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - WkgUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ObjectDescriptionType(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Ms2Units(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Km2Units(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Km2sUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Km2s2Units(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PositionUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - VelocityUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq)] pub struct VecDouble - { pub items : Vec < f64 > } impl yaserde :: YaDeserialize for - VecDouble - { - fn deserialize < R : std :: io :: Read > - (reader : & mut yaserde :: de :: Deserializer < R >) -> Result < - Self, String > - { - loop - { - match reader.next_event() ? - { - xml :: reader :: XmlEvent :: StartElement { .. } => {} xml - :: reader :: XmlEvent :: Characters(ref text_content) => - { - let items : Vec < f64 > = - text_content.split(' ').map(| item | - item.to_owned()).map(| item | - item.parse().unwrap()).collect() ; return - Ok(VecDouble { items }) ; - } _ => { break ; } +mod schema_common { + pub mod xml_schema_types { + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AccUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleRange(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleRateUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngMomentumUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngVelFrameType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AreaUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DayIntervalUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct FrequencyUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct GmUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct InclinationRange(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LengthUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct MassUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct MomentUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct WkgUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ObjectDescriptionType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Ms2Units(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2Units(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2sUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2s2Units(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct VelocityUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq)] + pub struct VecDouble { + pub items: Vec, + } + impl yaserde::YaDeserialize for VecDouble { + fn deserialize( + reader: &mut yaserde::de::Deserializer, + ) -> Result { + loop { + match reader.next_event()? { + xml::reader::XmlEvent::StartElement { .. } => {} + xml::reader::XmlEvent::Characters(ref text_content) => { + let items: Vec = text_content + .split(' ') + .map(|item| item.to_owned()) + .map(|item| item.parse().unwrap()) + .collect(); + return Ok(VecDouble { items }); + } + _ => { + break; + } } - } Err("Unable to parse attribute".to_string()) + } + Err("Unable to parse attribute".to_string()) } - } impl yaserde :: YaSerialize for VecDouble - { - fn serialize < W : std :: io :: Write > - (& self, writer : & mut yaserde :: ser :: Serializer < W >) -> - Result < (), String > - { - let content = - self.items.iter().map(| item | item.to_string()).collect :: < - Vec < String >> ().join(" ") ; let data_event = xml :: writer - :: XmlEvent :: characters(& content) ; - writer.write(data_event).map_err(| e | e.to_string()) ? ; + } + impl yaserde::YaSerialize for VecDouble { + fn serialize( + &self, + writer: &mut yaserde::ser::Serializer, + ) -> Result<(), String> { + let content = self + .items + .iter() + .map(|item| item.to_string()) + .collect::>() + .join(" "); + let data_event = xml::writer::XmlEvent::characters(&content); + writer.write(data_event).map_err(|e| e.to_string())?; Ok(()) - } fn - serialize_attributes(& self, mut source_attributes : Vec < xml :: - attribute :: OwnedAttribute >, mut source_namespace : xml :: - namespace :: Namespace) -> Result < - (Vec < xml :: attribute :: OwnedAttribute >, xml :: namespace :: - Namespace), String > { Ok((source_attributes, source_namespace)) } - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Vec3Double(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Vec6Double(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Vec9Double(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - EpochType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - TimeUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - TimeSystemType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - NegativeDouble(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - NonNegativeDouble(#[serde(rename = "$text")] std :: string :: String) - ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - NonPositiveDouble(#[serde(rename = "$text")] std :: string :: String) - ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PercentType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PositiveDouble(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - Range100Type(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ProbabilityType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PercentageUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - YesNoType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - TrajBasisType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RevNumBasisType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - CovBasisType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ManBasisType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ManDcType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - NumPerYearUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ThrustUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - CovOrderType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - GeomagUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - SolarFluxUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PositionCovarianceUnits(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - VelocityCovarianceUnits(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std :: - string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - BallisticCoeffUnitsType(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - LatRange(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AltRange(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - LonRange(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - LatLonUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ControlledType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - DisintegrationType(#[serde(rename = "$text")] std :: string :: String) - ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ImpactUncertaintyType(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ReentryUncertaintyMethodType(#[serde(rename = "$text")] std :: string - :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - QuaternionComponentType(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - QuaternionDotUnits(#[serde(rename = "$text")] std :: string :: String) - ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RotDirectionType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RotseqType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngleKeywordType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AngleRateKeywordType(#[serde(rename = "$text")] std :: string :: - String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ApmRateFrameType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - TorqueUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct NdmHeader - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "CREATION_DATE")] pub creation_date : EpochType, - #[serde(rename = "ORIGINATOR")] pub originator : String, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AdmHeader - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "CREATION_DATE")] pub creation_date : EpochType, - #[serde(rename = "ORIGINATOR")] pub originator : String, - #[serde(rename = "MESSAGE_ID")] pub message_id : Option < String - >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OdmHeader - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "CLASSIFICATION")] pub classification_list : Vec - < String >, #[serde(rename = "CREATION_DATE")] pub creation_date : - EpochType, #[serde(rename = "ORIGINATOR")] pub originator : - String, #[serde(rename = "MESSAGE_ID")] pub message_id : Option < - String >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AccType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < AccUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngleType - { - #[serde(rename = "$text")] pub base : AngleRange, - #[serde(rename = "@units")] pub units : Option < AngleUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngleRateType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngMomentumType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : AngMomentumUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngVelComponentType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngVelStateType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "REF_FRAME_A")] pub ref_frame_a : String, - #[serde(rename = "REF_FRAME_B")] pub ref_frame_b : String, - #[serde(rename = "ANGVEL_FRAME")] pub angvel_frame : - AngVelFrameType, #[serde(rename = "ANGVEL_X")] pub angvel_x : - AngVelComponentType, #[serde(rename = "ANGVEL_Y")] pub angvel_y : - AngVelComponentType, #[serde(rename = "ANGVEL_Z")] pub angvel_z : - AngVelComponentType, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AngVelType - { - #[serde(rename = "ANGVEL_X")] pub angvel_x : AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] pub angvel_y : AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] pub angvel_z : AngVelComponentType, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AreaType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < AreaUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DayIntervalType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : DayIntervalUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmDayIntervalType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < DayIntervalUnits - >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DeltamassType - { - #[serde(rename = "$text")] pub base : NegativeDouble, - #[serde(rename = "@units")] pub units : Option < MassUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DeltamassTypeZ - { - #[serde(rename = "$text")] pub base : NonPositiveDouble, - #[serde(rename = "@units")] pub units : Option < MassUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct FrequencyType - { - #[serde(rename = "$text")] pub base : PositiveDouble, - #[serde(rename = "@units")] pub units : Option < FrequencyUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct GmType - { - #[serde(rename = "$text")] pub base : PositiveDouble, - #[serde(rename = "@units")] pub units : Option < GmUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct InclinationType - { - #[serde(rename = "$text")] pub base : InclinationRange, - #[serde(rename = "@units")] pub units : Option < AngleUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct LengthType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : LengthUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmLengthType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < LengthUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct MassType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < MassUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct MomentType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < MomentUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct WkgType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : WkgUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OdParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "TIME_LASTOB_START")] pub time_lastob_start : - Option < EpochType >, #[serde(rename = "TIME_LASTOB_END")] pub - time_lastob_end : Option < EpochType >, - #[serde(rename = "RECOMMENDED_OD_SPAN")] pub recommended_od_span : - Option < DayIntervalType >, #[serde(rename = "ACTUAL_OD_SPAN")] - pub actual_od_span : Option < DayIntervalType >, - #[serde(rename = "OBS_AVAILABLE")] pub obs_available : Option < - u64 >, #[serde(rename = "OBS_USED")] pub obs_used : Option < u64 - >, #[serde(rename = "TRACKS_AVAILABLE")] pub tracks_available : - Option < u64 >, #[serde(rename = "TRACKS_USED")] pub tracks_used : - Option < u64 >, #[serde(rename = "RESIDUALS_ACCEPTED")] pub - residuals_accepted : Option < PercentageType >, - #[serde(rename = "WEIGHTED_RMS")] pub weighted_rms : Option < - NonNegativeDouble >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct SpacecraftParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "MASS")] pub mass : Option < MassType >, - #[serde(rename = "SOLAR_RAD_AREA")] pub solar_rad_area : Option < - AreaType >, #[serde(rename = "SOLAR_RAD_COEFF")] pub - solar_rad_coeff : Option < NonNegativeDouble >, - #[serde(rename = "DRAG_AREA")] pub drag_area : Option < AreaType - >, #[serde(rename = "DRAG_COEFF")] pub drag_coeff : Option < - NonNegativeDouble >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct StateVectorType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "EPOCH")] pub epoch : EpochType, - #[serde(rename = "X")] pub x : PositionType, - #[serde(rename = "Y")] pub y : PositionType, - #[serde(rename = "Z")] pub z : PositionType, - #[serde(rename = "X_DOT")] pub x_dot : VelocityType, - #[serde(rename = "Y_DOT")] pub y_dot : VelocityType, - #[serde(rename = "Z_DOT")] pub z_dot : VelocityType, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct StateVectorAccType - { - #[serde(rename = "EPOCH")] pub epoch : EpochType, - #[serde(rename = "X")] pub x : PositionType, - #[serde(rename = "Y")] pub y : PositionType, - #[serde(rename = "Z")] pub z : PositionType, - #[serde(rename = "X_DOT")] pub x_dot : VelocityType, - #[serde(rename = "Y_DOT")] pub y_dot : VelocityType, - #[serde(rename = "Z_DOT")] pub z_dot : VelocityType, - #[serde(rename = "X_DDOT")] pub x_ddot : Option < AccType >, - #[serde(rename = "Y_DDOT")] pub y_ddot : Option < AccType >, - #[serde(rename = "Z_DDOT")] pub z_ddot : Option < AccType >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct Ms2Type - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Ms2Units, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct Km2Type - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < Km2Units >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct Km2sType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < Km2sUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct Km2s2Type - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < Km2s2Units >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DistanceType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < PositionUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct PositionType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < PositionUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RdmPositionType - { #[serde(rename = "$text")] pub base : String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct VelocityType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < VelocityUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RdmVelocityType - { #[serde(rename = "$text")] pub base : String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DurationType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < TimeUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RelTimeType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < TimeUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct TimeOffsetType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < TimeUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct PercentageType - { - #[serde(rename = "$text")] pub base : Range100Type, - #[serde(rename = "@units")] pub units : Option < PercentageUnits - >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct ManeuverFreqType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < NumPerYearUnits - >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct ThrustType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < ThrustUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct GeomagType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < GeomagUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct SolarFluxType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < SolarFluxUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - OpmCovarianceMatrixAbstractType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : Option < - String >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - OemCovarianceMatrixAbstractType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "EPOCH")] pub epoch : EpochType, - #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : Option < - String >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemCovarianceMatrixType - { #[serde(flatten)] pub base : OemCovarianceMatrixAbstractType, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmCovarianceMatrixType - { - #[serde(flatten)] pub base : OpmCovarianceMatrixAbstractType, - #[serde(flatten)] pub extension : CovarianceMatrixElementsGroup, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct PositionCovarianceType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < - PositionCovarianceUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct VelocityCovarianceType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < - VelocityCovarianceUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - PositionVelocityCovarianceType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < - PositionVelocityCovarianceUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AtmosphericReentryParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "ORBIT_LIFETIME")] pub orbit_lifetime : - DayIntervalType, #[serde(rename = "REENTRY_ALTITUDE")] pub - reentry_altitude : PositionType, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] pub - orbit_lifetime_window_start : Option < DayIntervalType >, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] pub - orbit_lifetime_window_end : Option < DayIntervalType >, - #[serde(rename = "NOMINAL_REENTRY_EPOCH")] pub - nominal_reentry_epoch : Option < EpochType >, - #[serde(rename = "REENTRY_WINDOW_START")] pub reentry_window_start - : Option < EpochType >, #[serde(rename = "REENTRY_WINDOW_END")] - pub reentry_window_end : Option < EpochType >, - #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] pub - orbit_lifetime_confidence_level : Option < PercentageType >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct GroundImpactParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "PROBABILITY_OF_IMPACT")] pub - probability_of_impact : Option < ProbabilityType >, - #[serde(rename = "PROBABILITY_OF_BURN_UP")] pub - probability_of_burn_up : Option < ProbabilityType >, - #[serde(rename = "PROBABILITY_OF_BREAK_UP")] pub - probability_of_break_up : Option < ProbabilityType >, - #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] pub - probability_of_land_impact : Option < ProbabilityType >, - #[serde(rename = "PROBABILITY_OF_CASUALTY")] pub - probability_of_casualty : Option < ProbabilityType >, - #[serde(rename = "NOMINAL_IMPACT_EPOCH")] pub nominal_impact_epoch - : Option < EpochType >, #[serde(rename = "IMPACT_WINDOW_START")] - pub impact_window_start : Option < EpochType >, - #[serde(rename = "IMPACT_WINDOW_END")] pub impact_window_end : - Option < EpochType >, #[serde(rename = "IMPACT_REF_FRAME")] pub - impact_ref_frame : Option < String >, - #[serde(rename = "NOMINAL_IMPACT_LON")] pub nominal_impact_lon : - Option < LonType >, #[serde(rename = "NOMINAL_IMPACT_LAT")] pub - nominal_impact_lat : Option < LatType >, - #[serde(rename = "NOMINAL_IMPACT_ALT")] pub nominal_impact_alt : - Option < AltType >, #[serde(rename = "IMPACT_1_CONFIDENCE")] pub - impact_1_confidence : Option < PercentageType >, - #[serde(rename = "IMPACT_1_START_LON")] pub impact_1_start_lon : - Option < LonType >, #[serde(rename = "IMPACT_1_START_LAT")] pub - impact_1_start_lat : Option < LatType >, - #[serde(rename = "IMPACT_1_STOP_LON")] pub impact_1_stop_lon : - Option < LonType >, #[serde(rename = "IMPACT_1_STOP_LAT")] pub - impact_1_stop_lat : Option < LatType >, - #[serde(rename = "IMPACT_1_CROSS_TRACK")] pub impact_1_cross_track - : Option < DistanceType >, - #[serde(rename = "IMPACT_2_CONFIDENCE")] pub impact_2_confidence : - Option < PercentageType >, #[serde(rename = "IMPACT_2_START_LON")] - pub impact_2_start_lon : Option < LonType >, - #[serde(rename = "IMPACT_2_START_LAT")] pub impact_2_start_lat : - Option < LatType >, #[serde(rename = "IMPACT_2_STOP_LON")] pub - impact_2_stop_lon : Option < LonType >, - #[serde(rename = "IMPACT_2_STOP_LAT")] pub impact_2_stop_lat : - Option < LatType >, #[serde(rename = "IMPACT_2_CROSS_TRACK")] pub - impact_2_cross_track : Option < DistanceType >, - #[serde(rename = "IMPACT_3_CONFIDENCE")] pub impact_3_confidence : - Option < PercentageType >, #[serde(rename = "IMPACT_3_START_LON")] - pub impact_3_start_lon : Option < LonType >, - #[serde(rename = "IMPACT_3_START_LAT")] pub impact_3_start_lat : - Option < LatType >, #[serde(rename = "IMPACT_3_STOP_LON")] pub - impact_3_stop_lon : Option < LonType >, - #[serde(rename = "IMPACT_3_STOP_LAT")] pub impact_3_stop_lat : - Option < LatType >, #[serde(rename = "IMPACT_3_CROSS_TRACK")] pub - impact_3_cross_track : Option < DistanceType >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RdmSpacecraftParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "WET_MASS")] pub wet_mass : Option < MassType >, - #[serde(rename = "DRY_MASS")] pub dry_mass : Option < MassType >, - #[serde(rename = "HAZARDOUS_SUBSTANCES")] pub hazardous_substances - : Option < String >, #[serde(rename = "SOLAR_RAD_AREA")] pub - solar_rad_area : Option < AreaType >, - #[serde(rename = "SOLAR_RAD_COEFF")] pub solar_rad_coeff : Option - < NonNegativeDouble >, #[serde(rename = "DRAG_AREA")] pub - drag_area : Option < AreaType >, #[serde(rename = "DRAG_COEFF")] - pub drag_coeff : Option < NonNegativeDouble >, - #[serde(rename = "RCS")] pub rcs : Option < AreaType >, - #[serde(rename = "BALLISTIC_COEFF")] pub ballistic_coeff : Option - < BallisticCoeffType >, #[serde(rename = "THRUST_ACCELERATION")] - pub thrust_acceleration : Option < Ms2Type >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AltType - { - #[serde(rename = "$text")] pub base : AltRange, - #[serde(rename = "@units")] pub units : Option < LengthUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct BallisticCoeffType - { - #[serde(rename = "$text")] pub base : NonNegativeDouble, - #[serde(rename = "@units")] pub units : Option < - BallisticCoeffUnitsType >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct LatType - { - #[serde(rename = "$text")] pub base : LatRange, - #[serde(rename = "@units")] pub units : LatLonUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct LonType - { - #[serde(rename = "$text")] pub base : LonRange, - #[serde(rename = "@units")] pub units : LatLonUnits, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct UserDefinedType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "USER_DEFINED")] pub user_defined_list : Vec < - UserDefinedParameterType >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct UserDefinedParameterType - { - #[serde(rename = "$text")] pub base : String, - #[serde(rename = "@parameter")] pub parameter : String, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct QuaternionType {} - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct QuaternionRateType {} - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct QuaternionDotType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < - QuaternionDotUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RotationAngleType - { - #[serde(rename = "rotation1")] pub rotation1 : - RotationAngleComponentType, #[serde(rename = "rotation2")] pub - rotation2 : RotationAngleComponentType, - #[serde(rename = "rotation3")] pub rotation3 : - RotationAngleComponentType, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RotationAngleComponentTypeold - { - #[serde(rename = "@units")] pub units : Option < AngleUnits >, - #[serde(rename = "@angle")] pub angle : AngleKeywordType, - #[serde(rename = "@value")] pub value : AngleRange, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RotationAngleComponentType - { - #[serde(rename = "$text")] pub base : AngleRange, - #[serde(rename = "@angle")] pub angle : AngleKeywordType, - #[serde(rename = "@units")] pub units : Option < AngleUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RotationRateType - { - #[serde(rename = "rotation1")] pub rotation1 : - RotationRateComponentType, #[serde(rename = "rotation2")] pub - rotation2 : RotationRateComponentType, - #[serde(rename = "rotation3")] pub rotation3 : - RotationRateComponentType, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RotationRateComponentTypeOld - { - #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, - #[serde(rename = "@rate")] pub rate : AngleRateKeywordType, - #[serde(rename = "@value")] pub value : f64, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RotationRateComponentType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@rate")] pub rate : AngleRateKeywordType, - #[serde(rename = "@units")] pub units : Option < AngleRateUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct TorqueType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < TorqueUnits >, - } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - CovarianceMatrixElementsGroup - { - #[serde(rename = "CX_X")] pub cx_x : PositionCovarianceType, - #[serde(rename = "CY_X")] pub cy_x : PositionCovarianceType, - #[serde(rename = "CY_Y")] pub cy_y : PositionCovarianceType, - #[serde(rename = "CZ_X")] pub cz_x : PositionCovarianceType, - #[serde(rename = "CZ_Y")] pub cz_y : PositionCovarianceType, - #[serde(rename = "CZ_Z")] pub cz_z : PositionCovarianceType, - #[serde(rename = "CX_DOT_X")] pub cx_dot_x : - PositionVelocityCovarianceType, #[serde(rename = "CX_DOT_Y")] pub - cx_dot_y : PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Z")] pub cx_dot_z : - PositionVelocityCovarianceType, #[serde(rename = "CX_DOT_X_DOT")] - pub cx_dot_x_dot : VelocityCovarianceType, - #[serde(rename = "CY_DOT_X")] pub cy_dot_x : - PositionVelocityCovarianceType, #[serde(rename = "CY_DOT_Y")] pub - cy_dot_y : PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Z")] pub cy_dot_z : - PositionVelocityCovarianceType, #[serde(rename = "CY_DOT_X_DOT")] - pub cy_dot_x_dot : VelocityCovarianceType, - #[serde(rename = "CY_DOT_Y_DOT")] pub cy_dot_y_dot : - VelocityCovarianceType, #[serde(rename = "CZ_DOT_X")] pub cz_dot_x - : PositionVelocityCovarianceType, #[serde(rename = "CZ_DOT_Y")] - pub cz_dot_y : PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z")] pub cz_dot_z : - PositionVelocityCovarianceType, #[serde(rename = "CZ_DOT_X_DOT")] - pub cz_dot_x_dot : VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y_DOT")] pub cz_dot_y_dot : - VelocityCovarianceType, #[serde(rename = "CZ_DOT_Z_DOT")] pub - cz_dot_z_dot : VelocityCovarianceType, + } + fn serialize_attributes( + &self, + mut source_attributes: Vec, + mut source_namespace: xml::namespace::Namespace, + ) -> Result< + ( + Vec, + xml::namespace::Namespace, + ), + String, + > { + Ok((source_attributes, source_namespace)) + } + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Vec3Double(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Vec6Double(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Vec9Double(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct EpochType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TimeUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TimeSystemType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct NegativeDouble(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct NonNegativeDouble(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct NonPositiveDouble(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PercentType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositiveDouble(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Range100Type(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ProbabilityType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PercentageUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct YesNoType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TrajBasisType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RevNumBasisType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct CovBasisType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ManBasisType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ManDcType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct NumPerYearUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ThrustUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct CovOrderType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct GeomagUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct SolarFluxUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionCovarianceUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LatRange(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AltRange(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LonRange(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LatLonUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ControlledType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DisintegrationType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ImpactUncertaintyType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct QuaternionComponentType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct QuaternionDotUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotDirectionType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotseqType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleKeywordType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleRateKeywordType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ApmRateFrameType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TorqueUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct NdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CLASSIFICATION")] + pub classification_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AccType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngleRateType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngMomentumType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: AngMomentumUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngVelComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngVelStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "REF_FRAME_A")] + pub ref_frame_a: String, + #[serde(rename = "REF_FRAME_B")] + pub ref_frame_b: String, + #[serde(rename = "ANGVEL_FRAME")] + pub angvel_frame: AngVelFrameType, + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AngVelType { + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AreaType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: DayIntervalUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmDayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DeltamassType { + #[serde(rename = "$text")] + pub base: NegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DeltamassTypeZ { + #[serde(rename = "$text")] + pub base: NonPositiveDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct FrequencyType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct GmType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct InclinationType { + #[serde(rename = "$text")] + pub base: InclinationRange, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: LengthUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmLengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct MassType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct MomentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct WkgType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: WkgUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TIME_LASTOB_START")] + pub time_lastob_start: Option, + #[serde(rename = "TIME_LASTOB_END")] + pub time_lastob_end: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "RESIDUALS_ACCEPTED")] + pub residuals_accepted: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct SpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MASS")] + pub mass: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct StateVectorType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct StateVectorAccType { + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, + #[serde(rename = "X_DDOT")] + pub x_ddot: Option, + #[serde(rename = "Y_DDOT")] + pub y_ddot: Option, + #[serde(rename = "Z_DDOT")] + pub z_ddot: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Ms2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Ms2Units, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2sType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct Km2s2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DistanceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RdmPositionType { + #[serde(rename = "$text")] + pub base: String, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct VelocityType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RdmVelocityType { + #[serde(rename = "$text")] + pub base: String, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DurationType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RelTimeType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TimeOffsetType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PercentageType { + #[serde(rename = "$text")] + pub base: Range100Type, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ManeuverFreqType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ThrustType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct GeomagType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct SolarFluxType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmCovarianceMatrixAbstractType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemCovarianceMatrixAbstractType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemCovarianceMatrixType { + #[serde(flatten)] + pub base: OemCovarianceMatrixAbstractType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmCovarianceMatrixType { + #[serde(flatten)] + pub base: OpmCovarianceMatrixAbstractType, + #[serde(flatten)] + pub extension: CovarianceMatrixElementsGroup, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct VelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct PositionVelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AtmosphericReentryParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ORBIT_LIFETIME")] + pub orbit_lifetime: DayIntervalType, + #[serde(rename = "REENTRY_ALTITUDE")] + pub reentry_altitude: PositionType, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] + pub orbit_lifetime_window_start: Option, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] + pub orbit_lifetime_window_end: Option, + #[serde(rename = "NOMINAL_REENTRY_EPOCH")] + pub nominal_reentry_epoch: Option, + #[serde(rename = "REENTRY_WINDOW_START")] + pub reentry_window_start: Option, + #[serde(rename = "REENTRY_WINDOW_END")] + pub reentry_window_end: Option, + #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] + pub orbit_lifetime_confidence_level: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct GroundImpactParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "PROBABILITY_OF_IMPACT")] + pub probability_of_impact: Option, + #[serde(rename = "PROBABILITY_OF_BURN_UP")] + pub probability_of_burn_up: Option, + #[serde(rename = "PROBABILITY_OF_BREAK_UP")] + pub probability_of_break_up: Option, + #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] + pub probability_of_land_impact: Option, + #[serde(rename = "PROBABILITY_OF_CASUALTY")] + pub probability_of_casualty: Option, + #[serde(rename = "NOMINAL_IMPACT_EPOCH")] + pub nominal_impact_epoch: Option, + #[serde(rename = "IMPACT_WINDOW_START")] + pub impact_window_start: Option, + #[serde(rename = "IMPACT_WINDOW_END")] + pub impact_window_end: Option, + #[serde(rename = "IMPACT_REF_FRAME")] + pub impact_ref_frame: Option, + #[serde(rename = "NOMINAL_IMPACT_LON")] + pub nominal_impact_lon: Option, + #[serde(rename = "NOMINAL_IMPACT_LAT")] + pub nominal_impact_lat: Option, + #[serde(rename = "NOMINAL_IMPACT_ALT")] + pub nominal_impact_alt: Option, + #[serde(rename = "IMPACT_1_CONFIDENCE")] + pub impact_1_confidence: Option, + #[serde(rename = "IMPACT_1_START_LON")] + pub impact_1_start_lon: Option, + #[serde(rename = "IMPACT_1_START_LAT")] + pub impact_1_start_lat: Option, + #[serde(rename = "IMPACT_1_STOP_LON")] + pub impact_1_stop_lon: Option, + #[serde(rename = "IMPACT_1_STOP_LAT")] + pub impact_1_stop_lat: Option, + #[serde(rename = "IMPACT_1_CROSS_TRACK")] + pub impact_1_cross_track: Option, + #[serde(rename = "IMPACT_2_CONFIDENCE")] + pub impact_2_confidence: Option, + #[serde(rename = "IMPACT_2_START_LON")] + pub impact_2_start_lon: Option, + #[serde(rename = "IMPACT_2_START_LAT")] + pub impact_2_start_lat: Option, + #[serde(rename = "IMPACT_2_STOP_LON")] + pub impact_2_stop_lon: Option, + #[serde(rename = "IMPACT_2_STOP_LAT")] + pub impact_2_stop_lat: Option, + #[serde(rename = "IMPACT_2_CROSS_TRACK")] + pub impact_2_cross_track: Option, + #[serde(rename = "IMPACT_3_CONFIDENCE")] + pub impact_3_confidence: Option, + #[serde(rename = "IMPACT_3_START_LON")] + pub impact_3_start_lon: Option, + #[serde(rename = "IMPACT_3_START_LAT")] + pub impact_3_start_lat: Option, + #[serde(rename = "IMPACT_3_STOP_LON")] + pub impact_3_stop_lon: Option, + #[serde(rename = "IMPACT_3_STOP_LAT")] + pub impact_3_stop_lat: Option, + #[serde(rename = "IMPACT_3_CROSS_TRACK")] + pub impact_3_cross_track: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RdmSpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "HAZARDOUS_SUBSTANCES")] + pub hazardous_substances: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "BALLISTIC_COEFF")] + pub ballistic_coeff: Option, + #[serde(rename = "THRUST_ACCELERATION")] + pub thrust_acceleration: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AltType { + #[serde(rename = "$text")] + pub base: AltRange, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BallisticCoeffType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LatType { + #[serde(rename = "$text")] + pub base: LatRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct LonType { + #[serde(rename = "$text")] + pub base: LonRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct UserDefinedType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "USER_DEFINED")] + pub user_defined_list: Vec, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct UserDefinedParameterType { + #[serde(rename = "$text")] + pub base: String, + #[serde(rename = "@parameter")] + pub parameter: String, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct QuaternionType {} + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct QuaternionRateType {} + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct QuaternionDotType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationAngleType { + #[serde(rename = "rotation1")] + pub rotation1: RotationAngleComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationAngleComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationAngleComponentType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationAngleComponentTypeold { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@value")] + pub value: AngleRange, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationAngleComponentType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationRateType { + #[serde(rename = "rotation1")] + pub rotation1: RotationRateComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationRateComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationRateComponentType, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationRateComponentTypeOld { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@value")] + pub value: f64, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RotationRateComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TorqueType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, + } + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct CovarianceMatrixElementsGroup { + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, } } -} pub use schema_common :: * ; \ No newline at end of file +} +pub use schema_common::*; diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index 4fc94bf3..11abed2c 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -1,423 +1,539 @@ -mod schema_ocm -{ - pub mod xml_schema_types - { - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmType - { - #[serde(rename = "header")] pub header : schema_common :: - xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body - : schema_common :: xml_schema_types :: OcmBody, - #[serde(rename = "@id")] pub id : String, - #[serde(rename = "@version")] pub version : String, +mod schema_ocm { + pub mod xml_schema_types { + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmType { + #[serde(rename = "header")] + pub header: schema_common::xml_schema_types::OdmHeader, + #[serde(rename = "body")] + pub body: schema_common::xml_schema_types::OcmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmBody - { - #[serde(rename = "segment")] pub segment : schema_common :: - xml_schema_types :: OcmSegment, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmBody { + #[serde(rename = "segment")] + pub segment: schema_common::xml_schema_types::OcmSegment, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmSegment - { - #[serde(rename = "metadata")] pub metadata : schema_common :: - xml_schema_types :: OcmMetadata, #[serde(rename = "data")] pub - data : schema_common :: xml_schema_types :: OcmData, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmSegment { + #[serde(rename = "metadata")] + pub metadata: schema_common::xml_schema_types::OcmMetadata, + #[serde(rename = "data")] + pub data: schema_common::xml_schema_types::OcmData, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmMetadata - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "OBJECT_NAME")] pub object_name : Option < String - >, #[serde(rename = "INTERNATIONAL_DESIGNATOR")] pub - international_designator : Option < String >, - #[serde(rename = "CATALOG_NAME")] pub catalog_name : Option < - String >, #[serde(rename = "OBJECT_DESIGNATOR")] pub - object_designator : Option < String >, - #[serde(rename = "ALTERNATE_NAMES")] pub alternate_names : Option - < String >, #[serde(rename = "ORIGINATOR_POC")] pub originator_poc - : Option < String >, #[serde(rename = "ORIGINATOR_POSITION")] pub - originator_position : Option < String >, - #[serde(rename = "ORIGINATOR_PHONE")] pub originator_phone : - Option < String >, #[serde(rename = "ORIGINATOR_EMAIL")] pub - originator_email : Option < String >, - #[serde(rename = "ORIGINATOR_ADDRESS")] pub originator_address : - Option < String >, #[serde(rename = "TECH_ORG")] pub tech_org : - Option < String >, #[serde(rename = "TECH_POC")] pub tech_poc : - Option < String >, #[serde(rename = "TECH_POSITION")] pub - tech_position : Option < String >, #[serde(rename = "TECH_PHONE")] - pub tech_phone : Option < String >, - #[serde(rename = "TECH_EMAIL")] pub tech_email : Option < String - >, #[serde(rename = "TECH_ADDRESS")] pub tech_address : Option < - String >, #[serde(rename = "PREVIOUS_MESSAGE_ID")] pub - previous_message_id : Option < String >, - #[serde(rename = "NEXT_MESSAGE_ID")] pub next_message_id : Option - < String >, #[serde(rename = "ADM_MSG_LINK")] pub adm_msg_link : - Option < String >, #[serde(rename = "CDM_MSG_LINK")] pub - cdm_msg_link : Option < String >, - #[serde(rename = "PRM_MSG_LINK")] pub prm_msg_link : Option < - String >, #[serde(rename = "RDM_MSG_LINK")] pub rdm_msg_link : - Option < String >, #[serde(rename = "TDM_MSG_LINK")] pub - tdm_msg_link : Option < String >, #[serde(rename = "OPERATOR")] - pub operator : Option < String >, #[serde(rename = "OWNER")] pub - owner : Option < String >, #[serde(rename = "COUNTRY")] pub - country : Option < String >, #[serde(rename = "CONSTELLATION")] - pub constellation : Option < String >, - #[serde(rename = "OBJECT_TYPE")] pub object_type : Option < - schema_common :: xml_schema_types :: ObjectDescriptionType >, - #[serde(rename = "TIME_SYSTEM")] pub time_system : String, - #[serde(rename = "EPOCH_TZERO")] pub epoch_tzero : schema_common - :: xml_schema_types :: EpochType, #[serde(rename = "OPS_STATUS")] - pub ops_status : Option < String >, - #[serde(rename = "ORBIT_CATEGORY")] pub orbit_category : Option < - String >, #[serde(rename = "OCM_DATA_ELEMENTS")] pub - ocm_data_elements : Option < String >, - #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] pub sclk_offset_at_epoch - : Option < schema_common :: xml_schema_types :: TimeOffsetType >, - #[serde(rename = "SCLK_SEC_PER_SI_SEC")] pub sclk_sec_per_si_sec : - Option < schema_common :: xml_schema_types :: DurationType >, - #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] pub - previous_message_epoch : Option < schema_common :: - xml_schema_types :: EpochType >, - #[serde(rename = "NEXT_MESSAGE_EPOCH")] pub next_message_epoch : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "START_TIME")] pub start_time : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "STOP_TIME")] pub stop_time : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "TIME_SPAN")] pub time_span : Option < - schema_common :: xml_schema_types :: OcmDayIntervalType >, - #[serde(rename = "TAIMUTC_AT_TZERO")] pub taimutc_at_tzero : - Option < schema_common :: xml_schema_types :: TimeOffsetType >, - #[serde(rename = "NEXT_LEAP_EPOCH")] pub next_leap_epoch : Option - < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "NEXT_LEAP_TAIMUTC")] pub next_leap_taimutc : - Option < schema_common :: xml_schema_types :: TimeOffsetType >, - #[serde(rename = "UT1MUTC_AT_TZERO")] pub ut1mutc_at_tzero : - Option < schema_common :: xml_schema_types :: TimeOffsetType >, - #[serde(rename = "EOP_SOURCE")] pub eop_source : Option < String - >, #[serde(rename = "INTERP_METHOD_EOP")] pub interp_method_eop : - Option < String >, #[serde(rename = "CELESTIAL_SOURCE")] pub - celestial_source : Option < String >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: Option, + #[serde(rename = "INTERNATIONAL_DESIGNATOR")] + pub international_designator: Option, + #[serde(rename = "CATALOG_NAME")] + pub catalog_name: Option, + #[serde(rename = "OBJECT_DESIGNATOR")] + pub object_designator: Option, + #[serde(rename = "ALTERNATE_NAMES")] + pub alternate_names: Option, + #[serde(rename = "ORIGINATOR_POC")] + pub originator_poc: Option, + #[serde(rename = "ORIGINATOR_POSITION")] + pub originator_position: Option, + #[serde(rename = "ORIGINATOR_PHONE")] + pub originator_phone: Option, + #[serde(rename = "ORIGINATOR_EMAIL")] + pub originator_email: Option, + #[serde(rename = "ORIGINATOR_ADDRESS")] + pub originator_address: Option, + #[serde(rename = "TECH_ORG")] + pub tech_org: Option, + #[serde(rename = "TECH_POC")] + pub tech_poc: Option, + #[serde(rename = "TECH_POSITION")] + pub tech_position: Option, + #[serde(rename = "TECH_PHONE")] + pub tech_phone: Option, + #[serde(rename = "TECH_EMAIL")] + pub tech_email: Option, + #[serde(rename = "TECH_ADDRESS")] + pub tech_address: Option, + #[serde(rename = "PREVIOUS_MESSAGE_ID")] + pub previous_message_id: Option, + #[serde(rename = "NEXT_MESSAGE_ID")] + pub next_message_id: Option, + #[serde(rename = "ADM_MSG_LINK")] + pub adm_msg_link: Option, + #[serde(rename = "CDM_MSG_LINK")] + pub cdm_msg_link: Option, + #[serde(rename = "PRM_MSG_LINK")] + pub prm_msg_link: Option, + #[serde(rename = "RDM_MSG_LINK")] + pub rdm_msg_link: Option, + #[serde(rename = "TDM_MSG_LINK")] + pub tdm_msg_link: Option, + #[serde(rename = "OPERATOR")] + pub operator: Option, + #[serde(rename = "OWNER")] + pub owner: Option, + #[serde(rename = "COUNTRY")] + pub country: Option, + #[serde(rename = "CONSTELLATION")] + pub constellation: Option, + #[serde(rename = "OBJECT_TYPE")] + pub object_type: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "EPOCH_TZERO")] + pub epoch_tzero: schema_common::xml_schema_types::EpochType, + #[serde(rename = "OPS_STATUS")] + pub ops_status: Option, + #[serde(rename = "ORBIT_CATEGORY")] + pub orbit_category: Option, + #[serde(rename = "OCM_DATA_ELEMENTS")] + pub ocm_data_elements: Option, + #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] + pub sclk_offset_at_epoch: Option, + #[serde(rename = "SCLK_SEC_PER_SI_SEC")] + pub sclk_sec_per_si_sec: Option, + #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] + pub previous_message_epoch: Option, + #[serde(rename = "NEXT_MESSAGE_EPOCH")] + pub next_message_epoch: Option, + #[serde(rename = "START_TIME")] + pub start_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: Option, + #[serde(rename = "TIME_SPAN")] + pub time_span: Option, + #[serde(rename = "TAIMUTC_AT_TZERO")] + pub taimutc_at_tzero: Option, + #[serde(rename = "NEXT_LEAP_EPOCH")] + pub next_leap_epoch: Option, + #[serde(rename = "NEXT_LEAP_TAIMUTC")] + pub next_leap_taimutc: Option, + #[serde(rename = "UT1MUTC_AT_TZERO")] + pub ut1mutc_at_tzero: Option, + #[serde(rename = "EOP_SOURCE")] + pub eop_source: Option, + #[serde(rename = "INTERP_METHOD_EOP")] + pub interp_method_eop: Option, + #[serde(rename = "CELESTIAL_SOURCE")] + pub celestial_source: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmData - { - #[serde(rename = "traj")] pub traj_list : Vec < schema_common :: - xml_schema_types :: OcmTrajStateType >, #[serde(rename = "phys")] - pub phys : Option < schema_common :: xml_schema_types :: - OcmPhysicalDescriptionType >, #[serde(rename = "cov")] pub - cov_list : Vec < schema_common :: xml_schema_types :: - OcmCovarianceMatrixType >, #[serde(rename = "man")] pub man_list : - Vec < schema_common :: xml_schema_types :: - OcmManeuverParametersType >, #[serde(rename = "pert")] pub pert : - Option < schema_common :: xml_schema_types :: OcmPerturbationsType - >, #[serde(rename = "od")] pub od : Option < schema_common :: - xml_schema_types :: OcmOdParametersType >, - #[serde(rename = "user")] pub user : Option < schema_common :: - xml_schema_types :: UserDefinedType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmData { + #[serde(rename = "traj")] + pub traj_list: Vec, + #[serde(rename = "phys")] + pub phys: Option, + #[serde(rename = "cov")] + pub cov_list: Vec, + #[serde(rename = "man")] + pub man_list: Vec, + #[serde(rename = "pert")] + pub pert: Option, + #[serde(rename = "od")] + pub od: Option, + #[serde(rename = "user")] + pub user: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmTrajStateType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "TRAJ_ID")] pub traj_id : Option < String >, - #[serde(rename = "TRAJ_PREV_ID")] pub traj_prev_id : Option < - String >, #[serde(rename = "TRAJ_NEXT_ID")] pub traj_next_id : - Option < String >, #[serde(rename = "TRAJ_BASIS")] pub traj_basis - : Option < schema_common :: xml_schema_types :: TrajBasisType >, - #[serde(rename = "TRAJ_BASIS_ID")] pub traj_basis_id : Option < - String >, #[serde(rename = "INTERPOLATION")] pub interpolation : - Option < String >, #[serde(rename = "INTERPOLATION_DEGREE")] pub - interpolation_degree : Option < u64 >, - #[serde(rename = "PROPAGATOR")] pub propagator : Option < String - >, #[serde(rename = "CENTER_NAME")] pub center_name : String, - #[serde(rename = "TRAJ_REF_FRAME")] pub traj_ref_frame : String, - #[serde(rename = "TRAJ_FRAME_EPOCH")] pub traj_frame_epoch : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "USEABLE_START_TIME")] pub useable_start_time : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "USEABLE_STOP_TIME")] pub useable_stop_time : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "ORB_REVNUM")] pub orb_revnum : Option < - schema_common :: xml_schema_types :: NonNegativeDouble >, - #[serde(rename = "ORB_REVNUM_BASIS")] pub orb_revnum_basis : - Option < schema_common :: xml_schema_types :: RevNumBasisType >, - #[serde(rename = "TRAJ_TYPE")] pub traj_type : String, - #[serde(rename = "ORB_AVERAGING")] pub orb_averaging : Option < - String >, #[serde(rename = "TRAJ_UNITS")] pub traj_units : Option - < String >, #[serde(rename = "trajLine")] pub traj_line_list : Vec - < String >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmTrajStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TRAJ_ID")] + pub traj_id: Option, + #[serde(rename = "TRAJ_PREV_ID")] + pub traj_prev_id: Option, + #[serde(rename = "TRAJ_NEXT_ID")] + pub traj_next_id: Option, + #[serde(rename = "TRAJ_BASIS")] + pub traj_basis: Option, + #[serde(rename = "TRAJ_BASIS_ID")] + pub traj_basis_id: Option, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, + #[serde(rename = "PROPAGATOR")] + pub propagator: Option, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "TRAJ_REF_FRAME")] + pub traj_ref_frame: String, + #[serde(rename = "TRAJ_FRAME_EPOCH")] + pub traj_frame_epoch: Option, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "ORB_REVNUM")] + pub orb_revnum: Option, + #[serde(rename = "ORB_REVNUM_BASIS")] + pub orb_revnum_basis: Option, + #[serde(rename = "TRAJ_TYPE")] + pub traj_type: String, + #[serde(rename = "ORB_AVERAGING")] + pub orb_averaging: Option, + #[serde(rename = "TRAJ_UNITS")] + pub traj_units: Option, + #[serde(rename = "trajLine")] + pub traj_line_list: Vec, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmPhysicalDescriptionType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "MANUFACTURER")] pub manufacturer : Option < - String >, #[serde(rename = "BUS_MODEL")] pub bus_model : Option < - String >, #[serde(rename = "DOCKED_WITH")] pub docked_with : - Option < String >, #[serde(rename = "DRAG_CONST_AREA")] pub - drag_const_area : Option < schema_common :: xml_schema_types :: - AreaType >, #[serde(rename = "DRAG_COEFF_NOM")] pub drag_coeff_nom - : Option < schema_common :: xml_schema_types :: PositiveDouble >, - #[serde(rename = "DRAG_UNCERTAINTY")] pub drag_uncertainty : - Option < schema_common :: xml_schema_types :: PercentageType >, - #[serde(rename = "INITIAL_WET_MASS")] pub initial_wet_mass : - Option < schema_common :: xml_schema_types :: MassType >, - #[serde(rename = "WET_MASS")] pub wet_mass : Option < - schema_common :: xml_schema_types :: MassType >, - #[serde(rename = "DRY_MASS")] pub dry_mass : Option < - schema_common :: xml_schema_types :: MassType >, - #[serde(rename = "OEB_PARENT_FRAME")] pub oeb_parent_frame : - Option < String >, #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] pub - oeb_parent_frame_epoch : Option < schema_common :: - xml_schema_types :: EpochType >, #[serde(rename = "OEB_Q1")] pub - oeb_q1 : Option < f64 >, #[serde(rename = "OEB_Q2")] pub oeb_q2 : - Option < f64 >, #[serde(rename = "OEB_Q3")] pub oeb_q3 : Option < - f64 >, #[serde(rename = "OEB_QC")] pub oeb_qc : Option < f64 >, - #[serde(rename = "OEB_MAX")] pub oeb_max : Option < schema_common - :: xml_schema_types :: OcmLengthType >, - #[serde(rename = "OEB_INT")] pub oeb_int : Option < schema_common - :: xml_schema_types :: OcmLengthType >, - #[serde(rename = "OEB_MIN")] pub oeb_min : Option < schema_common - :: xml_schema_types :: OcmLengthType >, - #[serde(rename = "AREA_ALONG_OEB_MAX")] pub area_along_oeb_max : - Option < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "AREA_ALONG_OEB_INT")] pub area_along_oeb_int : - Option < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "AREA_ALONG_OEB_MIN")] pub area_along_oeb_min : - Option < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "AREA_MIN_FOR_PC")] pub area_min_for_pc : Option - < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "AREA_MAX_FOR_PC")] pub area_max_for_pc : Option - < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "AREA_TYP_FOR_PC")] pub area_typ_for_pc : Option - < schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "RCS")] pub rcs : Option < schema_common :: - xml_schema_types :: AreaType >, #[serde(rename = "RCS_MIN")] pub - rcs_min : Option < schema_common :: xml_schema_types :: AreaType - >, #[serde(rename = "RCS_MAX")] pub rcs_max : Option < - schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "SRP_CONST_AREA")] pub srp_const_area : Option < - schema_common :: xml_schema_types :: AreaType >, - #[serde(rename = "SOLAR_RAD_COEFF")] pub solar_rad_coeff : Option - < f64 >, #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] pub - solar_rad_uncertainty : Option < schema_common :: xml_schema_types - :: PercentageType >, #[serde(rename = "VM_ABSOLUTE")] pub - vm_absolute : Option < f64 >, #[serde(rename = "VM_APPARENT_MIN")] - pub vm_apparent_min : Option < f64 >, - #[serde(rename = "VM_APPARENT")] pub vm_apparent : Option < f64 >, - #[serde(rename = "VM_APPARENT_MAX")] pub vm_apparent_max : Option - < f64 >, #[serde(rename = "REFLECTANCE")] pub reflectance : Option - < schema_common :: xml_schema_types :: ProbabilityType >, - #[serde(rename = "ATT_CONTROL_MODE")] pub att_control_mode : - Option < String >, #[serde(rename = "ATT_ACTUATOR_TYPE")] pub - att_actuator_type : Option < String >, - #[serde(rename = "ATT_KNOWLEDGE")] pub att_knowledge : Option < - schema_common :: xml_schema_types :: AngleType >, - #[serde(rename = "ATT_CONTROL")] pub att_control : Option < - schema_common :: xml_schema_types :: AngleType >, - #[serde(rename = "ATT_POINTING")] pub att_pointing : Option < - schema_common :: xml_schema_types :: AngleType >, - #[serde(rename = "AVG_MANEUVER_FREQ")] pub avg_maneuver_freq : - Option < schema_common :: xml_schema_types :: ManeuverFreqType >, - #[serde(rename = "MAX_THRUST")] pub max_thrust : Option < - schema_common :: xml_schema_types :: ThrustType >, - #[serde(rename = "DV_BOL")] pub dv_bol : Option < schema_common :: - xml_schema_types :: VelocityType >, - #[serde(rename = "DV_REMAINING")] pub dv_remaining : Option < - schema_common :: xml_schema_types :: VelocityType >, - #[serde(rename = "IXX")] pub ixx : Option < schema_common :: - xml_schema_types :: MomentType >, #[serde(rename = "IYY")] pub iyy - : Option < schema_common :: xml_schema_types :: MomentType >, - #[serde(rename = "IZZ")] pub izz : Option < schema_common :: - xml_schema_types :: MomentType >, #[serde(rename = "IXY")] pub ixy - : Option < schema_common :: xml_schema_types :: MomentType >, - #[serde(rename = "IXZ")] pub ixz : Option < schema_common :: - xml_schema_types :: MomentType >, #[serde(rename = "IYZ")] pub iyz - : Option < schema_common :: xml_schema_types :: MomentType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmPhysicalDescriptionType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MANUFACTURER")] + pub manufacturer: Option, + #[serde(rename = "BUS_MODEL")] + pub bus_model: Option, + #[serde(rename = "DOCKED_WITH")] + pub docked_with: Option, + #[serde(rename = "DRAG_CONST_AREA")] + pub drag_const_area: Option, + #[serde(rename = "DRAG_COEFF_NOM")] + pub drag_coeff_nom: Option, + #[serde(rename = "DRAG_UNCERTAINTY")] + pub drag_uncertainty: Option, + #[serde(rename = "INITIAL_WET_MASS")] + pub initial_wet_mass: Option, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "OEB_PARENT_FRAME")] + pub oeb_parent_frame: Option, + #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] + pub oeb_parent_frame_epoch: Option, + #[serde(rename = "OEB_Q1")] + pub oeb_q1: Option, + #[serde(rename = "OEB_Q2")] + pub oeb_q2: Option, + #[serde(rename = "OEB_Q3")] + pub oeb_q3: Option, + #[serde(rename = "OEB_QC")] + pub oeb_qc: Option, + #[serde(rename = "OEB_MAX")] + pub oeb_max: Option, + #[serde(rename = "OEB_INT")] + pub oeb_int: Option, + #[serde(rename = "OEB_MIN")] + pub oeb_min: Option, + #[serde(rename = "AREA_ALONG_OEB_MAX")] + pub area_along_oeb_max: Option, + #[serde(rename = "AREA_ALONG_OEB_INT")] + pub area_along_oeb_int: Option, + #[serde(rename = "AREA_ALONG_OEB_MIN")] + pub area_along_oeb_min: Option, + #[serde(rename = "AREA_MIN_FOR_PC")] + pub area_min_for_pc: Option, + #[serde(rename = "AREA_MAX_FOR_PC")] + pub area_max_for_pc: Option, + #[serde(rename = "AREA_TYP_FOR_PC")] + pub area_typ_for_pc: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "RCS_MIN")] + pub rcs_min: Option, + #[serde(rename = "RCS_MAX")] + pub rcs_max: Option, + #[serde(rename = "SRP_CONST_AREA")] + pub srp_const_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] + pub solar_rad_uncertainty: Option, + #[serde(rename = "VM_ABSOLUTE")] + pub vm_absolute: Option, + #[serde(rename = "VM_APPARENT_MIN")] + pub vm_apparent_min: Option, + #[serde(rename = "VM_APPARENT")] + pub vm_apparent: Option, + #[serde(rename = "VM_APPARENT_MAX")] + pub vm_apparent_max: Option, + #[serde(rename = "REFLECTANCE")] + pub reflectance: Option, + #[serde(rename = "ATT_CONTROL_MODE")] + pub att_control_mode: Option, + #[serde(rename = "ATT_ACTUATOR_TYPE")] + pub att_actuator_type: Option, + #[serde(rename = "ATT_KNOWLEDGE")] + pub att_knowledge: Option, + #[serde(rename = "ATT_CONTROL")] + pub att_control: Option, + #[serde(rename = "ATT_POINTING")] + pub att_pointing: Option, + #[serde(rename = "AVG_MANEUVER_FREQ")] + pub avg_maneuver_freq: Option, + #[serde(rename = "MAX_THRUST")] + pub max_thrust: Option, + #[serde(rename = "DV_BOL")] + pub dv_bol: Option, + #[serde(rename = "DV_REMAINING")] + pub dv_remaining: Option, + #[serde(rename = "IXX")] + pub ixx: Option, + #[serde(rename = "IYY")] + pub iyy: Option, + #[serde(rename = "IZZ")] + pub izz: Option, + #[serde(rename = "IXY")] + pub ixy: Option, + #[serde(rename = "IXZ")] + pub ixz: Option, + #[serde(rename = "IYZ")] + pub iyz: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmCovarianceMatrixType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "COV_ID")] pub cov_id : Option < String >, - #[serde(rename = "COV_PREV_ID")] pub cov_prev_id : Option < String - >, #[serde(rename = "COV_NEXT_ID")] pub cov_next_id : Option < - String >, #[serde(rename = "COV_BASIS")] pub cov_basis : Option < - schema_common :: xml_schema_types :: CovBasisType >, - #[serde(rename = "COV_BASIS_ID")] pub cov_basis_id : Option < - String >, #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame : - String, #[serde(rename = "COV_FRAME_EPOCH")] pub cov_frame_epoch : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "COV_SCALE_MIN")] pub cov_scale_min : Option < - f64 >, #[serde(rename = "COV_SCALE_MAX")] pub cov_scale_max : - Option < f64 >, #[serde(rename = "COV_CONFIDENCE")] pub - cov_confidence : Option < schema_common :: xml_schema_types :: - PercentageType >, #[serde(rename = "COV_TYPE")] pub cov_type : - String, #[serde(rename = "COV_ORDERING")] pub cov_ordering : - schema_common :: xml_schema_types :: CovOrderType, - #[serde(rename = "COV_UNITS")] pub cov_units : Option < String >, - #[serde(rename = "covLine")] pub cov_line_list : Vec < String >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmCovarianceMatrixType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_ID")] + pub cov_id: Option, + #[serde(rename = "COV_PREV_ID")] + pub cov_prev_id: Option, + #[serde(rename = "COV_NEXT_ID")] + pub cov_next_id: Option, + #[serde(rename = "COV_BASIS")] + pub cov_basis: Option, + #[serde(rename = "COV_BASIS_ID")] + pub cov_basis_id: Option, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: String, + #[serde(rename = "COV_FRAME_EPOCH")] + pub cov_frame_epoch: Option, + #[serde(rename = "COV_SCALE_MIN")] + pub cov_scale_min: Option, + #[serde(rename = "COV_SCALE_MAX")] + pub cov_scale_max: Option, + #[serde(rename = "COV_CONFIDENCE")] + pub cov_confidence: Option, + #[serde(rename = "COV_TYPE")] + pub cov_type: String, + #[serde(rename = "COV_ORDERING")] + pub cov_ordering: schema_common::xml_schema_types::CovOrderType, + #[serde(rename = "COV_UNITS")] + pub cov_units: Option, + #[serde(rename = "covLine")] + pub cov_line_list: Vec, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmManeuverParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "MAN_ID")] pub man_id : String, - #[serde(rename = "MAN_PREV_ID")] pub man_prev_id : Option < String - >, #[serde(rename = "MAN_NEXT_ID")] pub man_next_id : Option < - String >, #[serde(rename = "MAN_BASIS")] pub man_basis : Option < - schema_common :: xml_schema_types :: ManBasisType >, - #[serde(rename = "MAN_BASIS_ID")] pub man_basis_id : Option < - String >, #[serde(rename = "MAN_DEVICE_ID")] pub man_device_id : - String, #[serde(rename = "MAN_PREV_EPOCH")] pub man_prev_epoch : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "MAN_NEXT_EPOCH")] pub man_next_epoch : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "MAN_PURPOSE")] pub man_purpose : Option < String - >, #[serde(rename = "MAN_PRED_SOURCE")] pub man_pred_source : - Option < String >, #[serde(rename = "MAN_REF_FRAME")] pub - man_ref_frame : String, #[serde(rename = "MAN_FRAME_EPOCH")] pub - man_frame_epoch : Option < schema_common :: xml_schema_types :: - EpochType >, #[serde(rename = "GRAV_ASSIST_NAME")] pub - grav_assist_name : Option < String >, #[serde(rename = "DC_TYPE")] - pub dc_type : schema_common :: xml_schema_types :: ManDcType, - #[serde(rename = "DC_WIN_OPEN")] pub dc_win_open : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "DC_WIN_CLOSE")] pub dc_win_close : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "DC_MIN_CYCLES")] pub dc_min_cycles : Option < - u64 >, #[serde(rename = "DC_MAX_CYCLES")] pub dc_max_cycles : - Option < u64 >, #[serde(rename = "DC_EXEC_START")] pub - dc_exec_start : Option < schema_common :: xml_schema_types :: - EpochType >, #[serde(rename = "DC_EXEC_STOP")] pub dc_exec_stop : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "DC_REF_TIME")] pub dc_ref_time : Option < - schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "DC_TIME_PULSE_DURATION")] pub - dc_time_pulse_duration : Option < schema_common :: - xml_schema_types :: DurationType >, - #[serde(rename = "DC_TIME_PULSE_PERIOD")] pub dc_time_pulse_period - : Option < schema_common :: xml_schema_types :: DurationType >, - #[serde(rename = "DC_REF_DIR")] pub dc_ref_dir : Option < - schema_common :: xml_schema_types :: Vec3Double >, - #[serde(rename = "DC_BODY_FRAME")] pub dc_body_frame : Option < - String >, #[serde(rename = "DC_BODY_TRIGGER")] pub dc_body_trigger - : Option < schema_common :: xml_schema_types :: Vec3Double >, - #[serde(rename = "DC_PA_START_ANGLE")] pub dc_pa_start_angle : - Option < schema_common :: xml_schema_types :: AngleType >, - #[serde(rename = "DC_PA_STOP_ANGLE")] pub dc_pa_stop_angle : - Option < schema_common :: xml_schema_types :: AngleType >, - #[serde(rename = "MAN_COMPOSITION")] pub man_composition : String, - #[serde(rename = "MAN_UNITS")] pub man_units : Option < String >, - #[serde(rename = "manLine")] pub man_line_list : Vec < String >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_ID")] + pub man_id: String, + #[serde(rename = "MAN_PREV_ID")] + pub man_prev_id: Option, + #[serde(rename = "MAN_NEXT_ID")] + pub man_next_id: Option, + #[serde(rename = "MAN_BASIS")] + pub man_basis: Option, + #[serde(rename = "MAN_BASIS_ID")] + pub man_basis_id: Option, + #[serde(rename = "MAN_DEVICE_ID")] + pub man_device_id: String, + #[serde(rename = "MAN_PREV_EPOCH")] + pub man_prev_epoch: Option, + #[serde(rename = "MAN_NEXT_EPOCH")] + pub man_next_epoch: Option, + #[serde(rename = "MAN_PURPOSE")] + pub man_purpose: Option, + #[serde(rename = "MAN_PRED_SOURCE")] + pub man_pred_source: Option, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_FRAME_EPOCH")] + pub man_frame_epoch: Option, + #[serde(rename = "GRAV_ASSIST_NAME")] + pub grav_assist_name: Option, + #[serde(rename = "DC_TYPE")] + pub dc_type: schema_common::xml_schema_types::ManDcType, + #[serde(rename = "DC_WIN_OPEN")] + pub dc_win_open: Option, + #[serde(rename = "DC_WIN_CLOSE")] + pub dc_win_close: Option, + #[serde(rename = "DC_MIN_CYCLES")] + pub dc_min_cycles: Option, + #[serde(rename = "DC_MAX_CYCLES")] + pub dc_max_cycles: Option, + #[serde(rename = "DC_EXEC_START")] + pub dc_exec_start: Option, + #[serde(rename = "DC_EXEC_STOP")] + pub dc_exec_stop: Option, + #[serde(rename = "DC_REF_TIME")] + pub dc_ref_time: Option, + #[serde(rename = "DC_TIME_PULSE_DURATION")] + pub dc_time_pulse_duration: Option, + #[serde(rename = "DC_TIME_PULSE_PERIOD")] + pub dc_time_pulse_period: Option, + #[serde(rename = "DC_REF_DIR")] + pub dc_ref_dir: Option, + #[serde(rename = "DC_BODY_FRAME")] + pub dc_body_frame: Option, + #[serde(rename = "DC_BODY_TRIGGER")] + pub dc_body_trigger: Option, + #[serde(rename = "DC_PA_START_ANGLE")] + pub dc_pa_start_angle: Option, + #[serde(rename = "DC_PA_STOP_ANGLE")] + pub dc_pa_stop_angle: Option, + #[serde(rename = "MAN_COMPOSITION")] + pub man_composition: String, + #[serde(rename = "MAN_UNITS")] + pub man_units: Option, + #[serde(rename = "manLine")] + pub man_line_list: Vec, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmPerturbationsType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "ATMOSPHERIC_MODEL")] pub atmospheric_model : - Option < String >, #[serde(rename = "GRAVITY_MODEL")] pub - gravity_model : Option < String >, - #[serde(rename = "EQUATORIAL_RADIUS")] pub equatorial_radius : - Option < schema_common :: xml_schema_types :: PositionType >, - #[serde(rename = "GM")] pub gm : Option < schema_common :: - xml_schema_types :: GmType >, - #[serde(rename = "N_BODY_PERTURBATIONS")] pub n_body_perturbations - : Option < String >, #[serde(rename = "CENTRAL_BODY_ROTATION")] - pub central_body_rotation : Option < schema_common :: - xml_schema_types :: AngleRateType >, - #[serde(rename = "OBLATE_FLATTENING")] pub oblate_flattening : - Option < schema_common :: xml_schema_types :: PositiveDouble >, - #[serde(rename = "OCEAN_TIDES_MODEL")] pub ocean_tides_model : - Option < String >, #[serde(rename = "SOLID_TIDES_MODEL")] pub - solid_tides_model : Option < String >, - #[serde(rename = "REDUCTION_THEORY")] pub reduction_theory : - Option < String >, #[serde(rename = "ALBEDO_MODEL")] pub - albedo_model : Option < String >, - #[serde(rename = "ALBEDO_GRID_SIZE")] pub albedo_grid_size : - Option < u64 >, #[serde(rename = "SHADOW_MODEL")] pub shadow_model - : Option < String >, #[serde(rename = "SHADOW_BODIES")] pub - shadow_bodies : Option < String >, #[serde(rename = "SRP_MODEL")] - pub srp_model : Option < String >, - #[serde(rename = "SW_DATA_SOURCE")] pub sw_data_source : Option < - String >, #[serde(rename = "SW_DATA_EPOCH")] pub sw_data_epoch : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "SW_INTERP_METHOD")] pub sw_interp_method : - Option < String >, #[serde(rename = "FIXED_GEOMAG_KP")] pub - fixed_geomag_kp : Option < schema_common :: xml_schema_types :: - GeomagType >, #[serde(rename = "FIXED_GEOMAG_AP")] pub - fixed_geomag_ap : Option < schema_common :: xml_schema_types :: - GeomagType >, #[serde(rename = "FIXED_GEOMAG_DST")] pub - fixed_geomag_dst : Option < schema_common :: xml_schema_types :: - GeomagType >, #[serde(rename = "FIXED_F10P7")] pub fixed_f10p7 : - Option < schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_F10P7_MEAN")] pub fixed_f10p7_mean : - Option < schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_M10P7")] pub fixed_m10p7 : Option < - schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_M10P7_MEAN")] pub fixed_m10p7_mean : - Option < schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_S10P7")] pub fixed_s10p7 : Option < - schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_S10P7_MEAN")] pub fixed_s10p7_mean : - Option < schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_Y10P7")] pub fixed_y10p7 : Option < - schema_common :: xml_schema_types :: SolarFluxType >, - #[serde(rename = "FIXED_Y10P7_MEAN")] pub fixed_y10p7_mean : - Option < schema_common :: xml_schema_types :: SolarFluxType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmPerturbationsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ATMOSPHERIC_MODEL")] + pub atmospheric_model: Option, + #[serde(rename = "GRAVITY_MODEL")] + pub gravity_model: Option, + #[serde(rename = "EQUATORIAL_RADIUS")] + pub equatorial_radius: Option, + #[serde(rename = "GM")] + pub gm: Option, + #[serde(rename = "N_BODY_PERTURBATIONS")] + pub n_body_perturbations: Option, + #[serde(rename = "CENTRAL_BODY_ROTATION")] + pub central_body_rotation: Option, + #[serde(rename = "OBLATE_FLATTENING")] + pub oblate_flattening: Option, + #[serde(rename = "OCEAN_TIDES_MODEL")] + pub ocean_tides_model: Option, + #[serde(rename = "SOLID_TIDES_MODEL")] + pub solid_tides_model: Option, + #[serde(rename = "REDUCTION_THEORY")] + pub reduction_theory: Option, + #[serde(rename = "ALBEDO_MODEL")] + pub albedo_model: Option, + #[serde(rename = "ALBEDO_GRID_SIZE")] + pub albedo_grid_size: Option, + #[serde(rename = "SHADOW_MODEL")] + pub shadow_model: Option, + #[serde(rename = "SHADOW_BODIES")] + pub shadow_bodies: Option, + #[serde(rename = "SRP_MODEL")] + pub srp_model: Option, + #[serde(rename = "SW_DATA_SOURCE")] + pub sw_data_source: Option, + #[serde(rename = "SW_DATA_EPOCH")] + pub sw_data_epoch: Option, + #[serde(rename = "SW_INTERP_METHOD")] + pub sw_interp_method: Option, + #[serde(rename = "FIXED_GEOMAG_KP")] + pub fixed_geomag_kp: Option, + #[serde(rename = "FIXED_GEOMAG_AP")] + pub fixed_geomag_ap: Option, + #[serde(rename = "FIXED_GEOMAG_DST")] + pub fixed_geomag_dst: Option, + #[serde(rename = "FIXED_F10P7")] + pub fixed_f10p7: Option, + #[serde(rename = "FIXED_F10P7_MEAN")] + pub fixed_f10p7_mean: Option, + #[serde(rename = "FIXED_M10P7")] + pub fixed_m10p7: Option, + #[serde(rename = "FIXED_M10P7_MEAN")] + pub fixed_m10p7_mean: Option, + #[serde(rename = "FIXED_S10P7")] + pub fixed_s10p7: Option, + #[serde(rename = "FIXED_S10P7_MEAN")] + pub fixed_s10p7_mean: Option, + #[serde(rename = "FIXED_Y10P7")] + pub fixed_y10p7: Option, + #[serde(rename = "FIXED_Y10P7_MEAN")] + pub fixed_y10p7_mean: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OcmOdParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "OD_ID")] pub od_id : String, - #[serde(rename = "OD_PREV_ID")] pub od_prev_id : Option < String - >, #[serde(rename = "OD_METHOD")] pub od_method : String, - #[serde(rename = "OD_EPOCH")] pub od_epoch : schema_common :: - xml_schema_types :: EpochType, - #[serde(rename = "DAYS_SINCE_FIRST_OBS")] pub days_since_first_obs - : Option < schema_common :: xml_schema_types :: OcmDayIntervalType - >, #[serde(rename = "DAYS_SINCE_LAST_OBS")] pub - days_since_last_obs : Option < schema_common :: xml_schema_types - :: OcmDayIntervalType >, #[serde(rename = "RECOMMENDED_OD_SPAN")] - pub recommended_od_span : Option < schema_common :: - xml_schema_types :: OcmDayIntervalType >, - #[serde(rename = "ACTUAL_OD_SPAN")] pub actual_od_span : Option < - schema_common :: xml_schema_types :: OcmDayIntervalType >, - #[serde(rename = "OBS_AVAILABLE")] pub obs_available : Option < - u64 >, #[serde(rename = "OBS_USED")] pub obs_used : Option < u64 - >, #[serde(rename = "TRACKS_AVAILABLE")] pub tracks_available : - Option < u64 >, #[serde(rename = "TRACKS_USED")] pub tracks_used : - Option < u64 >, #[serde(rename = "MAXIMUM_OBS_GAP")] pub - maximum_obs_gap : Option < schema_common :: xml_schema_types :: - OcmDayIntervalType >, #[serde(rename = "OD_EPOCH_EIGMAJ")] pub - od_epoch_eigmaj : Option < schema_common :: xml_schema_types :: - OcmLengthType >, #[serde(rename = "OD_EPOCH_EIGINT")] pub - od_epoch_eigint : Option < schema_common :: xml_schema_types :: - OcmLengthType >, #[serde(rename = "OD_EPOCH_EIGMIN")] pub - od_epoch_eigmin : Option < schema_common :: xml_schema_types :: - OcmLengthType >, #[serde(rename = "OD_MAX_PRED_EIGMAJ")] pub - od_max_pred_eigmaj : Option < schema_common :: xml_schema_types :: - OcmLengthType >, #[serde(rename = "OD_MIN_PRED_EIGMIN")] pub - od_min_pred_eigmin : Option < schema_common :: xml_schema_types :: - OcmLengthType >, #[serde(rename = "OD_CONFIDENCE")] pub - od_confidence : Option < schema_common :: xml_schema_types :: - PercentageType >, #[serde(rename = "GDOP")] pub gdop : Option < - schema_common :: xml_schema_types :: NonNegativeDouble >, - #[serde(rename = "SOLVE_N")] pub solve_n : Option < u64 >, - #[serde(rename = "SOLVE_STATES")] pub solve_states : Option < - String >, #[serde(rename = "CONSIDER_N")] pub consider_n : Option - < u64 >, #[serde(rename = "CONSIDER_PARAMS")] pub consider_params - : Option < String >, #[serde(rename = "SEDR")] pub sedr : Option < - schema_common :: xml_schema_types :: WkgType >, - #[serde(rename = "SENSORS_N")] pub sensors_n : Option < u64 >, - #[serde(rename = "SENSORS")] pub sensors : Option < String >, - #[serde(rename = "WEIGHTED_RMS")] pub weighted_rms : Option < - schema_common :: xml_schema_types :: NonNegativeDouble >, - #[serde(rename = "DATA_TYPES")] pub data_types : Option < String - >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OcmOdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OD_ID")] + pub od_id: String, + #[serde(rename = "OD_PREV_ID")] + pub od_prev_id: Option, + #[serde(rename = "OD_METHOD")] + pub od_method: String, + #[serde(rename = "OD_EPOCH")] + pub od_epoch: schema_common::xml_schema_types::EpochType, + #[serde(rename = "DAYS_SINCE_FIRST_OBS")] + pub days_since_first_obs: Option, + #[serde(rename = "DAYS_SINCE_LAST_OBS")] + pub days_since_last_obs: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "MAXIMUM_OBS_GAP")] + pub maximum_obs_gap: Option, + #[serde(rename = "OD_EPOCH_EIGMAJ")] + pub od_epoch_eigmaj: Option, + #[serde(rename = "OD_EPOCH_EIGINT")] + pub od_epoch_eigint: Option, + #[serde(rename = "OD_EPOCH_EIGMIN")] + pub od_epoch_eigmin: Option, + #[serde(rename = "OD_MAX_PRED_EIGMAJ")] + pub od_max_pred_eigmaj: Option, + #[serde(rename = "OD_MIN_PRED_EIGMIN")] + pub od_min_pred_eigmin: Option, + #[serde(rename = "OD_CONFIDENCE")] + pub od_confidence: Option, + #[serde(rename = "GDOP")] + pub gdop: Option, + #[serde(rename = "SOLVE_N")] + pub solve_n: Option, + #[serde(rename = "SOLVE_STATES")] + pub solve_states: Option, + #[serde(rename = "CONSIDER_N")] + pub consider_n: Option, + #[serde(rename = "CONSIDER_PARAMS")] + pub consider_params: Option, + #[serde(rename = "SEDR")] + pub sedr: Option, + #[serde(rename = "SENSORS_N")] + pub sensors_n: Option, + #[serde(rename = "SENSORS")] + pub sensors: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, + #[serde(rename = "DATA_TYPES")] + pub data_types: Option, } } -} pub use schema_ocm :: * ; \ No newline at end of file +} +pub use schema_ocm::*; diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index 501472ce..2b65982f 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -1,61 +1,76 @@ -mod schema_oem -{ - pub mod xml_schema_types - { - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemType - { - #[serde(rename = "header")] pub header : schema_common :: - xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body - : schema_common :: xml_schema_types :: OemBody, - #[serde(rename = "@id")] pub id : String, - #[serde(rename = "@version")] pub version : String, +mod schema_oem { + pub mod xml_schema_types { + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemType { + #[serde(rename = "header")] + pub header: schema_common::xml_schema_types::OdmHeader, + #[serde(rename = "body")] + pub body: schema_common::xml_schema_types::OemBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemBody - { - #[serde(rename = "segment")] pub segment_list : Vec < - schema_common :: xml_schema_types :: OemSegment >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemBody { + #[serde(rename = "segment")] + pub segment_list: Vec, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemSegment - { - #[serde(rename = "metadata")] pub metadata : schema_common :: - xml_schema_types :: OemMetadata, #[serde(rename = "data")] pub - data : schema_common :: xml_schema_types :: OemData, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemSegment { + #[serde(rename = "metadata")] + pub metadata: schema_common::xml_schema_types::OemMetadata, + #[serde(rename = "data")] + pub data: schema_common::xml_schema_types::OemData, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemMetadata - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "OBJECT_NAME")] pub object_name : String, - #[serde(rename = "OBJECT_ID")] pub object_id : String, - #[serde(rename = "CENTER_NAME")] pub center_name : String, - #[serde(rename = "REF_FRAME")] pub ref_frame : String, - #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option - < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "TIME_SYSTEM")] pub time_system : String, - #[serde(rename = "START_TIME")] pub start_time : schema_common :: - xml_schema_types :: EpochType, - #[serde(rename = "USEABLE_START_TIME")] pub useable_start_time : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "USEABLE_STOP_TIME")] pub useable_stop_time : - Option < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "STOP_TIME")] pub stop_time : schema_common :: - xml_schema_types :: EpochType, #[serde(rename = "INTERPOLATION")] - pub interpolation : Option < String >, - #[serde(rename = "INTERPOLATION_DEGREE")] pub interpolation_degree - : Option < u64 >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "START_TIME")] + pub start_time: schema_common::xml_schema_types::EpochType, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: schema_common::xml_schema_types::EpochType, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OemData - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "stateVector")] pub state_vector_list : Vec < - schema_common :: xml_schema_types :: StateVectorAccType >, - #[serde(rename = "covarianceMatrix")] pub covariance_matrix_list : - Vec < schema_common :: xml_schema_types :: OemCovarianceMatrixType - >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OemData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector_list: Vec, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix_list: + Vec, } } -} pub use schema_oem :: * ; \ No newline at end of file +} +pub use schema_oem::*; diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 859bf178..fdf49c05 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1,156 +1,198 @@ -mod schema_omm -{ - pub mod xml_schema_types - { - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - BStarUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - BTermUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - AgomUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - ElementSetNoType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - RevUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - DRevUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - DdRevUnits(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct - SpacewarnType(#[serde(rename = "$text")] std :: string :: String) ; - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OmmType - { - #[serde(rename = "header")] pub header : schema_common :: - xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body - : schema_common :: xml_schema_types :: OmmBody, - #[serde(rename = "@id")] pub id : String, - #[serde(rename = "@version")] pub version : String, +mod schema_omm { + pub mod xml_schema_types { + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BStarUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BTermUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AgomUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ElementSetNoType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RevUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DRevUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DdRevUnits(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct SpacewarnType(#[serde(rename = "$text")] std::string::String); + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OmmType { + #[serde(rename = "header")] + pub header: schema_common::xml_schema_types::OdmHeader, + #[serde(rename = "body")] + pub body: schema_common::xml_schema_types::OmmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OmmBody - { - #[serde(rename = "segment")] pub segment : schema_common :: - xml_schema_types :: OmmSegment, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OmmBody { + #[serde(rename = "segment")] + pub segment: schema_common::xml_schema_types::OmmSegment, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OmmSegment - { - #[serde(rename = "metadata")] pub metadata : schema_common :: - xml_schema_types :: OmmMetadata, #[serde(rename = "data")] pub - data : schema_common :: xml_schema_types :: OmmData, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OmmSegment { + #[serde(rename = "metadata")] + pub metadata: schema_common::xml_schema_types::OmmMetadata, + #[serde(rename = "data")] + pub data: schema_common::xml_schema_types::OmmData, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OmmMetadata - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "OBJECT_NAME")] pub object_name : String, - #[serde(rename = "OBJECT_ID")] pub object_id : String, - #[serde(rename = "CENTER_NAME")] pub center_name : String, - #[serde(rename = "REF_FRAME")] pub ref_frame : String, - #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option - < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "TIME_SYSTEM")] pub time_system : String, - #[serde(rename = "MEAN_ELEMENT_THEORY")] pub mean_element_theory : - String, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OmmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "MEAN_ELEMENT_THEORY")] + pub mean_element_theory: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OmmData - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "meanElements")] pub mean_elements : - schema_common :: xml_schema_types :: MeanElementsType, - #[serde(rename = "spacecraftParameters")] pub - spacecraft_parameters : Option < schema_common :: xml_schema_types - :: SpacecraftParametersType >, #[serde(rename = "tleParameters")] - pub tle_parameters : Option < schema_common :: xml_schema_types :: - TleParametersType >, #[serde(rename = "covarianceMatrix")] pub - covariance_matrix : Option < schema_common :: xml_schema_types :: - OpmCovarianceMatrixType >, - #[serde(rename = "userDefinedParameters")] pub - user_defined_parameters : Option < schema_common :: - xml_schema_types :: UserDefinedType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OmmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "meanElements")] + pub mean_elements: schema_common::xml_schema_types::MeanElementsType, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: + Option, + #[serde(rename = "tleParameters")] + pub tle_parameters: Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct MeanElementsType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "EPOCH")] pub epoch : schema_common :: - xml_schema_types :: EpochType, #[serde(rename = "ECCENTRICITY")] - pub eccentricity : schema_common :: xml_schema_types :: - NonNegativeDouble, #[serde(rename = "INCLINATION")] pub - inclination : schema_common :: xml_schema_types :: - InclinationType, #[serde(rename = "RA_OF_ASC_NODE")] pub - ra_of_asc_node : schema_common :: xml_schema_types :: AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] pub arg_of_pericenter : - schema_common :: xml_schema_types :: AngleType, - #[serde(rename = "MEAN_ANOMALY")] pub mean_anomaly : schema_common - :: xml_schema_types :: AngleType, #[serde(rename = "GM")] pub gm : - Option < schema_common :: xml_schema_types :: GmType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct MeanElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: schema_common::xml_schema_types::EpochType, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: schema_common::xml_schema_types::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: schema_common::xml_schema_types::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: schema_common::xml_schema_types::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: schema_common::xml_schema_types::AngleType, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: schema_common::xml_schema_types::AngleType, + #[serde(rename = "GM")] + pub gm: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct TleParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "EPHEMERIS_TYPE")] pub ephemeris_type : Option < - i32 >, #[serde(rename = "CLASSIFICATION_TYPE")] pub - classification_type : Option < String >, - #[serde(rename = "NORAD_CAT_ID")] pub norad_cat_id : Option < i32 - >, #[serde(rename = "ELEMENT_SET_NO")] pub element_set_no : Option - < schema_common :: xml_schema_types :: ElementSetNoType >, - #[serde(rename = "REV_AT_EPOCH")] pub rev_at_epoch : Option < u64 - >, #[serde(rename = "MEAN_MOTION_DOT")] pub mean_motion_dot : - schema_common :: xml_schema_types :: DRevType, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct TleParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPHEMERIS_TYPE")] + pub ephemeris_type: Option, + #[serde(rename = "CLASSIFICATION_TYPE")] + pub classification_type: Option, + #[serde(rename = "NORAD_CAT_ID")] + pub norad_cat_id: Option, + #[serde(rename = "ELEMENT_SET_NO")] + pub element_set_no: Option, + #[serde(rename = "REV_AT_EPOCH")] + pub rev_at_epoch: Option, + #[serde(rename = "MEAN_MOTION_DOT")] + pub mean_motion_dot: schema_common::xml_schema_types::DRevType, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct BStarType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: BStarUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BStarType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct BTermType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: BTermUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct BTermType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct AgomType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: AgomUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct AgomType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct RevType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: RevUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct RevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DRevType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: DRevUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct DdRevType - { - #[serde(rename = "$text")] pub base : f64, - #[serde(rename = "@units")] pub units : Option < schema_common :: - xml_schema_types :: DdRevUnits >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct DdRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } } -} pub use schema_omm :: * ; \ No newline at end of file +} +pub use schema_omm::*; diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 4ecb63be..7145dd30 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -1,94 +1,113 @@ -mod schema_opm -{ - pub mod xml_schema_types - { - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmType - { - #[serde(rename = "header")] pub header : schema_common :: - xml_schema_types :: OdmHeader, #[serde(rename = "body")] pub body - : schema_common :: xml_schema_types :: OpmBody, - #[serde(rename = "@id")] pub id : String, - #[serde(rename = "@version")] pub version : String, +mod schema_opm { + pub mod xml_schema_types { + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmType { + #[serde(rename = "header")] + pub header: schema_common::xml_schema_types::OdmHeader, + #[serde(rename = "body")] + pub body: schema_common::xml_schema_types::OpmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmBody - { - #[serde(rename = "segment")] pub segment : schema_common :: - xml_schema_types :: OpmSegment, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmBody { + #[serde(rename = "segment")] + pub segment: schema_common::xml_schema_types::OpmSegment, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmSegment - { - #[serde(rename = "metadata")] pub metadata : schema_common :: - xml_schema_types :: OpmMetadata, #[serde(rename = "data")] pub - data : schema_common :: xml_schema_types :: OpmData, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmSegment { + #[serde(rename = "metadata")] + pub metadata: schema_common::xml_schema_types::OpmMetadata, + #[serde(rename = "data")] + pub data: schema_common::xml_schema_types::OpmData, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmMetadata - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "OBJECT_NAME")] pub object_name : String, - #[serde(rename = "OBJECT_ID")] pub object_id : String, - #[serde(rename = "CENTER_NAME")] pub center_name : String, - #[serde(rename = "REF_FRAME")] pub ref_frame : String, - #[serde(rename = "REF_FRAME_EPOCH")] pub ref_frame_epoch : Option - < schema_common :: xml_schema_types :: EpochType >, - #[serde(rename = "TIME_SYSTEM")] pub time_system : String, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct OpmData - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "stateVector")] pub state_vector : schema_common - :: xml_schema_types :: StateVectorType, - #[serde(rename = "keplerianElements")] pub keplerian_elements : - Option < schema_common :: xml_schema_types :: - KeplerianElementsType >, #[serde(rename = "spacecraftParameters")] - pub spacecraft_parameters : Option < schema_common :: - xml_schema_types :: SpacecraftParametersType >, - #[serde(rename = "covarianceMatrix")] pub covariance_matrix : - Option < schema_common :: xml_schema_types :: - OpmCovarianceMatrixType >, #[serde(rename = "maneuverParameters")] - pub maneuver_parameters_list : Vec < schema_common :: - xml_schema_types :: ManeuverParametersType >, - #[serde(rename = "userDefinedParameters")] pub - user_defined_parameters : Option < schema_common :: - xml_schema_types :: UserDefinedType >, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct OpmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector: schema_common::xml_schema_types::StateVectorType, + #[serde(rename = "keplerianElements")] + pub keplerian_elements: Option, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: + Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "maneuverParameters")] + pub maneuver_parameters_list: + Vec, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct KeplerianElementsType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "SEMI_MAJOR_AXIS")] pub semi_major_axis : - schema_common :: xml_schema_types :: DistanceType, - #[serde(rename = "ECCENTRICITY")] pub eccentricity : schema_common - :: xml_schema_types :: NonNegativeDouble, - #[serde(rename = "INCLINATION")] pub inclination : schema_common - :: xml_schema_types :: InclinationType, - #[serde(rename = "RA_OF_ASC_NODE")] pub ra_of_asc_node : - schema_common :: xml_schema_types :: AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] pub arg_of_pericenter : - schema_common :: xml_schema_types :: AngleType, - #[serde(rename = "GM")] pub gm : schema_common :: xml_schema_types - :: GmType, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct KeplerianElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: schema_common::xml_schema_types::DistanceType, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: schema_common::xml_schema_types::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: schema_common::xml_schema_types::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: schema_common::xml_schema_types::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: schema_common::xml_schema_types::AngleType, + #[serde(rename = "GM")] + pub gm: schema_common::xml_schema_types::GmType, } - #[derive(Clone, Debug, Default, PartialEq, serde :: Deserialize, serde - :: Serialize)] #[serde(default)] pub struct ManeuverParametersType - { - #[serde(rename = "COMMENT")] pub comment_list : Vec < String >, - #[serde(rename = "MAN_EPOCH_IGNITION")] pub man_epoch_ignition : - schema_common :: xml_schema_types :: EpochType, - #[serde(rename = "MAN_DURATION")] pub man_duration : schema_common - :: xml_schema_types :: DurationType, - #[serde(rename = "MAN_DELTA_MASS")] pub man_delta_mass : - schema_common :: xml_schema_types :: DeltamassType, - #[serde(rename = "MAN_REF_FRAME")] pub man_ref_frame : String, - #[serde(rename = "MAN_DV_1")] pub man_dv_1 : schema_common :: - xml_schema_types :: VelocityType, #[serde(rename = "MAN_DV_2")] - pub man_dv_2 : schema_common :: xml_schema_types :: VelocityType, - #[serde(rename = "MAN_DV_3")] pub man_dv_3 : schema_common :: - xml_schema_types :: VelocityType, + + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] + #[serde(default)] + pub struct ManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_EPOCH_IGNITION")] + pub man_epoch_ignition: schema_common::xml_schema_types::EpochType, + #[serde(rename = "MAN_DURATION")] + pub man_duration: schema_common::xml_schema_types::DurationType, + #[serde(rename = "MAN_DELTA_MASS")] + pub man_delta_mass: schema_common::xml_schema_types::DeltamassType, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_DV_1")] + pub man_dv_1: schema_common::xml_schema_types::VelocityType, + #[serde(rename = "MAN_DV_2")] + pub man_dv_2: schema_common::xml_schema_types::VelocityType, + #[serde(rename = "MAN_DV_3")] + pub man_dv_3: schema_common::xml_schema_types::VelocityType, } } -} pub use schema_opm :: * ; \ No newline at end of file +} +pub use schema_opm::*; From e1f3fe2bf2ab53ecee7117eb4b6ed615fa154acf Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 17:53:46 +0100 Subject: [PATCH 003/150] Fix namespaces and imports --- crates/lox-utils/src/odm/common.rs | 2108 ++++++++++++++-------------- crates/lox-utils/src/odm/ocm.rs | 1053 +++++++------- crates/lox-utils/src/odm/oem.rs | 138 +- crates/lox-utils/src/odm/omm.rs | 390 +++-- crates/lox-utils/src/odm/opm.rs | 207 ++- 5 files changed, 1937 insertions(+), 1959 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 3ba53990..565b287b 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -1,1173 +1,1167 @@ -mod schema_common { - pub mod xml_schema_types { +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AccUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AccUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRange(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleRange(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleRateUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngMomentumUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngMomentumUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelFrameType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngVelFrameType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AreaUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AreaUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DayIntervalUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DayIntervalUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct FrequencyUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct FrequencyUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GmUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct GmUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct InclinationRange(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct InclinationRange(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LengthUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LengthUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MassUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct MassUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MomentUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct MomentUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct WkgUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct WkgUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ObjectDescriptionType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ObjectDescriptionType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Ms2Units(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Ms2Units(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2Units(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2Units(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2sUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2sUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2s2Units(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2s2Units(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct VelocityUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq)] - pub struct VecDouble { - pub items: Vec, - } - impl yaserde::YaDeserialize for VecDouble { - fn deserialize( - reader: &mut yaserde::de::Deserializer, - ) -> Result { - loop { - match reader.next_event()? { - xml::reader::XmlEvent::StartElement { .. } => {} - xml::reader::XmlEvent::Characters(ref text_content) => { - let items: Vec = text_content - .split(' ') - .map(|item| item.to_owned()) - .map(|item| item.parse().unwrap()) - .collect(); - return Ok(VecDouble { items }); - } - _ => { - break; - } - } +#[derive(Clone, Debug, Default, PartialEq)] +pub struct VecDouble { + pub items: Vec, +} +impl yaserde::YaDeserialize for VecDouble { + fn deserialize( + reader: &mut yaserde::de::Deserializer, + ) -> Result { + loop { + match reader.next_event()? { + xml::reader::XmlEvent::StartElement { .. } => {} + xml::reader::XmlEvent::Characters(ref text_content) => { + let items: Vec = text_content + .split(' ') + .map(|item| item.to_owned()) + .map(|item| item.parse().unwrap()) + .collect(); + return Ok(VecDouble { items }); + } + _ => { + break; } - Err("Unable to parse attribute".to_string()) - } - } - impl yaserde::YaSerialize for VecDouble { - fn serialize( - &self, - writer: &mut yaserde::ser::Serializer, - ) -> Result<(), String> { - let content = self - .items - .iter() - .map(|item| item.to_string()) - .collect::>() - .join(" "); - let data_event = xml::writer::XmlEvent::characters(&content); - writer.write(data_event).map_err(|e| e.to_string())?; - Ok(()) - } - fn serialize_attributes( - &self, - mut source_attributes: Vec, - mut source_namespace: xml::namespace::Namespace, - ) -> Result< - ( - Vec, - xml::namespace::Namespace, - ), - String, - > { - Ok((source_attributes, source_namespace)) } } + Err("Unable to parse attribute".to_string()) + } +} +impl yaserde::YaSerialize for VecDouble { + fn serialize( + &self, + writer: &mut yaserde::ser::Serializer, + ) -> Result<(), String> { + let content = self + .items + .iter() + .map(|item| item.to_string()) + .collect::>() + .join(" "); + let data_event = xml::writer::XmlEvent::characters(&content); + writer.write(data_event).map_err(|e| e.to_string())?; + Ok(()) + } + fn serialize_attributes( + &self, + mut source_attributes: Vec, + mut source_namespace: xml::namespace::Namespace, + ) -> Result< + ( + Vec, + xml::namespace::Namespace, + ), + String, + > { + Ok((source_attributes, source_namespace)) + } +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Vec3Double(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec3Double(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Vec6Double(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec6Double(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Vec9Double(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec9Double(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct EpochType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct EpochType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TimeUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TimeSystemType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeSystemType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct NegativeDouble(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NegativeDouble(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct NonNegativeDouble(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NonNegativeDouble(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct NonPositiveDouble(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NonPositiveDouble(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PercentType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositiveDouble(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositiveDouble(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Range100Type(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Range100Type(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ProbabilityType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ProbabilityType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PercentageUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentageUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct YesNoType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct YesNoType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TrajBasisType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TrajBasisType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RevNumBasisType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevNumBasisType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct CovBasisType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct CovBasisType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ManBasisType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManBasisType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ManDcType(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManDcType(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct NumPerYearUnits(#[serde(rename = "$text")] std::string::String); +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NumPerYearUnits(#[serde(rename = "$text")] std::string::String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ThrustUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct CovOrderType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct GeomagUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct SolarFluxUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionCovarianceUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LatRange(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AltRange(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LonRange(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LatLonUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ControlledType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DisintegrationType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ImpactUncertaintyType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct QuaternionComponentType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct QuaternionDotUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotDirectionType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotseqType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleKeywordType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleRateKeywordType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ApmRateFrameType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TorqueUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct NdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ThrustUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct CovOrderType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GeomagUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SolarFluxUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionCovarianceUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatRange(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AltRange(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LonRange(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatLonUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ControlledType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DisintegrationType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ImpactUncertaintyType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionComponentType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionDotUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotDirectionType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotseqType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleKeywordType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateKeywordType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ApmRateFrameType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TorqueUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CLASSIFICATION")] - pub classification_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CLASSIFICATION")] + pub classification_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AccType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AccType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleType { - #[serde(rename = "$text")] - pub base: AngleRange, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngleRateType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngMomentumType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: AngMomentumUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngMomentumType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: AngMomentumUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngVelComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngVelStateType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "REF_FRAME_A")] - pub ref_frame_a: String, - #[serde(rename = "REF_FRAME_B")] - pub ref_frame_b: String, - #[serde(rename = "ANGVEL_FRAME")] - pub angvel_frame: AngVelFrameType, - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "REF_FRAME_A")] + pub ref_frame_a: String, + #[serde(rename = "REF_FRAME_B")] + pub ref_frame_b: String, + #[serde(rename = "ANGVEL_FRAME")] + pub angvel_frame: AngVelFrameType, + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AngVelType { - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelType { + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AreaType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AreaType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DayIntervalType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: DayIntervalUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: DayIntervalUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmDayIntervalType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmDayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DeltamassType { - #[serde(rename = "$text")] - pub base: NegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DeltamassType { + #[serde(rename = "$text")] + pub base: NegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DeltamassTypeZ { - #[serde(rename = "$text")] - pub base: NonPositiveDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DeltamassTypeZ { + #[serde(rename = "$text")] + pub base: NonPositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct FrequencyType { - #[serde(rename = "$text")] - pub base: PositiveDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct FrequencyType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct GmType { - #[serde(rename = "$text")] - pub base: PositiveDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GmType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct InclinationType { - #[serde(rename = "$text")] - pub base: InclinationRange, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct InclinationType { + #[serde(rename = "$text")] + pub base: InclinationRange, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LengthType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: LengthUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: LengthUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmLengthType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmLengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct MassType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MassType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct MomentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MomentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct WkgType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: WkgUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct WkgType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: WkgUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OdParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "TIME_LASTOB_START")] - pub time_lastob_start: Option, - #[serde(rename = "TIME_LASTOB_END")] - pub time_lastob_end: Option, - #[serde(rename = "RECOMMENDED_OD_SPAN")] - pub recommended_od_span: Option, - #[serde(rename = "ACTUAL_OD_SPAN")] - pub actual_od_span: Option, - #[serde(rename = "OBS_AVAILABLE")] - pub obs_available: Option, - #[serde(rename = "OBS_USED")] - pub obs_used: Option, - #[serde(rename = "TRACKS_AVAILABLE")] - pub tracks_available: Option, - #[serde(rename = "TRACKS_USED")] - pub tracks_used: Option, - #[serde(rename = "RESIDUALS_ACCEPTED")] - pub residuals_accepted: Option, - #[serde(rename = "WEIGHTED_RMS")] - pub weighted_rms: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TIME_LASTOB_START")] + pub time_lastob_start: Option, + #[serde(rename = "TIME_LASTOB_END")] + pub time_lastob_end: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "RESIDUALS_ACCEPTED")] + pub residuals_accepted: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct SpacecraftParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MASS")] - pub mass: Option, - #[serde(rename = "SOLAR_RAD_AREA")] - pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] - pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] - pub drag_coeff: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MASS")] + pub mass: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct StateVectorType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "X")] - pub x: PositionType, - #[serde(rename = "Y")] - pub y: PositionType, - #[serde(rename = "Z")] - pub z: PositionType, - #[serde(rename = "X_DOT")] - pub x_dot: VelocityType, - #[serde(rename = "Y_DOT")] - pub y_dot: VelocityType, - #[serde(rename = "Z_DOT")] - pub z_dot: VelocityType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct StateVectorType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct StateVectorAccType { - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "X")] - pub x: PositionType, - #[serde(rename = "Y")] - pub y: PositionType, - #[serde(rename = "Z")] - pub z: PositionType, - #[serde(rename = "X_DOT")] - pub x_dot: VelocityType, - #[serde(rename = "Y_DOT")] - pub y_dot: VelocityType, - #[serde(rename = "Z_DOT")] - pub z_dot: VelocityType, - #[serde(rename = "X_DDOT")] - pub x_ddot: Option, - #[serde(rename = "Y_DDOT")] - pub y_ddot: Option, - #[serde(rename = "Z_DDOT")] - pub z_ddot: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct StateVectorAccType { + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, + #[serde(rename = "X_DDOT")] + pub x_ddot: Option, + #[serde(rename = "Y_DDOT")] + pub y_ddot: Option, + #[serde(rename = "Z_DDOT")] + pub z_ddot: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Ms2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Ms2Units, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Ms2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Ms2Units, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2sType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2sType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct Km2s2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2s2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DistanceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DistanceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RdmPositionType { - #[serde(rename = "$text")] - pub base: String, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmPositionType { + #[serde(rename = "$text")] + pub base: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct VelocityType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RdmVelocityType { - #[serde(rename = "$text")] - pub base: String, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmVelocityType { + #[serde(rename = "$text")] + pub base: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DurationType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DurationType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RelTimeType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RelTimeType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TimeOffsetType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeOffsetType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PercentageType { - #[serde(rename = "$text")] - pub base: Range100Type, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentageType { + #[serde(rename = "$text")] + pub base: Range100Type, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ManeuverFreqType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManeuverFreqType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ThrustType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ThrustType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct GeomagType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GeomagType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct SolarFluxType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SolarFluxType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmCovarianceMatrixAbstractType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmCovarianceMatrixAbstractType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemCovarianceMatrixAbstractType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemCovarianceMatrixAbstractType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemCovarianceMatrixType { - #[serde(flatten)] - pub base: OemCovarianceMatrixAbstractType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemCovarianceMatrixType { + #[serde(flatten)] + pub base: OemCovarianceMatrixAbstractType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmCovarianceMatrixType { - #[serde(flatten)] - pub base: OpmCovarianceMatrixAbstractType, - #[serde(flatten)] - pub extension: CovarianceMatrixElementsGroup, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmCovarianceMatrixType { + #[serde(flatten)] + pub base: OpmCovarianceMatrixAbstractType, + #[serde(flatten)] + pub extension: CovarianceMatrixElementsGroup, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct VelocityCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct PositionVelocityCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionVelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AtmosphericReentryParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "ORBIT_LIFETIME")] - pub orbit_lifetime: DayIntervalType, - #[serde(rename = "REENTRY_ALTITUDE")] - pub reentry_altitude: PositionType, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] - pub orbit_lifetime_window_start: Option, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] - pub orbit_lifetime_window_end: Option, - #[serde(rename = "NOMINAL_REENTRY_EPOCH")] - pub nominal_reentry_epoch: Option, - #[serde(rename = "REENTRY_WINDOW_START")] - pub reentry_window_start: Option, - #[serde(rename = "REENTRY_WINDOW_END")] - pub reentry_window_end: Option, - #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] - pub orbit_lifetime_confidence_level: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AtmosphericReentryParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ORBIT_LIFETIME")] + pub orbit_lifetime: DayIntervalType, + #[serde(rename = "REENTRY_ALTITUDE")] + pub reentry_altitude: PositionType, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] + pub orbit_lifetime_window_start: Option, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] + pub orbit_lifetime_window_end: Option, + #[serde(rename = "NOMINAL_REENTRY_EPOCH")] + pub nominal_reentry_epoch: Option, + #[serde(rename = "REENTRY_WINDOW_START")] + pub reentry_window_start: Option, + #[serde(rename = "REENTRY_WINDOW_END")] + pub reentry_window_end: Option, + #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] + pub orbit_lifetime_confidence_level: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct GroundImpactParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "PROBABILITY_OF_IMPACT")] - pub probability_of_impact: Option, - #[serde(rename = "PROBABILITY_OF_BURN_UP")] - pub probability_of_burn_up: Option, - #[serde(rename = "PROBABILITY_OF_BREAK_UP")] - pub probability_of_break_up: Option, - #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] - pub probability_of_land_impact: Option, - #[serde(rename = "PROBABILITY_OF_CASUALTY")] - pub probability_of_casualty: Option, - #[serde(rename = "NOMINAL_IMPACT_EPOCH")] - pub nominal_impact_epoch: Option, - #[serde(rename = "IMPACT_WINDOW_START")] - pub impact_window_start: Option, - #[serde(rename = "IMPACT_WINDOW_END")] - pub impact_window_end: Option, - #[serde(rename = "IMPACT_REF_FRAME")] - pub impact_ref_frame: Option, - #[serde(rename = "NOMINAL_IMPACT_LON")] - pub nominal_impact_lon: Option, - #[serde(rename = "NOMINAL_IMPACT_LAT")] - pub nominal_impact_lat: Option, - #[serde(rename = "NOMINAL_IMPACT_ALT")] - pub nominal_impact_alt: Option, - #[serde(rename = "IMPACT_1_CONFIDENCE")] - pub impact_1_confidence: Option, - #[serde(rename = "IMPACT_1_START_LON")] - pub impact_1_start_lon: Option, - #[serde(rename = "IMPACT_1_START_LAT")] - pub impact_1_start_lat: Option, - #[serde(rename = "IMPACT_1_STOP_LON")] - pub impact_1_stop_lon: Option, - #[serde(rename = "IMPACT_1_STOP_LAT")] - pub impact_1_stop_lat: Option, - #[serde(rename = "IMPACT_1_CROSS_TRACK")] - pub impact_1_cross_track: Option, - #[serde(rename = "IMPACT_2_CONFIDENCE")] - pub impact_2_confidence: Option, - #[serde(rename = "IMPACT_2_START_LON")] - pub impact_2_start_lon: Option, - #[serde(rename = "IMPACT_2_START_LAT")] - pub impact_2_start_lat: Option, - #[serde(rename = "IMPACT_2_STOP_LON")] - pub impact_2_stop_lon: Option, - #[serde(rename = "IMPACT_2_STOP_LAT")] - pub impact_2_stop_lat: Option, - #[serde(rename = "IMPACT_2_CROSS_TRACK")] - pub impact_2_cross_track: Option, - #[serde(rename = "IMPACT_3_CONFIDENCE")] - pub impact_3_confidence: Option, - #[serde(rename = "IMPACT_3_START_LON")] - pub impact_3_start_lon: Option, - #[serde(rename = "IMPACT_3_START_LAT")] - pub impact_3_start_lat: Option, - #[serde(rename = "IMPACT_3_STOP_LON")] - pub impact_3_stop_lon: Option, - #[serde(rename = "IMPACT_3_STOP_LAT")] - pub impact_3_stop_lat: Option, - #[serde(rename = "IMPACT_3_CROSS_TRACK")] - pub impact_3_cross_track: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GroundImpactParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "PROBABILITY_OF_IMPACT")] + pub probability_of_impact: Option, + #[serde(rename = "PROBABILITY_OF_BURN_UP")] + pub probability_of_burn_up: Option, + #[serde(rename = "PROBABILITY_OF_BREAK_UP")] + pub probability_of_break_up: Option, + #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] + pub probability_of_land_impact: Option, + #[serde(rename = "PROBABILITY_OF_CASUALTY")] + pub probability_of_casualty: Option, + #[serde(rename = "NOMINAL_IMPACT_EPOCH")] + pub nominal_impact_epoch: Option, + #[serde(rename = "IMPACT_WINDOW_START")] + pub impact_window_start: Option, + #[serde(rename = "IMPACT_WINDOW_END")] + pub impact_window_end: Option, + #[serde(rename = "IMPACT_REF_FRAME")] + pub impact_ref_frame: Option, + #[serde(rename = "NOMINAL_IMPACT_LON")] + pub nominal_impact_lon: Option, + #[serde(rename = "NOMINAL_IMPACT_LAT")] + pub nominal_impact_lat: Option, + #[serde(rename = "NOMINAL_IMPACT_ALT")] + pub nominal_impact_alt: Option, + #[serde(rename = "IMPACT_1_CONFIDENCE")] + pub impact_1_confidence: Option, + #[serde(rename = "IMPACT_1_START_LON")] + pub impact_1_start_lon: Option, + #[serde(rename = "IMPACT_1_START_LAT")] + pub impact_1_start_lat: Option, + #[serde(rename = "IMPACT_1_STOP_LON")] + pub impact_1_stop_lon: Option, + #[serde(rename = "IMPACT_1_STOP_LAT")] + pub impact_1_stop_lat: Option, + #[serde(rename = "IMPACT_1_CROSS_TRACK")] + pub impact_1_cross_track: Option, + #[serde(rename = "IMPACT_2_CONFIDENCE")] + pub impact_2_confidence: Option, + #[serde(rename = "IMPACT_2_START_LON")] + pub impact_2_start_lon: Option, + #[serde(rename = "IMPACT_2_START_LAT")] + pub impact_2_start_lat: Option, + #[serde(rename = "IMPACT_2_STOP_LON")] + pub impact_2_stop_lon: Option, + #[serde(rename = "IMPACT_2_STOP_LAT")] + pub impact_2_stop_lat: Option, + #[serde(rename = "IMPACT_2_CROSS_TRACK")] + pub impact_2_cross_track: Option, + #[serde(rename = "IMPACT_3_CONFIDENCE")] + pub impact_3_confidence: Option, + #[serde(rename = "IMPACT_3_START_LON")] + pub impact_3_start_lon: Option, + #[serde(rename = "IMPACT_3_START_LAT")] + pub impact_3_start_lat: Option, + #[serde(rename = "IMPACT_3_STOP_LON")] + pub impact_3_stop_lon: Option, + #[serde(rename = "IMPACT_3_STOP_LAT")] + pub impact_3_stop_lat: Option, + #[serde(rename = "IMPACT_3_CROSS_TRACK")] + pub impact_3_cross_track: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RdmSpacecraftParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "WET_MASS")] - pub wet_mass: Option, - #[serde(rename = "DRY_MASS")] - pub dry_mass: Option, - #[serde(rename = "HAZARDOUS_SUBSTANCES")] - pub hazardous_substances: Option, - #[serde(rename = "SOLAR_RAD_AREA")] - pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] - pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] - pub drag_coeff: Option, - #[serde(rename = "RCS")] - pub rcs: Option, - #[serde(rename = "BALLISTIC_COEFF")] - pub ballistic_coeff: Option, - #[serde(rename = "THRUST_ACCELERATION")] - pub thrust_acceleration: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmSpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "HAZARDOUS_SUBSTANCES")] + pub hazardous_substances: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "BALLISTIC_COEFF")] + pub ballistic_coeff: Option, + #[serde(rename = "THRUST_ACCELERATION")] + pub thrust_acceleration: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AltType { - #[serde(rename = "$text")] - pub base: AltRange, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AltType { + #[serde(rename = "$text")] + pub base: AltRange, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BallisticCoeffType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BallisticCoeffType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LatType { - #[serde(rename = "$text")] - pub base: LatRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatType { + #[serde(rename = "$text")] + pub base: LatRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct LonType { - #[serde(rename = "$text")] - pub base: LonRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LonType { + #[serde(rename = "$text")] + pub base: LonRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct UserDefinedType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "USER_DEFINED")] - pub user_defined_list: Vec, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct UserDefinedType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "USER_DEFINED")] + pub user_defined_list: Vec, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct UserDefinedParameterType { - #[serde(rename = "$text")] - pub base: String, - #[serde(rename = "@parameter")] - pub parameter: String, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct UserDefinedParameterType { + #[serde(rename = "$text")] + pub base: String, + #[serde(rename = "@parameter")] + pub parameter: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct QuaternionType {} - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct QuaternionRateType {} - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct QuaternionDotType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionType {} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionRateType {} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionDotType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationAngleType { - #[serde(rename = "rotation1")] - pub rotation1: RotationAngleComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationAngleComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationAngleComponentType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleType { + #[serde(rename = "rotation1")] + pub rotation1: RotationAngleComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationAngleComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationAngleComponentType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationAngleComponentTypeold { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@value")] - pub value: AngleRange, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleComponentTypeold { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@value")] + pub value: AngleRange, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationAngleComponentType { - #[serde(rename = "$text")] - pub base: AngleRange, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleComponentType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationRateType { - #[serde(rename = "rotation1")] - pub rotation1: RotationRateComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationRateComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationRateComponentType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateType { + #[serde(rename = "rotation1")] + pub rotation1: RotationRateComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationRateComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationRateComponentType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationRateComponentTypeOld { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@value")] - pub value: f64, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateComponentTypeOld { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@value")] + pub value: f64, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RotationRateComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TorqueType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TorqueType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct CovarianceMatrixElementsGroup { - #[serde(rename = "CX_X")] - pub cx_x: PositionCovarianceType, - #[serde(rename = "CY_X")] - pub cy_x: PositionCovarianceType, - #[serde(rename = "CY_Y")] - pub cy_y: PositionCovarianceType, - #[serde(rename = "CZ_X")] - pub cz_x: PositionCovarianceType, - #[serde(rename = "CZ_Y")] - pub cz_y: PositionCovarianceType, - #[serde(rename = "CZ_Z")] - pub cz_z: PositionCovarianceType, - #[serde(rename = "CX_DOT_X")] - pub cx_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Y")] - pub cx_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Z")] - pub cx_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_X_DOT")] - pub cx_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_X")] - pub cy_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Y")] - pub cy_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Z")] - pub cy_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_X_DOT")] - pub cy_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_Y_DOT")] - pub cy_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_X")] - pub cz_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y")] - pub cz_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z")] - pub cz_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_X_DOT")] - pub cz_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y_DOT")] - pub cz_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z_DOT")] - pub cz_dot_z_dot: VelocityCovarianceType, - } - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct CovarianceMatrixElementsGroup { + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, } -pub use schema_common::*; diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index 11abed2c..b146370c 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -1,539 +1,536 @@ -mod schema_ocm { - pub mod xml_schema_types { - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmType { - #[serde(rename = "header")] - pub header: schema_common::xml_schema_types::OdmHeader, - #[serde(rename = "body")] - pub body: schema_common::xml_schema_types::OcmBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, - } +use super::common; - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmBody { - #[serde(rename = "segment")] - pub segment: schema_common::xml_schema_types::OcmSegment, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: common::OcmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmSegment { - #[serde(rename = "metadata")] - pub metadata: schema_common::xml_schema_types::OcmMetadata, - #[serde(rename = "data")] - pub data: schema_common::xml_schema_types::OcmData, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmBody { + #[serde(rename = "segment")] + pub segment: common::OcmSegment, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: Option, - #[serde(rename = "INTERNATIONAL_DESIGNATOR")] - pub international_designator: Option, - #[serde(rename = "CATALOG_NAME")] - pub catalog_name: Option, - #[serde(rename = "OBJECT_DESIGNATOR")] - pub object_designator: Option, - #[serde(rename = "ALTERNATE_NAMES")] - pub alternate_names: Option, - #[serde(rename = "ORIGINATOR_POC")] - pub originator_poc: Option, - #[serde(rename = "ORIGINATOR_POSITION")] - pub originator_position: Option, - #[serde(rename = "ORIGINATOR_PHONE")] - pub originator_phone: Option, - #[serde(rename = "ORIGINATOR_EMAIL")] - pub originator_email: Option, - #[serde(rename = "ORIGINATOR_ADDRESS")] - pub originator_address: Option, - #[serde(rename = "TECH_ORG")] - pub tech_org: Option, - #[serde(rename = "TECH_POC")] - pub tech_poc: Option, - #[serde(rename = "TECH_POSITION")] - pub tech_position: Option, - #[serde(rename = "TECH_PHONE")] - pub tech_phone: Option, - #[serde(rename = "TECH_EMAIL")] - pub tech_email: Option, - #[serde(rename = "TECH_ADDRESS")] - pub tech_address: Option, - #[serde(rename = "PREVIOUS_MESSAGE_ID")] - pub previous_message_id: Option, - #[serde(rename = "NEXT_MESSAGE_ID")] - pub next_message_id: Option, - #[serde(rename = "ADM_MSG_LINK")] - pub adm_msg_link: Option, - #[serde(rename = "CDM_MSG_LINK")] - pub cdm_msg_link: Option, - #[serde(rename = "PRM_MSG_LINK")] - pub prm_msg_link: Option, - #[serde(rename = "RDM_MSG_LINK")] - pub rdm_msg_link: Option, - #[serde(rename = "TDM_MSG_LINK")] - pub tdm_msg_link: Option, - #[serde(rename = "OPERATOR")] - pub operator: Option, - #[serde(rename = "OWNER")] - pub owner: Option, - #[serde(rename = "COUNTRY")] - pub country: Option, - #[serde(rename = "CONSTELLATION")] - pub constellation: Option, - #[serde(rename = "OBJECT_TYPE")] - pub object_type: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "EPOCH_TZERO")] - pub epoch_tzero: schema_common::xml_schema_types::EpochType, - #[serde(rename = "OPS_STATUS")] - pub ops_status: Option, - #[serde(rename = "ORBIT_CATEGORY")] - pub orbit_category: Option, - #[serde(rename = "OCM_DATA_ELEMENTS")] - pub ocm_data_elements: Option, - #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] - pub sclk_offset_at_epoch: Option, - #[serde(rename = "SCLK_SEC_PER_SI_SEC")] - pub sclk_sec_per_si_sec: Option, - #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] - pub previous_message_epoch: Option, - #[serde(rename = "NEXT_MESSAGE_EPOCH")] - pub next_message_epoch: Option, - #[serde(rename = "START_TIME")] - pub start_time: Option, - #[serde(rename = "STOP_TIME")] - pub stop_time: Option, - #[serde(rename = "TIME_SPAN")] - pub time_span: Option, - #[serde(rename = "TAIMUTC_AT_TZERO")] - pub taimutc_at_tzero: Option, - #[serde(rename = "NEXT_LEAP_EPOCH")] - pub next_leap_epoch: Option, - #[serde(rename = "NEXT_LEAP_TAIMUTC")] - pub next_leap_taimutc: Option, - #[serde(rename = "UT1MUTC_AT_TZERO")] - pub ut1mutc_at_tzero: Option, - #[serde(rename = "EOP_SOURCE")] - pub eop_source: Option, - #[serde(rename = "INTERP_METHOD_EOP")] - pub interp_method_eop: Option, - #[serde(rename = "CELESTIAL_SOURCE")] - pub celestial_source: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmSegment { + #[serde(rename = "metadata")] + pub metadata: common::OcmMetadata, + #[serde(rename = "data")] + pub data: common::OcmData, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmData { - #[serde(rename = "traj")] - pub traj_list: Vec, - #[serde(rename = "phys")] - pub phys: Option, - #[serde(rename = "cov")] - pub cov_list: Vec, - #[serde(rename = "man")] - pub man_list: Vec, - #[serde(rename = "pert")] - pub pert: Option, - #[serde(rename = "od")] - pub od: Option, - #[serde(rename = "user")] - pub user: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: Option, + #[serde(rename = "INTERNATIONAL_DESIGNATOR")] + pub international_designator: Option, + #[serde(rename = "CATALOG_NAME")] + pub catalog_name: Option, + #[serde(rename = "OBJECT_DESIGNATOR")] + pub object_designator: Option, + #[serde(rename = "ALTERNATE_NAMES")] + pub alternate_names: Option, + #[serde(rename = "ORIGINATOR_POC")] + pub originator_poc: Option, + #[serde(rename = "ORIGINATOR_POSITION")] + pub originator_position: Option, + #[serde(rename = "ORIGINATOR_PHONE")] + pub originator_phone: Option, + #[serde(rename = "ORIGINATOR_EMAIL")] + pub originator_email: Option, + #[serde(rename = "ORIGINATOR_ADDRESS")] + pub originator_address: Option, + #[serde(rename = "TECH_ORG")] + pub tech_org: Option, + #[serde(rename = "TECH_POC")] + pub tech_poc: Option, + #[serde(rename = "TECH_POSITION")] + pub tech_position: Option, + #[serde(rename = "TECH_PHONE")] + pub tech_phone: Option, + #[serde(rename = "TECH_EMAIL")] + pub tech_email: Option, + #[serde(rename = "TECH_ADDRESS")] + pub tech_address: Option, + #[serde(rename = "PREVIOUS_MESSAGE_ID")] + pub previous_message_id: Option, + #[serde(rename = "NEXT_MESSAGE_ID")] + pub next_message_id: Option, + #[serde(rename = "ADM_MSG_LINK")] + pub adm_msg_link: Option, + #[serde(rename = "CDM_MSG_LINK")] + pub cdm_msg_link: Option, + #[serde(rename = "PRM_MSG_LINK")] + pub prm_msg_link: Option, + #[serde(rename = "RDM_MSG_LINK")] + pub rdm_msg_link: Option, + #[serde(rename = "TDM_MSG_LINK")] + pub tdm_msg_link: Option, + #[serde(rename = "OPERATOR")] + pub operator: Option, + #[serde(rename = "OWNER")] + pub owner: Option, + #[serde(rename = "COUNTRY")] + pub country: Option, + #[serde(rename = "CONSTELLATION")] + pub constellation: Option, + #[serde(rename = "OBJECT_TYPE")] + pub object_type: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "EPOCH_TZERO")] + pub epoch_tzero: common::EpochType, + #[serde(rename = "OPS_STATUS")] + pub ops_status: Option, + #[serde(rename = "ORBIT_CATEGORY")] + pub orbit_category: Option, + #[serde(rename = "OCM_DATA_ELEMENTS")] + pub ocm_data_elements: Option, + #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] + pub sclk_offset_at_epoch: Option, + #[serde(rename = "SCLK_SEC_PER_SI_SEC")] + pub sclk_sec_per_si_sec: Option, + #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] + pub previous_message_epoch: Option, + #[serde(rename = "NEXT_MESSAGE_EPOCH")] + pub next_message_epoch: Option, + #[serde(rename = "START_TIME")] + pub start_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: Option, + #[serde(rename = "TIME_SPAN")] + pub time_span: Option, + #[serde(rename = "TAIMUTC_AT_TZERO")] + pub taimutc_at_tzero: Option, + #[serde(rename = "NEXT_LEAP_EPOCH")] + pub next_leap_epoch: Option, + #[serde(rename = "NEXT_LEAP_TAIMUTC")] + pub next_leap_taimutc: Option, + #[serde(rename = "UT1MUTC_AT_TZERO")] + pub ut1mutc_at_tzero: Option, + #[serde(rename = "EOP_SOURCE")] + pub eop_source: Option, + #[serde(rename = "INTERP_METHOD_EOP")] + pub interp_method_eop: Option, + #[serde(rename = "CELESTIAL_SOURCE")] + pub celestial_source: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmTrajStateType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "TRAJ_ID")] - pub traj_id: Option, - #[serde(rename = "TRAJ_PREV_ID")] - pub traj_prev_id: Option, - #[serde(rename = "TRAJ_NEXT_ID")] - pub traj_next_id: Option, - #[serde(rename = "TRAJ_BASIS")] - pub traj_basis: Option, - #[serde(rename = "TRAJ_BASIS_ID")] - pub traj_basis_id: Option, - #[serde(rename = "INTERPOLATION")] - pub interpolation: Option, - #[serde(rename = "INTERPOLATION_DEGREE")] - pub interpolation_degree: Option, - #[serde(rename = "PROPAGATOR")] - pub propagator: Option, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "TRAJ_REF_FRAME")] - pub traj_ref_frame: String, - #[serde(rename = "TRAJ_FRAME_EPOCH")] - pub traj_frame_epoch: Option, - #[serde(rename = "USEABLE_START_TIME")] - pub useable_start_time: Option, - #[serde(rename = "USEABLE_STOP_TIME")] - pub useable_stop_time: Option, - #[serde(rename = "ORB_REVNUM")] - pub orb_revnum: Option, - #[serde(rename = "ORB_REVNUM_BASIS")] - pub orb_revnum_basis: Option, - #[serde(rename = "TRAJ_TYPE")] - pub traj_type: String, - #[serde(rename = "ORB_AVERAGING")] - pub orb_averaging: Option, - #[serde(rename = "TRAJ_UNITS")] - pub traj_units: Option, - #[serde(rename = "trajLine")] - pub traj_line_list: Vec, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmData { + #[serde(rename = "traj")] + pub traj_list: Vec, + #[serde(rename = "phys")] + pub phys: Option, + #[serde(rename = "cov")] + pub cov_list: Vec, + #[serde(rename = "man")] + pub man_list: Vec, + #[serde(rename = "pert")] + pub pert: Option, + #[serde(rename = "od")] + pub od: Option, + #[serde(rename = "user")] + pub user: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmPhysicalDescriptionType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MANUFACTURER")] - pub manufacturer: Option, - #[serde(rename = "BUS_MODEL")] - pub bus_model: Option, - #[serde(rename = "DOCKED_WITH")] - pub docked_with: Option, - #[serde(rename = "DRAG_CONST_AREA")] - pub drag_const_area: Option, - #[serde(rename = "DRAG_COEFF_NOM")] - pub drag_coeff_nom: Option, - #[serde(rename = "DRAG_UNCERTAINTY")] - pub drag_uncertainty: Option, - #[serde(rename = "INITIAL_WET_MASS")] - pub initial_wet_mass: Option, - #[serde(rename = "WET_MASS")] - pub wet_mass: Option, - #[serde(rename = "DRY_MASS")] - pub dry_mass: Option, - #[serde(rename = "OEB_PARENT_FRAME")] - pub oeb_parent_frame: Option, - #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] - pub oeb_parent_frame_epoch: Option, - #[serde(rename = "OEB_Q1")] - pub oeb_q1: Option, - #[serde(rename = "OEB_Q2")] - pub oeb_q2: Option, - #[serde(rename = "OEB_Q3")] - pub oeb_q3: Option, - #[serde(rename = "OEB_QC")] - pub oeb_qc: Option, - #[serde(rename = "OEB_MAX")] - pub oeb_max: Option, - #[serde(rename = "OEB_INT")] - pub oeb_int: Option, - #[serde(rename = "OEB_MIN")] - pub oeb_min: Option, - #[serde(rename = "AREA_ALONG_OEB_MAX")] - pub area_along_oeb_max: Option, - #[serde(rename = "AREA_ALONG_OEB_INT")] - pub area_along_oeb_int: Option, - #[serde(rename = "AREA_ALONG_OEB_MIN")] - pub area_along_oeb_min: Option, - #[serde(rename = "AREA_MIN_FOR_PC")] - pub area_min_for_pc: Option, - #[serde(rename = "AREA_MAX_FOR_PC")] - pub area_max_for_pc: Option, - #[serde(rename = "AREA_TYP_FOR_PC")] - pub area_typ_for_pc: Option, - #[serde(rename = "RCS")] - pub rcs: Option, - #[serde(rename = "RCS_MIN")] - pub rcs_min: Option, - #[serde(rename = "RCS_MAX")] - pub rcs_max: Option, - #[serde(rename = "SRP_CONST_AREA")] - pub srp_const_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] - pub solar_rad_uncertainty: Option, - #[serde(rename = "VM_ABSOLUTE")] - pub vm_absolute: Option, - #[serde(rename = "VM_APPARENT_MIN")] - pub vm_apparent_min: Option, - #[serde(rename = "VM_APPARENT")] - pub vm_apparent: Option, - #[serde(rename = "VM_APPARENT_MAX")] - pub vm_apparent_max: Option, - #[serde(rename = "REFLECTANCE")] - pub reflectance: Option, - #[serde(rename = "ATT_CONTROL_MODE")] - pub att_control_mode: Option, - #[serde(rename = "ATT_ACTUATOR_TYPE")] - pub att_actuator_type: Option, - #[serde(rename = "ATT_KNOWLEDGE")] - pub att_knowledge: Option, - #[serde(rename = "ATT_CONTROL")] - pub att_control: Option, - #[serde(rename = "ATT_POINTING")] - pub att_pointing: Option, - #[serde(rename = "AVG_MANEUVER_FREQ")] - pub avg_maneuver_freq: Option, - #[serde(rename = "MAX_THRUST")] - pub max_thrust: Option, - #[serde(rename = "DV_BOL")] - pub dv_bol: Option, - #[serde(rename = "DV_REMAINING")] - pub dv_remaining: Option, - #[serde(rename = "IXX")] - pub ixx: Option, - #[serde(rename = "IYY")] - pub iyy: Option, - #[serde(rename = "IZZ")] - pub izz: Option, - #[serde(rename = "IXY")] - pub ixy: Option, - #[serde(rename = "IXZ")] - pub ixz: Option, - #[serde(rename = "IYZ")] - pub iyz: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmTrajStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TRAJ_ID")] + pub traj_id: Option, + #[serde(rename = "TRAJ_PREV_ID")] + pub traj_prev_id: Option, + #[serde(rename = "TRAJ_NEXT_ID")] + pub traj_next_id: Option, + #[serde(rename = "TRAJ_BASIS")] + pub traj_basis: Option, + #[serde(rename = "TRAJ_BASIS_ID")] + pub traj_basis_id: Option, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, + #[serde(rename = "PROPAGATOR")] + pub propagator: Option, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "TRAJ_REF_FRAME")] + pub traj_ref_frame: String, + #[serde(rename = "TRAJ_FRAME_EPOCH")] + pub traj_frame_epoch: Option, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "ORB_REVNUM")] + pub orb_revnum: Option, + #[serde(rename = "ORB_REVNUM_BASIS")] + pub orb_revnum_basis: Option, + #[serde(rename = "TRAJ_TYPE")] + pub traj_type: String, + #[serde(rename = "ORB_AVERAGING")] + pub orb_averaging: Option, + #[serde(rename = "TRAJ_UNITS")] + pub traj_units: Option, + #[serde(rename = "trajLine")] + pub traj_line_list: Vec, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmCovarianceMatrixType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "COV_ID")] - pub cov_id: Option, - #[serde(rename = "COV_PREV_ID")] - pub cov_prev_id: Option, - #[serde(rename = "COV_NEXT_ID")] - pub cov_next_id: Option, - #[serde(rename = "COV_BASIS")] - pub cov_basis: Option, - #[serde(rename = "COV_BASIS_ID")] - pub cov_basis_id: Option, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: String, - #[serde(rename = "COV_FRAME_EPOCH")] - pub cov_frame_epoch: Option, - #[serde(rename = "COV_SCALE_MIN")] - pub cov_scale_min: Option, - #[serde(rename = "COV_SCALE_MAX")] - pub cov_scale_max: Option, - #[serde(rename = "COV_CONFIDENCE")] - pub cov_confidence: Option, - #[serde(rename = "COV_TYPE")] - pub cov_type: String, - #[serde(rename = "COV_ORDERING")] - pub cov_ordering: schema_common::xml_schema_types::CovOrderType, - #[serde(rename = "COV_UNITS")] - pub cov_units: Option, - #[serde(rename = "covLine")] - pub cov_line_list: Vec, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmPhysicalDescriptionType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MANUFACTURER")] + pub manufacturer: Option, + #[serde(rename = "BUS_MODEL")] + pub bus_model: Option, + #[serde(rename = "DOCKED_WITH")] + pub docked_with: Option, + #[serde(rename = "DRAG_CONST_AREA")] + pub drag_const_area: Option, + #[serde(rename = "DRAG_COEFF_NOM")] + pub drag_coeff_nom: Option, + #[serde(rename = "DRAG_UNCERTAINTY")] + pub drag_uncertainty: Option, + #[serde(rename = "INITIAL_WET_MASS")] + pub initial_wet_mass: Option, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "OEB_PARENT_FRAME")] + pub oeb_parent_frame: Option, + #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] + pub oeb_parent_frame_epoch: Option, + #[serde(rename = "OEB_Q1")] + pub oeb_q1: Option, + #[serde(rename = "OEB_Q2")] + pub oeb_q2: Option, + #[serde(rename = "OEB_Q3")] + pub oeb_q3: Option, + #[serde(rename = "OEB_QC")] + pub oeb_qc: Option, + #[serde(rename = "OEB_MAX")] + pub oeb_max: Option, + #[serde(rename = "OEB_INT")] + pub oeb_int: Option, + #[serde(rename = "OEB_MIN")] + pub oeb_min: Option, + #[serde(rename = "AREA_ALONG_OEB_MAX")] + pub area_along_oeb_max: Option, + #[serde(rename = "AREA_ALONG_OEB_INT")] + pub area_along_oeb_int: Option, + #[serde(rename = "AREA_ALONG_OEB_MIN")] + pub area_along_oeb_min: Option, + #[serde(rename = "AREA_MIN_FOR_PC")] + pub area_min_for_pc: Option, + #[serde(rename = "AREA_MAX_FOR_PC")] + pub area_max_for_pc: Option, + #[serde(rename = "AREA_TYP_FOR_PC")] + pub area_typ_for_pc: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "RCS_MIN")] + pub rcs_min: Option, + #[serde(rename = "RCS_MAX")] + pub rcs_max: Option, + #[serde(rename = "SRP_CONST_AREA")] + pub srp_const_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] + pub solar_rad_uncertainty: Option, + #[serde(rename = "VM_ABSOLUTE")] + pub vm_absolute: Option, + #[serde(rename = "VM_APPARENT_MIN")] + pub vm_apparent_min: Option, + #[serde(rename = "VM_APPARENT")] + pub vm_apparent: Option, + #[serde(rename = "VM_APPARENT_MAX")] + pub vm_apparent_max: Option, + #[serde(rename = "REFLECTANCE")] + pub reflectance: Option, + #[serde(rename = "ATT_CONTROL_MODE")] + pub att_control_mode: Option, + #[serde(rename = "ATT_ACTUATOR_TYPE")] + pub att_actuator_type: Option, + #[serde(rename = "ATT_KNOWLEDGE")] + pub att_knowledge: Option, + #[serde(rename = "ATT_CONTROL")] + pub att_control: Option, + #[serde(rename = "ATT_POINTING")] + pub att_pointing: Option, + #[serde(rename = "AVG_MANEUVER_FREQ")] + pub avg_maneuver_freq: Option, + #[serde(rename = "MAX_THRUST")] + pub max_thrust: Option, + #[serde(rename = "DV_BOL")] + pub dv_bol: Option, + #[serde(rename = "DV_REMAINING")] + pub dv_remaining: Option, + #[serde(rename = "IXX")] + pub ixx: Option, + #[serde(rename = "IYY")] + pub iyy: Option, + #[serde(rename = "IZZ")] + pub izz: Option, + #[serde(rename = "IXY")] + pub ixy: Option, + #[serde(rename = "IXZ")] + pub ixz: Option, + #[serde(rename = "IYZ")] + pub iyz: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmManeuverParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MAN_ID")] - pub man_id: String, - #[serde(rename = "MAN_PREV_ID")] - pub man_prev_id: Option, - #[serde(rename = "MAN_NEXT_ID")] - pub man_next_id: Option, - #[serde(rename = "MAN_BASIS")] - pub man_basis: Option, - #[serde(rename = "MAN_BASIS_ID")] - pub man_basis_id: Option, - #[serde(rename = "MAN_DEVICE_ID")] - pub man_device_id: String, - #[serde(rename = "MAN_PREV_EPOCH")] - pub man_prev_epoch: Option, - #[serde(rename = "MAN_NEXT_EPOCH")] - pub man_next_epoch: Option, - #[serde(rename = "MAN_PURPOSE")] - pub man_purpose: Option, - #[serde(rename = "MAN_PRED_SOURCE")] - pub man_pred_source: Option, - #[serde(rename = "MAN_REF_FRAME")] - pub man_ref_frame: String, - #[serde(rename = "MAN_FRAME_EPOCH")] - pub man_frame_epoch: Option, - #[serde(rename = "GRAV_ASSIST_NAME")] - pub grav_assist_name: Option, - #[serde(rename = "DC_TYPE")] - pub dc_type: schema_common::xml_schema_types::ManDcType, - #[serde(rename = "DC_WIN_OPEN")] - pub dc_win_open: Option, - #[serde(rename = "DC_WIN_CLOSE")] - pub dc_win_close: Option, - #[serde(rename = "DC_MIN_CYCLES")] - pub dc_min_cycles: Option, - #[serde(rename = "DC_MAX_CYCLES")] - pub dc_max_cycles: Option, - #[serde(rename = "DC_EXEC_START")] - pub dc_exec_start: Option, - #[serde(rename = "DC_EXEC_STOP")] - pub dc_exec_stop: Option, - #[serde(rename = "DC_REF_TIME")] - pub dc_ref_time: Option, - #[serde(rename = "DC_TIME_PULSE_DURATION")] - pub dc_time_pulse_duration: Option, - #[serde(rename = "DC_TIME_PULSE_PERIOD")] - pub dc_time_pulse_period: Option, - #[serde(rename = "DC_REF_DIR")] - pub dc_ref_dir: Option, - #[serde(rename = "DC_BODY_FRAME")] - pub dc_body_frame: Option, - #[serde(rename = "DC_BODY_TRIGGER")] - pub dc_body_trigger: Option, - #[serde(rename = "DC_PA_START_ANGLE")] - pub dc_pa_start_angle: Option, - #[serde(rename = "DC_PA_STOP_ANGLE")] - pub dc_pa_stop_angle: Option, - #[serde(rename = "MAN_COMPOSITION")] - pub man_composition: String, - #[serde(rename = "MAN_UNITS")] - pub man_units: Option, - #[serde(rename = "manLine")] - pub man_line_list: Vec, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmCovarianceMatrixType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_ID")] + pub cov_id: Option, + #[serde(rename = "COV_PREV_ID")] + pub cov_prev_id: Option, + #[serde(rename = "COV_NEXT_ID")] + pub cov_next_id: Option, + #[serde(rename = "COV_BASIS")] + pub cov_basis: Option, + #[serde(rename = "COV_BASIS_ID")] + pub cov_basis_id: Option, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: String, + #[serde(rename = "COV_FRAME_EPOCH")] + pub cov_frame_epoch: Option, + #[serde(rename = "COV_SCALE_MIN")] + pub cov_scale_min: Option, + #[serde(rename = "COV_SCALE_MAX")] + pub cov_scale_max: Option, + #[serde(rename = "COV_CONFIDENCE")] + pub cov_confidence: Option, + #[serde(rename = "COV_TYPE")] + pub cov_type: String, + #[serde(rename = "COV_ORDERING")] + pub cov_ordering: common::CovOrderType, + #[serde(rename = "COV_UNITS")] + pub cov_units: Option, + #[serde(rename = "covLine")] + pub cov_line_list: Vec, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmPerturbationsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "ATMOSPHERIC_MODEL")] - pub atmospheric_model: Option, - #[serde(rename = "GRAVITY_MODEL")] - pub gravity_model: Option, - #[serde(rename = "EQUATORIAL_RADIUS")] - pub equatorial_radius: Option, - #[serde(rename = "GM")] - pub gm: Option, - #[serde(rename = "N_BODY_PERTURBATIONS")] - pub n_body_perturbations: Option, - #[serde(rename = "CENTRAL_BODY_ROTATION")] - pub central_body_rotation: Option, - #[serde(rename = "OBLATE_FLATTENING")] - pub oblate_flattening: Option, - #[serde(rename = "OCEAN_TIDES_MODEL")] - pub ocean_tides_model: Option, - #[serde(rename = "SOLID_TIDES_MODEL")] - pub solid_tides_model: Option, - #[serde(rename = "REDUCTION_THEORY")] - pub reduction_theory: Option, - #[serde(rename = "ALBEDO_MODEL")] - pub albedo_model: Option, - #[serde(rename = "ALBEDO_GRID_SIZE")] - pub albedo_grid_size: Option, - #[serde(rename = "SHADOW_MODEL")] - pub shadow_model: Option, - #[serde(rename = "SHADOW_BODIES")] - pub shadow_bodies: Option, - #[serde(rename = "SRP_MODEL")] - pub srp_model: Option, - #[serde(rename = "SW_DATA_SOURCE")] - pub sw_data_source: Option, - #[serde(rename = "SW_DATA_EPOCH")] - pub sw_data_epoch: Option, - #[serde(rename = "SW_INTERP_METHOD")] - pub sw_interp_method: Option, - #[serde(rename = "FIXED_GEOMAG_KP")] - pub fixed_geomag_kp: Option, - #[serde(rename = "FIXED_GEOMAG_AP")] - pub fixed_geomag_ap: Option, - #[serde(rename = "FIXED_GEOMAG_DST")] - pub fixed_geomag_dst: Option, - #[serde(rename = "FIXED_F10P7")] - pub fixed_f10p7: Option, - #[serde(rename = "FIXED_F10P7_MEAN")] - pub fixed_f10p7_mean: Option, - #[serde(rename = "FIXED_M10P7")] - pub fixed_m10p7: Option, - #[serde(rename = "FIXED_M10P7_MEAN")] - pub fixed_m10p7_mean: Option, - #[serde(rename = "FIXED_S10P7")] - pub fixed_s10p7: Option, - #[serde(rename = "FIXED_S10P7_MEAN")] - pub fixed_s10p7_mean: Option, - #[serde(rename = "FIXED_Y10P7")] - pub fixed_y10p7: Option, - #[serde(rename = "FIXED_Y10P7_MEAN")] - pub fixed_y10p7_mean: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_ID")] + pub man_id: String, + #[serde(rename = "MAN_PREV_ID")] + pub man_prev_id: Option, + #[serde(rename = "MAN_NEXT_ID")] + pub man_next_id: Option, + #[serde(rename = "MAN_BASIS")] + pub man_basis: Option, + #[serde(rename = "MAN_BASIS_ID")] + pub man_basis_id: Option, + #[serde(rename = "MAN_DEVICE_ID")] + pub man_device_id: String, + #[serde(rename = "MAN_PREV_EPOCH")] + pub man_prev_epoch: Option, + #[serde(rename = "MAN_NEXT_EPOCH")] + pub man_next_epoch: Option, + #[serde(rename = "MAN_PURPOSE")] + pub man_purpose: Option, + #[serde(rename = "MAN_PRED_SOURCE")] + pub man_pred_source: Option, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_FRAME_EPOCH")] + pub man_frame_epoch: Option, + #[serde(rename = "GRAV_ASSIST_NAME")] + pub grav_assist_name: Option, + #[serde(rename = "DC_TYPE")] + pub dc_type: common::ManDcType, + #[serde(rename = "DC_WIN_OPEN")] + pub dc_win_open: Option, + #[serde(rename = "DC_WIN_CLOSE")] + pub dc_win_close: Option, + #[serde(rename = "DC_MIN_CYCLES")] + pub dc_min_cycles: Option, + #[serde(rename = "DC_MAX_CYCLES")] + pub dc_max_cycles: Option, + #[serde(rename = "DC_EXEC_START")] + pub dc_exec_start: Option, + #[serde(rename = "DC_EXEC_STOP")] + pub dc_exec_stop: Option, + #[serde(rename = "DC_REF_TIME")] + pub dc_ref_time: Option, + #[serde(rename = "DC_TIME_PULSE_DURATION")] + pub dc_time_pulse_duration: Option, + #[serde(rename = "DC_TIME_PULSE_PERIOD")] + pub dc_time_pulse_period: Option, + #[serde(rename = "DC_REF_DIR")] + pub dc_ref_dir: Option, + #[serde(rename = "DC_BODY_FRAME")] + pub dc_body_frame: Option, + #[serde(rename = "DC_BODY_TRIGGER")] + pub dc_body_trigger: Option, + #[serde(rename = "DC_PA_START_ANGLE")] + pub dc_pa_start_angle: Option, + #[serde(rename = "DC_PA_STOP_ANGLE")] + pub dc_pa_stop_angle: Option, + #[serde(rename = "MAN_COMPOSITION")] + pub man_composition: String, + #[serde(rename = "MAN_UNITS")] + pub man_units: Option, + #[serde(rename = "manLine")] + pub man_line_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmPerturbationsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ATMOSPHERIC_MODEL")] + pub atmospheric_model: Option, + #[serde(rename = "GRAVITY_MODEL")] + pub gravity_model: Option, + #[serde(rename = "EQUATORIAL_RADIUS")] + pub equatorial_radius: Option, + #[serde(rename = "GM")] + pub gm: Option, + #[serde(rename = "N_BODY_PERTURBATIONS")] + pub n_body_perturbations: Option, + #[serde(rename = "CENTRAL_BODY_ROTATION")] + pub central_body_rotation: Option, + #[serde(rename = "OBLATE_FLATTENING")] + pub oblate_flattening: Option, + #[serde(rename = "OCEAN_TIDES_MODEL")] + pub ocean_tides_model: Option, + #[serde(rename = "SOLID_TIDES_MODEL")] + pub solid_tides_model: Option, + #[serde(rename = "REDUCTION_THEORY")] + pub reduction_theory: Option, + #[serde(rename = "ALBEDO_MODEL")] + pub albedo_model: Option, + #[serde(rename = "ALBEDO_GRID_SIZE")] + pub albedo_grid_size: Option, + #[serde(rename = "SHADOW_MODEL")] + pub shadow_model: Option, + #[serde(rename = "SHADOW_BODIES")] + pub shadow_bodies: Option, + #[serde(rename = "SRP_MODEL")] + pub srp_model: Option, + #[serde(rename = "SW_DATA_SOURCE")] + pub sw_data_source: Option, + #[serde(rename = "SW_DATA_EPOCH")] + pub sw_data_epoch: Option, + #[serde(rename = "SW_INTERP_METHOD")] + pub sw_interp_method: Option, + #[serde(rename = "FIXED_GEOMAG_KP")] + pub fixed_geomag_kp: Option, + #[serde(rename = "FIXED_GEOMAG_AP")] + pub fixed_geomag_ap: Option, + #[serde(rename = "FIXED_GEOMAG_DST")] + pub fixed_geomag_dst: Option, + #[serde(rename = "FIXED_F10P7")] + pub fixed_f10p7: Option, + #[serde(rename = "FIXED_F10P7_MEAN")] + pub fixed_f10p7_mean: Option, + #[serde(rename = "FIXED_M10P7")] + pub fixed_m10p7: Option, + #[serde(rename = "FIXED_M10P7_MEAN")] + pub fixed_m10p7_mean: Option, + #[serde(rename = "FIXED_S10P7")] + pub fixed_s10p7: Option, + #[serde(rename = "FIXED_S10P7_MEAN")] + pub fixed_s10p7_mean: Option, + #[serde(rename = "FIXED_Y10P7")] + pub fixed_y10p7: Option, + #[serde(rename = "FIXED_Y10P7_MEAN")] + pub fixed_y10p7_mean: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OcmOdParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OD_ID")] - pub od_id: String, - #[serde(rename = "OD_PREV_ID")] - pub od_prev_id: Option, - #[serde(rename = "OD_METHOD")] - pub od_method: String, - #[serde(rename = "OD_EPOCH")] - pub od_epoch: schema_common::xml_schema_types::EpochType, - #[serde(rename = "DAYS_SINCE_FIRST_OBS")] - pub days_since_first_obs: Option, - #[serde(rename = "DAYS_SINCE_LAST_OBS")] - pub days_since_last_obs: Option, - #[serde(rename = "RECOMMENDED_OD_SPAN")] - pub recommended_od_span: Option, - #[serde(rename = "ACTUAL_OD_SPAN")] - pub actual_od_span: Option, - #[serde(rename = "OBS_AVAILABLE")] - pub obs_available: Option, - #[serde(rename = "OBS_USED")] - pub obs_used: Option, - #[serde(rename = "TRACKS_AVAILABLE")] - pub tracks_available: Option, - #[serde(rename = "TRACKS_USED")] - pub tracks_used: Option, - #[serde(rename = "MAXIMUM_OBS_GAP")] - pub maximum_obs_gap: Option, - #[serde(rename = "OD_EPOCH_EIGMAJ")] - pub od_epoch_eigmaj: Option, - #[serde(rename = "OD_EPOCH_EIGINT")] - pub od_epoch_eigint: Option, - #[serde(rename = "OD_EPOCH_EIGMIN")] - pub od_epoch_eigmin: Option, - #[serde(rename = "OD_MAX_PRED_EIGMAJ")] - pub od_max_pred_eigmaj: Option, - #[serde(rename = "OD_MIN_PRED_EIGMIN")] - pub od_min_pred_eigmin: Option, - #[serde(rename = "OD_CONFIDENCE")] - pub od_confidence: Option, - #[serde(rename = "GDOP")] - pub gdop: Option, - #[serde(rename = "SOLVE_N")] - pub solve_n: Option, - #[serde(rename = "SOLVE_STATES")] - pub solve_states: Option, - #[serde(rename = "CONSIDER_N")] - pub consider_n: Option, - #[serde(rename = "CONSIDER_PARAMS")] - pub consider_params: Option, - #[serde(rename = "SEDR")] - pub sedr: Option, - #[serde(rename = "SENSORS_N")] - pub sensors_n: Option, - #[serde(rename = "SENSORS")] - pub sensors: Option, - #[serde(rename = "WEIGHTED_RMS")] - pub weighted_rms: Option, - #[serde(rename = "DATA_TYPES")] - pub data_types: Option, - } - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmOdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OD_ID")] + pub od_id: String, + #[serde(rename = "OD_PREV_ID")] + pub od_prev_id: Option, + #[serde(rename = "OD_METHOD")] + pub od_method: String, + #[serde(rename = "OD_EPOCH")] + pub od_epoch: common::EpochType, + #[serde(rename = "DAYS_SINCE_FIRST_OBS")] + pub days_since_first_obs: Option, + #[serde(rename = "DAYS_SINCE_LAST_OBS")] + pub days_since_last_obs: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "MAXIMUM_OBS_GAP")] + pub maximum_obs_gap: Option, + #[serde(rename = "OD_EPOCH_EIGMAJ")] + pub od_epoch_eigmaj: Option, + #[serde(rename = "OD_EPOCH_EIGINT")] + pub od_epoch_eigint: Option, + #[serde(rename = "OD_EPOCH_EIGMIN")] + pub od_epoch_eigmin: Option, + #[serde(rename = "OD_MAX_PRED_EIGMAJ")] + pub od_max_pred_eigmaj: Option, + #[serde(rename = "OD_MIN_PRED_EIGMIN")] + pub od_min_pred_eigmin: Option, + #[serde(rename = "OD_CONFIDENCE")] + pub od_confidence: Option, + #[serde(rename = "GDOP")] + pub gdop: Option, + #[serde(rename = "SOLVE_N")] + pub solve_n: Option, + #[serde(rename = "SOLVE_STATES")] + pub solve_states: Option, + #[serde(rename = "CONSIDER_N")] + pub consider_n: Option, + #[serde(rename = "CONSIDER_PARAMS")] + pub consider_params: Option, + #[serde(rename = "SEDR")] + pub sedr: Option, + #[serde(rename = "SENSORS_N")] + pub sensors_n: Option, + #[serde(rename = "SENSORS")] + pub sensors: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, + #[serde(rename = "DATA_TYPES")] + pub data_types: Option, } -pub use schema_ocm::*; diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index 2b65982f..e37c4aa7 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -1,76 +1,72 @@ -mod schema_oem { - pub mod xml_schema_types { - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemType { - #[serde(rename = "header")] - pub header: schema_common::xml_schema_types::OdmHeader, - #[serde(rename = "body")] - pub body: schema_common::xml_schema_types::OemBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, - } +use super::common; - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemBody { - #[serde(rename = "segment")] - pub segment_list: Vec, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: common::OemBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemSegment { - #[serde(rename = "metadata")] - pub metadata: schema_common::xml_schema_types::OemMetadata, - #[serde(rename = "data")] - pub data: schema_common::xml_schema_types::OemData, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemBody { + #[serde(rename = "segment")] + pub segment_list: Vec, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "START_TIME")] - pub start_time: schema_common::xml_schema_types::EpochType, - #[serde(rename = "USEABLE_START_TIME")] - pub useable_start_time: Option, - #[serde(rename = "USEABLE_STOP_TIME")] - pub useable_stop_time: Option, - #[serde(rename = "STOP_TIME")] - pub stop_time: schema_common::xml_schema_types::EpochType, - #[serde(rename = "INTERPOLATION")] - pub interpolation: Option, - #[serde(rename = "INTERPOLATION_DEGREE")] - pub interpolation_degree: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemSegment { + #[serde(rename = "metadata")] + pub metadata: common::OemMetadata, + #[serde(rename = "data")] + pub data: common::OemData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "START_TIME")] + pub start_time: common::EpochType, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: common::EpochType, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OemData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "stateVector")] - pub state_vector_list: Vec, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix_list: - Vec, - } - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector_list: Vec, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix_list: Vec, } -pub use schema_oem::*; diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index fdf49c05..28d36c67 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1,198 +1,194 @@ -mod schema_omm { - pub mod xml_schema_types { - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BStarUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BTermUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AgomUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ElementSetNoType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RevUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DRevUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DdRevUnits(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct SpacewarnType(#[serde(rename = "$text")] std::string::String); - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OmmType { - #[serde(rename = "header")] - pub header: schema_common::xml_schema_types::OdmHeader, - #[serde(rename = "body")] - pub body: schema_common::xml_schema_types::OmmBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OmmBody { - #[serde(rename = "segment")] - pub segment: schema_common::xml_schema_types::OmmSegment, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OmmSegment { - #[serde(rename = "metadata")] - pub metadata: schema_common::xml_schema_types::OmmMetadata, - #[serde(rename = "data")] - pub data: schema_common::xml_schema_types::OmmData, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OmmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "MEAN_ELEMENT_THEORY")] - pub mean_element_theory: String, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OmmData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "meanElements")] - pub mean_elements: schema_common::xml_schema_types::MeanElementsType, - #[serde(rename = "spacecraftParameters")] - pub spacecraft_parameters: - Option, - #[serde(rename = "tleParameters")] - pub tle_parameters: Option, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix: Option, - #[serde(rename = "userDefinedParameters")] - pub user_defined_parameters: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct MeanElementsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: schema_common::xml_schema_types::EpochType, - #[serde(rename = "ECCENTRICITY")] - pub eccentricity: schema_common::xml_schema_types::NonNegativeDouble, - #[serde(rename = "INCLINATION")] - pub inclination: schema_common::xml_schema_types::InclinationType, - #[serde(rename = "RA_OF_ASC_NODE")] - pub ra_of_asc_node: schema_common::xml_schema_types::AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] - pub arg_of_pericenter: schema_common::xml_schema_types::AngleType, - #[serde(rename = "MEAN_ANOMALY")] - pub mean_anomaly: schema_common::xml_schema_types::AngleType, - #[serde(rename = "GM")] - pub gm: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct TleParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPHEMERIS_TYPE")] - pub ephemeris_type: Option, - #[serde(rename = "CLASSIFICATION_TYPE")] - pub classification_type: Option, - #[serde(rename = "NORAD_CAT_ID")] - pub norad_cat_id: Option, - #[serde(rename = "ELEMENT_SET_NO")] - pub element_set_no: Option, - #[serde(rename = "REV_AT_EPOCH")] - pub rev_at_epoch: Option, - #[serde(rename = "MEAN_MOTION_DOT")] - pub mean_motion_dot: schema_common::xml_schema_types::DRevType, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BStarType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct BTermType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct AgomType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct RevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DRevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct DdRevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, - } - } +use super::common; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BStarUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BTermUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AgomUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ElementSetNoType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DRevUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DdRevUnits(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SpacewarnType(#[serde(rename = "$text")] std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: common::OmmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmBody { + #[serde(rename = "segment")] + pub segment: common::OmmSegment, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmSegment { + #[serde(rename = "metadata")] + pub metadata: common::OmmMetadata, + #[serde(rename = "data")] + pub data: common::OmmData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "MEAN_ELEMENT_THEORY")] + pub mean_element_theory: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "meanElements")] + pub mean_elements: common::MeanElementsType, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: Option, + #[serde(rename = "tleParameters")] + pub tle_parameters: Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MeanElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: common::EpochType, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: common::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: common::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: common::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: common::AngleType, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: common::AngleType, + #[serde(rename = "GM")] + pub gm: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TleParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPHEMERIS_TYPE")] + pub ephemeris_type: Option, + #[serde(rename = "CLASSIFICATION_TYPE")] + pub classification_type: Option, + #[serde(rename = "NORAD_CAT_ID")] + pub norad_cat_id: Option, + #[serde(rename = "ELEMENT_SET_NO")] + pub element_set_no: Option, + #[serde(rename = "REV_AT_EPOCH")] + pub rev_at_epoch: Option, + #[serde(rename = "MEAN_MOTION_DOT")] + pub mean_motion_dot: common::DRevType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BStarType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BTermType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AgomType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DdRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, } -pub use schema_omm::*; diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 7145dd30..8e26bcce 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -1,113 +1,108 @@ -mod schema_opm { - pub mod xml_schema_types { - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmType { - #[serde(rename = "header")] - pub header: schema_common::xml_schema_types::OdmHeader, - #[serde(rename = "body")] - pub body: schema_common::xml_schema_types::OpmBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, - } +use super::common; - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmBody { - #[serde(rename = "segment")] - pub segment: schema_common::xml_schema_types::OpmSegment, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: common::OpmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmSegment { - #[serde(rename = "metadata")] - pub metadata: schema_common::xml_schema_types::OpmMetadata, - #[serde(rename = "data")] - pub data: schema_common::xml_schema_types::OpmData, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmBody { + #[serde(rename = "segment")] + pub segment: common::OpmSegment, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmSegment { + #[serde(rename = "metadata")] + pub metadata: common::OpmMetadata, + #[serde(rename = "data")] + pub data: common::OpmData, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct OpmData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "stateVector")] - pub state_vector: schema_common::xml_schema_types::StateVectorType, - #[serde(rename = "keplerianElements")] - pub keplerian_elements: Option, - #[serde(rename = "spacecraftParameters")] - pub spacecraft_parameters: - Option, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix: Option, - #[serde(rename = "maneuverParameters")] - pub maneuver_parameters_list: - Vec, - #[serde(rename = "userDefinedParameters")] - pub user_defined_parameters: Option, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct KeplerianElementsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "SEMI_MAJOR_AXIS")] - pub semi_major_axis: schema_common::xml_schema_types::DistanceType, - #[serde(rename = "ECCENTRICITY")] - pub eccentricity: schema_common::xml_schema_types::NonNegativeDouble, - #[serde(rename = "INCLINATION")] - pub inclination: schema_common::xml_schema_types::InclinationType, - #[serde(rename = "RA_OF_ASC_NODE")] - pub ra_of_asc_node: schema_common::xml_schema_types::AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] - pub arg_of_pericenter: schema_common::xml_schema_types::AngleType, - #[serde(rename = "GM")] - pub gm: schema_common::xml_schema_types::GmType, - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector: common::StateVectorType, + #[serde(rename = "keplerianElements")] + pub keplerian_elements: Option, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "maneuverParameters")] + pub maneuver_parameters_list: Vec, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct KeplerianElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: common::DistanceType, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: common::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: common::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: common::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: common::AngleType, + #[serde(rename = "GM")] + pub gm: common::GmType, +} - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] - #[serde(default)] - pub struct ManeuverParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MAN_EPOCH_IGNITION")] - pub man_epoch_ignition: schema_common::xml_schema_types::EpochType, - #[serde(rename = "MAN_DURATION")] - pub man_duration: schema_common::xml_schema_types::DurationType, - #[serde(rename = "MAN_DELTA_MASS")] - pub man_delta_mass: schema_common::xml_schema_types::DeltamassType, - #[serde(rename = "MAN_REF_FRAME")] - pub man_ref_frame: String, - #[serde(rename = "MAN_DV_1")] - pub man_dv_1: schema_common::xml_schema_types::VelocityType, - #[serde(rename = "MAN_DV_2")] - pub man_dv_2: schema_common::xml_schema_types::VelocityType, - #[serde(rename = "MAN_DV_3")] - pub man_dv_3: schema_common::xml_schema_types::VelocityType, - } - } +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_EPOCH_IGNITION")] + pub man_epoch_ignition: common::EpochType, + #[serde(rename = "MAN_DURATION")] + pub man_duration: common::DurationType, + #[serde(rename = "MAN_DELTA_MASS")] + pub man_delta_mass: common::DeltamassType, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_DV_1")] + pub man_dv_1: common::VelocityType, + #[serde(rename = "MAN_DV_2")] + pub man_dv_2: common::VelocityType, + #[serde(rename = "MAN_DV_3")] + pub man_dv_3: common::VelocityType, } -pub use schema_opm::*; From 37845c7b4c7cef4f600d67babc869f6b95a842da Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 18:07:35 +0100 Subject: [PATCH 004/150] Fix imports --- crates/lox-utils/Cargo.toml | 2 ++ crates/lox-utils/src/odm/common.rs | 2 ++ crates/lox-utils/src/odm/ocm.rs | 2 ++ crates/lox-utils/src/odm/oem.rs | 2 ++ crates/lox-utils/src/odm/omm.rs | 2 ++ crates/lox-utils/src/odm/opm.rs | 2 ++ 6 files changed, 12 insertions(+) diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 06d785ec..96ee6f7a 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [dependencies] fast_polynomial.workspace = true thiserror.workspace = true +quick-xml = { version = "0.31.0", features = ["serde"] } +serde = { version = "1.0.194", features = ["serde_derive"] } [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 565b287b..dbbea4e8 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -1,3 +1,5 @@ +use serde; + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct AccUnits(#[serde(rename = "$text")] std::string::String); diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index b146370c..6d72be4b 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -1,3 +1,5 @@ +use serde; + use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index e37c4aa7..cee5a5dc 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -1,3 +1,5 @@ +use serde; + use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 28d36c67..3a4444f6 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1,3 +1,5 @@ +use serde; + use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 8e26bcce..140e47f3 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -1,3 +1,5 @@ +use serde; + use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] From 04e00e67b93ac6db5d59f2cae1f6dedbae9561de Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 18:26:35 +0100 Subject: [PATCH 005/150] Fix type namespaces --- crates/lox-utils/src/odm/ocm.rs | 20 ++++++++++---------- crates/lox-utils/src/odm/oem.rs | 8 ++++---- crates/lox-utils/src/odm/omm.rs | 28 ++++++++++++++-------------- crates/lox-utils/src/odm/opm.rs | 12 ++++++------ 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index 6d72be4b..6ab71a7f 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -8,7 +8,7 @@ pub struct OcmType { #[serde(rename = "header")] pub header: common::OdmHeader, #[serde(rename = "body")] - pub body: common::OcmBody, + pub body: OcmBody, #[serde(rename = "@id")] pub id: String, #[serde(rename = "@version")] @@ -19,16 +19,16 @@ pub struct OcmType { #[serde(default)] pub struct OcmBody { #[serde(rename = "segment")] - pub segment: common::OcmSegment, + pub segment: OcmSegment, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OcmSegment { #[serde(rename = "metadata")] - pub metadata: common::OcmMetadata, + pub metadata: OcmMetadata, #[serde(rename = "data")] - pub data: common::OcmData, + pub data: OcmData, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -136,17 +136,17 @@ pub struct OcmMetadata { #[serde(default)] pub struct OcmData { #[serde(rename = "traj")] - pub traj_list: Vec, + pub traj_list: Vec, #[serde(rename = "phys")] - pub phys: Option, + pub phys: Option, #[serde(rename = "cov")] - pub cov_list: Vec, + pub cov_list: Vec, #[serde(rename = "man")] - pub man_list: Vec, + pub man_list: Vec, #[serde(rename = "pert")] - pub pert: Option, + pub pert: Option, #[serde(rename = "od")] - pub od: Option, + pub od: Option, #[serde(rename = "user")] pub user: Option, } diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index cee5a5dc..dc0aa964 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -8,7 +8,7 @@ pub struct OemType { #[serde(rename = "header")] pub header: common::OdmHeader, #[serde(rename = "body")] - pub body: common::OemBody, + pub body: OemBody, #[serde(rename = "@id")] pub id: String, #[serde(rename = "@version")] @@ -19,16 +19,16 @@ pub struct OemType { #[serde(default)] pub struct OemBody { #[serde(rename = "segment")] - pub segment_list: Vec, + pub segment_list: Vec, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OemSegment { #[serde(rename = "metadata")] - pub metadata: common::OemMetadata, + pub metadata: OemMetadata, #[serde(rename = "data")] - pub data: common::OemData, + pub data: OemData, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 3a4444f6..efb44f12 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -40,7 +40,7 @@ pub struct OmmType { #[serde(rename = "header")] pub header: common::OdmHeader, #[serde(rename = "body")] - pub body: common::OmmBody, + pub body: OmmBody, #[serde(rename = "@id")] pub id: String, #[serde(rename = "@version")] @@ -51,16 +51,16 @@ pub struct OmmType { #[serde(default)] pub struct OmmBody { #[serde(rename = "segment")] - pub segment: common::OmmSegment, + pub segment: OmmSegment, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OmmSegment { #[serde(rename = "metadata")] - pub metadata: common::OmmMetadata, + pub metadata: OmmMetadata, #[serde(rename = "data")] - pub data: common::OmmData, + pub data: OmmData, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -90,11 +90,11 @@ pub struct OmmData { #[serde(rename = "COMMENT")] pub comment_list: Vec, #[serde(rename = "meanElements")] - pub mean_elements: common::MeanElementsType, + pub mean_elements: MeanElementsType, #[serde(rename = "spacecraftParameters")] pub spacecraft_parameters: Option, #[serde(rename = "tleParameters")] - pub tle_parameters: Option, + pub tle_parameters: Option, #[serde(rename = "covarianceMatrix")] pub covariance_matrix: Option, #[serde(rename = "userDefinedParameters")] @@ -134,11 +134,11 @@ pub struct TleParametersType { #[serde(rename = "NORAD_CAT_ID")] pub norad_cat_id: Option, #[serde(rename = "ELEMENT_SET_NO")] - pub element_set_no: Option, + pub element_set_no: Option, #[serde(rename = "REV_AT_EPOCH")] pub rev_at_epoch: Option, #[serde(rename = "MEAN_MOTION_DOT")] - pub mean_motion_dot: common::DRevType, + pub mean_motion_dot: DRevType, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -147,7 +147,7 @@ pub struct BStarType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -156,7 +156,7 @@ pub struct BTermType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -165,7 +165,7 @@ pub struct AgomType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -174,7 +174,7 @@ pub struct RevType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -183,7 +183,7 @@ pub struct DRevType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -192,5 +192,5 @@ pub struct DdRevType { #[serde(rename = "$text")] pub base: f64, #[serde(rename = "@units")] - pub units: Option, + pub units: Option, } diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 140e47f3..2abacc53 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -8,7 +8,7 @@ pub struct OpmType { #[serde(rename = "header")] pub header: common::OdmHeader, #[serde(rename = "body")] - pub body: common::OpmBody, + pub body: OpmBody, #[serde(rename = "@id")] pub id: String, #[serde(rename = "@version")] @@ -19,16 +19,16 @@ pub struct OpmType { #[serde(default)] pub struct OpmBody { #[serde(rename = "segment")] - pub segment: common::OpmSegment, + pub segment: OpmSegment, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OpmSegment { #[serde(rename = "metadata")] - pub metadata: common::OpmMetadata, + pub metadata: OpmMetadata, #[serde(rename = "data")] - pub data: common::OpmData, + pub data: OpmData, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -58,13 +58,13 @@ pub struct OpmData { #[serde(rename = "stateVector")] pub state_vector: common::StateVectorType, #[serde(rename = "keplerianElements")] - pub keplerian_elements: Option, + pub keplerian_elements: Option, #[serde(rename = "spacecraftParameters")] pub spacecraft_parameters: Option, #[serde(rename = "covarianceMatrix")] pub covariance_matrix: Option, #[serde(rename = "maneuverParameters")] - pub maneuver_parameters_list: Vec, + pub maneuver_parameters_list: Vec, #[serde(rename = "userDefinedParameters")] pub user_defined_parameters: Option, } From 48fe90f0144fda691980aeabda190ef6af736c62 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 2 Jan 2024 21:17:08 +0100 Subject: [PATCH 006/150] Remove custom list serde quick-xml handles this natively --- crates/lox-utils/src/odm/common.rs | 52 ------------------------------ 1 file changed, 52 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index dbbea4e8..9849f3e1 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -92,58 +92,6 @@ pub struct VelocityUnits(#[serde(rename = "$text")] std::string::String); pub struct VecDouble { pub items: Vec, } -impl yaserde::YaDeserialize for VecDouble { - fn deserialize( - reader: &mut yaserde::de::Deserializer, - ) -> Result { - loop { - match reader.next_event()? { - xml::reader::XmlEvent::StartElement { .. } => {} - xml::reader::XmlEvent::Characters(ref text_content) => { - let items: Vec = text_content - .split(' ') - .map(|item| item.to_owned()) - .map(|item| item.parse().unwrap()) - .collect(); - return Ok(VecDouble { items }); - } - _ => { - break; - } - } - } - Err("Unable to parse attribute".to_string()) - } -} -impl yaserde::YaSerialize for VecDouble { - fn serialize( - &self, - writer: &mut yaserde::ser::Serializer, - ) -> Result<(), String> { - let content = self - .items - .iter() - .map(|item| item.to_string()) - .collect::>() - .join(" "); - let data_event = xml::writer::XmlEvent::characters(&content); - writer.write(data_event).map_err(|e| e.to_string())?; - Ok(()) - } - fn serialize_attributes( - &self, - mut source_attributes: Vec, - mut source_namespace: xml::namespace::Namespace, - ) -> Result< - ( - Vec, - xml::namespace::Namespace, - ), - String, - > { - Ok((source_attributes, source_namespace)) - } -} #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] From b643045275565f1866aa753178aaeb55d826223f Mon Sep 17 00:00:00 2001 From: Andrei Date: Thu, 4 Jan 2024 17:57:23 +0000 Subject: [PATCH 007/150] Implement choice types --- crates/lox-utils/src/odm/omm.rs | 12 ++++++++++++ crates/lox-utils/src/odm/opm.rs | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index efb44f12..e0a68b0b 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -108,6 +108,10 @@ pub struct MeanElementsType { pub comment_list: Vec, #[serde(rename = "EPOCH")] pub epoch: common::EpochType, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: Option, + #[serde(rename = "MEAN_MOTION")] + pub mean_motion: Option, #[serde(rename = "ECCENTRICITY")] pub eccentricity: common::NonNegativeDouble, #[serde(rename = "INCLINATION")] @@ -137,8 +141,16 @@ pub struct TleParametersType { pub element_set_no: Option, #[serde(rename = "REV_AT_EPOCH")] pub rev_at_epoch: Option, + #[serde(rename = "BSTAR")] + pub bstar: Option, + #[serde(rename = "BTERM")] + pub bterm: Option, #[serde(rename = "MEAN_MOTION_DOT")] pub mean_motion_dot: DRevType, + #[serde(rename = "MEAN_MOTION_DDOT")] + pub mean_motion_ddot: Option, + #[serde(rename = "AGOM")] + pub agom: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 2abacc53..72a57bf5 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -84,6 +84,10 @@ pub struct KeplerianElementsType { pub ra_of_asc_node: common::AngleType, #[serde(rename = "ARG_OF_PERICENTER")] pub arg_of_pericenter: common::AngleType, + #[serde(rename = "TRUE_ANOMALY")] + pub true_anomaly: Option, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: Option, #[serde(rename = "GM")] pub gm: common::GmType, } From 361502efd5c1d017d546a37f02afc9ce4d35d397 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 20 Jan 2024 17:49:33 +0100 Subject: [PATCH 008/150] Add copyright headers --- crates/lox-utils/src/odm/common.rs | 8 ++++++++ crates/lox-utils/src/odm/ocm.rs | 8 ++++++++ crates/lox-utils/src/odm/oem.rs | 8 ++++++++ crates/lox-utils/src/odm/omm.rs | 10 +++++++++- crates/lox-utils/src/odm/opm.rs | 10 +++++++++- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 9849f3e1..b17a2157 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use serde; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index 6ab71a7f..f7114bcb 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use serde; use super::common; diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index dc0aa964..a5d5362c 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use serde; use super::common; diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index e0a68b0b..3b06a043 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use serde; use super::common; @@ -111,7 +119,7 @@ pub struct MeanElementsType { #[serde(rename = "SEMI_MAJOR_AXIS")] pub semi_major_axis: Option, #[serde(rename = "MEAN_MOTION")] - pub mean_motion: Option, + pub mean_motion: Option, #[serde(rename = "ECCENTRICITY")] pub eccentricity: common::NonNegativeDouble, #[serde(rename = "INCLINATION")] diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 72a57bf5..fa4ed6bc 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use serde; use super::common; @@ -87,7 +95,7 @@ pub struct KeplerianElementsType { #[serde(rename = "TRUE_ANOMALY")] pub true_anomaly: Option, #[serde(rename = "MEAN_ANOMALY")] - pub mean_anomaly: Option, + pub mean_anomaly: Option, #[serde(rename = "GM")] pub gm: common::GmType, } From a3f8ffd392613b0cc36bf02d9bd63b1e23d820d2 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 21 Jan 2024 11:46:32 +0100 Subject: [PATCH 009/150] Patch out wrong type refs --- crates/lox-utils/src/odm/omm.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 3b06a043..dca93db0 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -119,7 +119,7 @@ pub struct MeanElementsType { #[serde(rename = "SEMI_MAJOR_AXIS")] pub semi_major_axis: Option, #[serde(rename = "MEAN_MOTION")] - pub mean_motion: Option, + pub mean_motion: Option, #[serde(rename = "ECCENTRICITY")] pub eccentricity: common::NonNegativeDouble, #[serde(rename = "INCLINATION")] @@ -150,15 +150,15 @@ pub struct TleParametersType { #[serde(rename = "REV_AT_EPOCH")] pub rev_at_epoch: Option, #[serde(rename = "BSTAR")] - pub bstar: Option, + pub bstar: Option, #[serde(rename = "BTERM")] - pub bterm: Option, + pub bterm: Option, #[serde(rename = "MEAN_MOTION_DOT")] pub mean_motion_dot: DRevType, #[serde(rename = "MEAN_MOTION_DDOT")] - pub mean_motion_ddot: Option, + pub mean_motion_ddot: Option, #[serde(rename = "AGOM")] - pub agom: Option, + pub agom: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] From b0a36d57ce50d9a2c83c4103f9509c2b2a7d9a6f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 21 Jan 2024 23:27:53 +0100 Subject: [PATCH 010/150] Make field publicly editable --- crates/lox-utils/src/odm/common.rs | 134 ++++++++++++++--------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index b17a2157..43187225 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -10,91 +10,91 @@ use serde; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AccUnits(#[serde(rename = "$text")] std::string::String); +pub struct AccUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleUnits(#[serde(rename = "$text")] std::string::String); +pub struct AngleUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRange(#[serde(rename = "$text")] std::string::String); +pub struct AngleRange(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateUnits(#[serde(rename = "$text")] std::string::String); +pub struct AngleRateUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngMomentumUnits(#[serde(rename = "$text")] std::string::String); +pub struct AngMomentumUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngVelFrameType(#[serde(rename = "$text")] std::string::String); +pub struct AngVelFrameType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AreaUnits(#[serde(rename = "$text")] std::string::String); +pub struct AreaUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DayIntervalUnits(#[serde(rename = "$text")] std::string::String); +pub struct DayIntervalUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct FrequencyUnits(#[serde(rename = "$text")] std::string::String); +pub struct FrequencyUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GmUnits(#[serde(rename = "$text")] std::string::String); +pub struct GmUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct InclinationRange(#[serde(rename = "$text")] std::string::String); +pub struct InclinationRange(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LengthUnits(#[serde(rename = "$text")] std::string::String); +pub struct LengthUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MassUnits(#[serde(rename = "$text")] std::string::String); +pub struct MassUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MomentUnits(#[serde(rename = "$text")] std::string::String); +pub struct MomentUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct WkgUnits(#[serde(rename = "$text")] std::string::String); +pub struct WkgUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ObjectDescriptionType(#[serde(rename = "$text")] std::string::String); +pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Ms2Units(#[serde(rename = "$text")] std::string::String); +pub struct Ms2Units(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2Units(#[serde(rename = "$text")] std::string::String); +pub struct Km2Units(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2sUnits(#[serde(rename = "$text")] std::string::String); +pub struct Km2sUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2s2Units(#[serde(rename = "$text")] std::string::String); +pub struct Km2s2Units(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionUnits(#[serde(rename = "$text")] std::string::String); +pub struct PositionUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityUnits(#[serde(rename = "$text")] std::string::String); +pub struct VelocityUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq)] pub struct VecDouble { @@ -103,183 +103,183 @@ pub struct VecDouble { #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec3Double(#[serde(rename = "$text")] std::string::String); +pub struct Vec3Double(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec6Double(#[serde(rename = "$text")] std::string::String); +pub struct Vec6Double(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec9Double(#[serde(rename = "$text")] std::string::String); +pub struct Vec9Double(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct EpochType(#[serde(rename = "$text")] std::string::String); +pub struct EpochType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeUnits(#[serde(rename = "$text")] std::string::String); +pub struct TimeUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeSystemType(#[serde(rename = "$text")] std::string::String); +pub struct TimeSystemType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NegativeDouble(#[serde(rename = "$text")] std::string::String); +pub struct NegativeDouble(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NonNegativeDouble(#[serde(rename = "$text")] std::string::String); +pub struct NonNegativeDouble(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NonPositiveDouble(#[serde(rename = "$text")] std::string::String); +pub struct NonPositiveDouble(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentType(#[serde(rename = "$text")] std::string::String); +pub struct PercentType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositiveDouble(#[serde(rename = "$text")] std::string::String); +pub struct PositiveDouble(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Range100Type(#[serde(rename = "$text")] std::string::String); +pub struct Range100Type(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ProbabilityType(#[serde(rename = "$text")] std::string::String); +pub struct ProbabilityType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentageUnits(#[serde(rename = "$text")] std::string::String); +pub struct PercentageUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct YesNoType(#[serde(rename = "$text")] std::string::String); +pub struct YesNoType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TrajBasisType(#[serde(rename = "$text")] std::string::String); +pub struct TrajBasisType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RevNumBasisType(#[serde(rename = "$text")] std::string::String); +pub struct RevNumBasisType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovBasisType(#[serde(rename = "$text")] std::string::String); +pub struct CovBasisType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManBasisType(#[serde(rename = "$text")] std::string::String); +pub struct ManBasisType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManDcType(#[serde(rename = "$text")] std::string::String); +pub struct ManDcType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NumPerYearUnits(#[serde(rename = "$text")] std::string::String); +pub struct NumPerYearUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ThrustUnits(#[serde(rename = "$text")] std::string::String); +pub struct ThrustUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovOrderType(#[serde(rename = "$text")] std::string::String); +pub struct CovOrderType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GeomagUnits(#[serde(rename = "$text")] std::string::String); +pub struct GeomagUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct SolarFluxUnits(#[serde(rename = "$text")] std::string::String); +pub struct SolarFluxUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionCovarianceUnits(#[serde(rename = "$text")] std::string::String); +pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); +pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] std::string::String); +pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] std::string::String); +pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatRange(#[serde(rename = "$text")] std::string::String); +pub struct LatRange(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AltRange(#[serde(rename = "$text")] std::string::String); +pub struct AltRange(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LonRange(#[serde(rename = "$text")] std::string::String); +pub struct LonRange(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatLonUnits(#[serde(rename = "$text")] std::string::String); +pub struct LatLonUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ControlledType(#[serde(rename = "$text")] std::string::String); +pub struct ControlledType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DisintegrationType(#[serde(rename = "$text")] std::string::String); +pub struct DisintegrationType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ImpactUncertaintyType(#[serde(rename = "$text")] std::string::String); +pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] std::string::String); +pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionComponentType(#[serde(rename = "$text")] std::string::String); +pub struct QuaternionComponentType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionDotUnits(#[serde(rename = "$text")] std::string::String); +pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotDirectionType(#[serde(rename = "$text")] std::string::String); +pub struct RotDirectionType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotseqType(#[serde(rename = "$text")] std::string::String); +pub struct RotseqType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleKeywordType(#[serde(rename = "$text")] std::string::String); +pub struct AngleKeywordType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateKeywordType(#[serde(rename = "$text")] std::string::String); +pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ApmRateFrameType(#[serde(rename = "$text")] std::string::String); +pub struct ApmRateFrameType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TorqueUnits(#[serde(rename = "$text")] std::string::String); +pub struct TorqueUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] From 760836894998eb25b58d2ab5bce81432399b191e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 21 Jan 2024 23:29:59 +0100 Subject: [PATCH 011/150] Add test for OEM --- crates/lox-utils/Cargo.toml | 2 + crates/lox-utils/src/odm/oem.rs | 197 ++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 96ee6f7a..417f9e48 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [dependencies] fast_polynomial.workspace = true thiserror.workspace = true +nom = "7.1.3" +fast_polynomial = "0.1.0" quick-xml = { version = "0.31.0", features = ["serde"] } serde = { version = "1.0.194", features = ["serde_derive"] } diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index a5d5362c..065ade13 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -80,3 +80,200 @@ pub struct OemData { #[serde(rename = "covarianceMatrix")] pub covariance_matrix_list: Vec, } + +#[cfg(test)] +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_oem_message() { + let xml = r#" + + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + 2004-100T00:00:00.000000 + 2004-100T01:00:00.000000 + Hermite + 1 + + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + + +
"#; + + let message: OemType = from_str(xml).unwrap(); + + assert_eq!( + message, + OemType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: OemBody { + segment_list: vec![OemSegment { + metadata: OemMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType("2004-100T00:00:00.000000".to_string(),), + useable_start_time: None, + useable_stop_time: None, + stop_time: common::EpochType("2004-100T01:00:00.000000".to_string(),), + interpolation: Some("Hermite".to_string(),), + interpolation_degree: Some(1,), + }, + data: OemData { + comment_list: vec![], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + ], + covariance_matrix_list: vec![], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "2.0".to_string(), + } + ); + } +} From 6989aec2fafc43a97f5a1bdec49f05c6ec9b6f3f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 21 Jan 2024 23:51:56 +0100 Subject: [PATCH 012/150] Add OMM test --- crates/lox-utils/src/odm/omm.rs | 237 ++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index dca93db0..5a6f2c97 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -214,3 +214,240 @@ pub struct DdRevType { #[serde(rename = "@units")] pub units: Option, } + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_oem_message() { + let xml = r#" + + +
+ THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2 + 2007-065T16:00:00 + NOAA/USA +
+ + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + TLE + + + USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA + + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA/USA".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "TLE".to_string(), + }, + data: OmmData { + comment_list: vec![ + "USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA".to_string(), + ], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + "0.0005013".to_string(), + ), + inclination: common::InclinationType { + base: common::InclinationRange( + "3.0539".to_string(), + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + "81.7939".to_string(), + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + "249.2363".to_string(), + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + "150.1602".to_string(), + ), + units: None, + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + "398600.8".to_string(), + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC0".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC1".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC2".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC3".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC4".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC5".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC6".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC7".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC8".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC9".to_string(), + }, + ], + }, + ), + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } +} From 4dbea18d6ca7bd28b096066d9ad082f1165d91be Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 27 Jan 2024 19:07:38 +0100 Subject: [PATCH 013/150] Making the same as in oem test --- crates/lox-utils/src/odm/omm.rs | 110 ++++++++++++++++---------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 5a6f2c97..560832a8 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -223,61 +223,61 @@ mod test { #[test] fn test_parse_oem_message() { let xml = r#" - - -
- THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2 - 2007-065T16:00:00 - NOAA/USA -
- - - - GOES-9 - 1995-025A - EARTH - TEME - UTC - TLE - - - USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA - - 2007-064T10:34:41.4264 - 1.00273272 - 0.0005013 - 3.0539 - 81.7939 - 249.2363 - 150.1602 - 398600.8 - - - 23581 - 0925 - 4316 - 0.0001 - -0.00000113 - 0.0 - - - xyz - 9 - xyz - 9 - xyz - 9 - xyz - 9 - xyz - 9 - - - - -
"#; + + +
+ THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2 + 2007-065T16:00:00 + NOAA/USA +
+ + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + TLE + + + USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA + + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + + + + +
"#; let message: OmmType = from_str(xml).unwrap(); From 5444d8f35d447b4be381b789715322cd5f59c388 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 27 Jan 2024 19:10:57 +0100 Subject: [PATCH 014/150] Fix test name --- crates/lox-utils/src/odm/omm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 560832a8..119e012f 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -221,7 +221,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_oem_message() { + fn test_parse_omm_message() { let xml = r#" Date: Sat, 27 Jan 2024 23:36:15 +0100 Subject: [PATCH 015/150] Simplify extension types --- crates/lox-utils/src/odm/common.rs | 155 ++++++++++++++++------------- 1 file changed, 88 insertions(+), 67 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 43187225..8e55775a 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -753,38 +753,106 @@ pub struct SolarFluxType { #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct OpmCovarianceMatrixAbstractType { +pub struct OemCovarianceMatrixType { #[serde(rename = "COMMENT")] pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame: Option, + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct OemCovarianceMatrixAbstractType { +pub struct OpmCovarianceMatrixType { #[serde(rename = "COMMENT")] pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: EpochType, #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemCovarianceMatrixType { - #[serde(flatten)] - pub base: OemCovarianceMatrixAbstractType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OpmCovarianceMatrixType { - #[serde(flatten)] - pub base: OpmCovarianceMatrixAbstractType, - #[serde(flatten)] - pub extension: CovarianceMatrixElementsGroup, + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -1076,50 +1144,3 @@ pub struct TorqueType { #[serde(rename = "@units")] pub units: Option, } - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct CovarianceMatrixElementsGroup { - #[serde(rename = "CX_X")] - pub cx_x: PositionCovarianceType, - #[serde(rename = "CY_X")] - pub cy_x: PositionCovarianceType, - #[serde(rename = "CY_Y")] - pub cy_y: PositionCovarianceType, - #[serde(rename = "CZ_X")] - pub cz_x: PositionCovarianceType, - #[serde(rename = "CZ_Y")] - pub cz_y: PositionCovarianceType, - #[serde(rename = "CZ_Z")] - pub cz_z: PositionCovarianceType, - #[serde(rename = "CX_DOT_X")] - pub cx_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Y")] - pub cx_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Z")] - pub cx_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_X_DOT")] - pub cx_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_X")] - pub cy_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Y")] - pub cy_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Z")] - pub cy_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_X_DOT")] - pub cy_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_Y_DOT")] - pub cy_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_X")] - pub cz_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y")] - pub cz_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z")] - pub cz_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_X_DOT")] - pub cz_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y_DOT")] - pub cz_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z_DOT")] - pub cz_dot_z_dot: VelocityCovarianceType, -} From cef08ff8fae4001b1ad8444fc9a35cf6f20d54af Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 27 Jan 2024 23:36:32 +0100 Subject: [PATCH 016/150] Add OEM test 2 --- crates/lox-utils/src/odm/oem.rs | 407 +++++++++++++++++++++++++++++++- 1 file changed, 406 insertions(+), 1 deletion(-) diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/odm/oem.rs index 065ade13..0158b8ee 100644 --- a/crates/lox-utils/src/odm/oem.rs +++ b/crates/lox-utils/src/odm/oem.rs @@ -88,7 +88,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_oem_message() { + fn test_parse_oem_message1() { let xml = r#" + + +
+ OEM WITH OPTIONAL ACCELERATIONS + 1996-11-04T17:22:31 + NASA/JPL + OEM 201113719185 +
+ + + + MARS GLOBAL SURVEYOR + 2000-028A + MARS BARYCENTER + J2000 + UTC + 1996-12-18T12:00:00.331 + 1996-12-18T12:10:00.331 + 1996-12-28T21:23:00.331 + 1996-12-28T21:28:00.331 + HERMITE + 7 + + + Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is + to be used for DSN scheduling purposes only. + + 1996-12-18T12:00:00.331 + 2789.6 + -280.0 + -1746.8 + 4.73 + -2.50 + -1.04 + 0.008 + 0.001 + -0.159 + + + 1996-12-18T12:01:00.331 + 2783.4 + -308.1 + -1877.1 + 5.19 + -2.42 + -2.00 + 0.008 + 0.001 + 0.001 + + + 1996-12-18T12:02:00.331 + 2776.0 + -336.9 + -2008.7 + 5.64 + -2.34 + -1.95 + 0.008 + 0.001 + 0.159 + + + 1996-12-28T21:28:00.331 + -3881.0 + 564.0 + -682.8 + -3.29 + -3.67 + 1.64 + -0.003 + 0.000 + 0.000 + + + blabla + 1996-12-28T22:28:00.331 + ITRF1997 + 0.316 + 0.722 + 0.518 + 0.202 + 0.715 + 0.002 + 0.912 + 0.306 + 0.276 + 0.797 + 0.562 + 0.899 + 0.022 + 0.079 + 0.415 + 0.245 + 0.965 + 0.950 + 0.435 + 0.621 + 0.991 + + + + +
"#; + + let message: OemType = from_str(xml).unwrap(); + + assert_eq!( + message, + OemType { + header: common::OdmHeader { + comment_list: vec!["OEM WITH OPTIONAL ACCELERATIONS".to_string(),], + classification_list: vec![], + creation_date: common::EpochType("1996-11-04T17:22:31".to_string(),), + originator: "NASA/JPL".to_string(), + message_id: Some("OEM 201113719185".to_string(),), + }, + body: OemBody { + segment_list: vec![OemSegment { + metadata: OemMetadata { + comment_list: vec![], + object_name: "MARS GLOBAL SURVEYOR".to_string(), + object_id: "2000-028A".to_string(), + center_name: "MARS BARYCENTER".to_string(), + ref_frame: "J2000".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + useable_start_time: Some(common::EpochType( + "1996-12-18T12:10:00.331".to_string(), + ),), + useable_stop_time: Some(common::EpochType( + "1996-12-28T21:23:00.331".to_string(), + ),), + stop_time: common::EpochType("1996-12-28T21:28:00.331".to_string(),), + interpolation: Some("HERMITE".to_string(),), + interpolation_degree: Some(7,), + }, + data: OemData { + comment_list: vec![ + "Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is" + .to_string(), + "to be used for DSN scheduling purposes only.".to_string(), + ], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + x: common::PositionType { + base: 2789.6, + units: None, + }, + y: common::PositionType { + base: -280.0, + units: None, + }, + z: common::PositionType { + base: -1746.8, + units: None, + }, + x_dot: common::VelocityType { + base: 4.73, + units: None, + }, + y_dot: common::VelocityType { + base: -2.5, + units: None, + }, + z_dot: common::VelocityType { + base: -1.04, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: -0.159, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:01:00.331".to_string(),), + x: common::PositionType { + base: 2783.4, + units: None, + }, + y: common::PositionType { + base: -308.1, + units: None, + }, + z: common::PositionType { + base: -1877.1, + units: None, + }, + x_dot: common::VelocityType { + base: 5.19, + units: None, + }, + y_dot: common::VelocityType { + base: -2.42, + units: None, + }, + z_dot: common::VelocityType { + base: -2.0, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:02:00.331".to_string(),), + x: common::PositionType { + base: 2776.0, + units: None, + }, + y: common::PositionType { + base: -336.9, + units: None, + }, + z: common::PositionType { + base: -2008.7, + units: None, + }, + x_dot: common::VelocityType { + base: 5.64, + units: None, + }, + y_dot: common::VelocityType { + base: -2.34, + units: None, + }, + z_dot: common::VelocityType { + base: -1.95, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.159, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-28T21:28:00.331".to_string(),), + x: common::PositionType { + base: -3881.0, + units: None, + }, + y: common::PositionType { + base: 564.0, + units: None, + }, + z: common::PositionType { + base: -682.8, + units: None, + }, + x_dot: common::VelocityType { + base: -3.29, + units: None, + }, + y_dot: common::VelocityType { + base: -3.67, + units: None, + }, + z_dot: common::VelocityType { + base: 1.64, + units: None, + }, + x_ddot: Some(common::AccType { + base: -0.003, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.0, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.0, + units: None, + },), + }, + ], + covariance_matrix_list: vec![common::OemCovarianceMatrixType { + comment_list: vec!["blabla".to_string(),], + epoch: common::EpochType("1996-12-28T22:28:00.331".to_string(),), + cov_ref_frame: Some("ITRF1997".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.316, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.722, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.518, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: 0.202, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: 0.715, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.002, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: 0.912, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: 0.306, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 0.276, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 0.797, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: 0.562, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: 0.899, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 0.022, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 0.079, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 0.415, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: 0.245, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: 0.965, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 0.95, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 0.435, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 0.621, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 0.991, + units: None, + }, + },], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "3.0".to_string(), + } + ); + } } From c3193d60bd3d413ea27198901b4375751822a87f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 11:07:54 +0100 Subject: [PATCH 017/150] Add OMM test 2 --- crates/lox-utils/src/odm/omm.rs | 164 +++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 119e012f..190a8503 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -221,7 +221,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_omm_message() { + fn test_parse_omm_message1() { let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + + EARTH + TEME + UTC + SGP4 + + + + 2021-03-22T13:21:09.224928 + 13.82309053 + .0205751 + 49.8237 + 93.8140 + 224.8348 + 133.5761 + + + 0 + U + 7646 + 999 + 32997 + -.47102E-5 + -.147E-5 + 0 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType( + "2021-03-24T23:00:00.000".to_string(), + ), + originator: "CelesTrak".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "STARLETTE".to_string(), + object_id: "".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2021-03-22T13:21:09.224928".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 13.82309053, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + ".0205751".to_string(), + ), + inclination: common::InclinationType { + base: common::InclinationRange( + "49.8237".to_string(), + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + "93.8140".to_string(), + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + "224.8348".to_string(), + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + "133.5761".to_string(), + ), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: Some( + 0, + ), + classification_type: Some( + "U".to_string(), + ), + norad_cat_id: Some( + 7646, + ), + element_set_no: Some( + ElementSetNoType( + "999".to_string(), + ), + ), + rev_at_epoch: Some( + 32997, + ), + bstar: Some( + BStarType { + base: -4.7102e-6, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } } From 2da81aa8c8ed8d93b2c6cb5cce471e580d4e5432 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 11:21:12 +0100 Subject: [PATCH 018/150] Add OMM message test with units --- crates/lox-utils/src/odm/omm.rs | 330 ++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 190a8503..046e94a6 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -612,4 +612,334 @@ mod test { version: "2.0".to_string(), }); } + + #[test] + fn test_parse_omm_message_with_units() { + let xml = r#" + +
+ THIS IS AN XML VERSION OF THE OMM + 2007-065T16:00:00 + NOAA + OMM 201113719185 +
+ + + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + SGP/SGP4 + + + + + mean Elements + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + tle Parameters + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + covariance Matrix + TEME + 3.331349476038534e-04 + 4.618927349220216e-04 + 6.782421679971363e-04 + -3.070007847730449e-04 + -4.221234189514228e-04 + 3.231931992380369e-04 + -3.349365033922630e-07 + -4.686084221046758e-07 + 2.484949578400095e-07 + 4.296022805587290e-10 + -2.211832501084875e-07 + -2.864186892102733e-07 + 1.798098699846038e-07 + 2.608899201686016e-10 + 1.767514756338532e-10 + -3.041346050686871e-07 + -4.989496988610662e-07 + 3.540310904497689e-07 + 1.869263192954590e-10 + 1.008862586240695e-10 + 6.224444338635500e-10 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS IS AN XML VERSION OF THE OMM".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA".to_string(), + message_id: Some( + "OMM 201113719185".to_string(), + ), + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP/SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![ + "mean Elements".to_string(), + ], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: Some( + RevUnits( + "rev/day".to_string(), + ), + ), + }, + ), + eccentricity: common::NonNegativeDouble( + "0.0005013".to_string(), + ), + inclination: common::InclinationType { + base: common::InclinationRange( + "3.0539".to_string(), + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + "81.7939".to_string(), + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + "249.2363".to_string(), + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + "150.1602".to_string(), + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + "398600.8".to_string(), + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![ + "tle Parameters".to_string(), + ], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: Some( + BStarUnits( + "1/ER".to_string(), + ), + ), + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: Some( + DRevUnits( + "rev/day**2".to_string(), + ), + ), + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: Some( + DRevUnits( + "rev/day**3".to_string(), + ), + ), + }, + ), + agom: None, + }, + ), + covariance_matrix: Some( + common::OpmCovarianceMatrixType { + comment_list: vec![ + "covariance Matrix".to_string(), + ], + cov_ref_frame: Some( + "TEME".to_string(), + ), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + }, + ), + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "3.0".to_string(), + }); + } } From 3346fd8a3bc31a61f6a5474e060a12b956144602 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 11:31:30 +0100 Subject: [PATCH 019/150] Add OMM message test 3 --- crates/lox-utils/src/odm/omm.rs | 289 ++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 046e94a6..4cb177dc 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -613,6 +613,295 @@ mod test { }); } + #[test] + fn test_parse_omm_message3() { + let xml = r#" + +
+ THIS IS AN XML VERSION OF THE OMM + 2007-065T16:00:00 + NOAA + OMM 201113719185 +
+ + + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + SGP/SGP4 + + + + + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + TEME + 3.331349476038534e-04 + 4.618927349220216e-04 + 6.782421679971363e-04 + -3.070007847730449e-04 + -4.221234189514228e-04 + 3.231931992380369e-04 + -3.349365033922630e-07 + -4.686084221046758e-07 + 2.484949578400095e-07 + 4.296022805587290e-10 + -2.211832501084875e-07 + -2.864186892102733e-07 + 1.798098699846038e-07 + 2.608899201686016e-10 + 1.767514756338532e-10 + -3.041346050686871e-07 + -4.989496988610662e-07 + 3.540310904497689e-07 + 1.869263192954590e-10 + 1.008862586240695e-10 + 6.224444338635500e-10 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS IS AN XML VERSION OF THE OMM".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA".to_string(), + message_id: Some( + "OMM 201113719185".to_string(), + ), + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP/SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + "0.0005013".to_string(), + ), + inclination: common::InclinationType { + base: common::InclinationRange( + "3.0539".to_string(), + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + "81.7939".to_string(), + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + "249.2363".to_string(), + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + "150.1602".to_string(), + ), + units: None, + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + "398600.8".to_string(), + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: Some( + common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some( + "TEME".to_string(), + ), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + }, + ), + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "3.0".to_string(), + }); + } + #[test] fn test_parse_omm_message_with_units() { let xml = r#" From 566f16d812196c90454cad15528f041e08b44d8c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 11:38:43 +0100 Subject: [PATCH 020/150] Clarify empty_object_id test --- crates/lox-utils/src/odm/omm.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 4cb177dc..fd55c9cc 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -452,7 +452,10 @@ mod test { } #[test] - fn test_parse_omm_message2() { + fn test_parse_omm_message_with_empty_object_id() { + // According to Orekit this should fail to parse due to having an empty object id. However, the XSD type of + // the object id is just xsd:string, which allows empty strings too. + let xml = r#"
@@ -614,7 +617,7 @@ mod test { } #[test] - fn test_parse_omm_message3() { + fn test_parse_omm_message2() { let xml = r#" Date: Sun, 28 Jan 2024 21:59:04 +0100 Subject: [PATCH 021/150] Make types as float --- crates/lox-utils/src/odm/common.rs | 18 ++++++------ crates/lox-utils/src/odm/omm.rs | 46 +++++++++++++++--------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/odm/common.rs index 8e55775a..3aa1997b 100644 --- a/crates/lox-utils/src/odm/common.rs +++ b/crates/lox-utils/src/odm/common.rs @@ -18,7 +18,7 @@ pub struct AngleUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRange(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -30,7 +30,7 @@ pub struct AngMomentumUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngVelFrameType(#[serde(rename = "$text")] pub std::string::String); +pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -50,7 +50,7 @@ pub struct GmUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct InclinationRange(#[serde(rename = "$text")] pub std::string::String); +pub struct InclinationRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -103,15 +103,15 @@ pub struct VecDouble { #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec3Double(#[serde(rename = "$text")] pub std::string::String); +pub struct Vec3Double(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec6Double(#[serde(rename = "$text")] pub std::string::String); +pub struct Vec6Double(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Vec9Double(#[serde(rename = "$text")] pub std::string::String); +pub struct Vec9Double(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -127,11 +127,11 @@ pub struct TimeSystemType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NegativeDouble(#[serde(rename = "$text")] pub std::string::String); +pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NonNegativeDouble(#[serde(rename = "$text")] pub std::string::String); +pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -143,7 +143,7 @@ pub struct PercentType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositiveDouble(#[serde(rename = "$text")] pub std::string::String); +pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index fd55c9cc..489d0de5 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -323,36 +323,36 @@ mod test { }, ), eccentricity: common::NonNegativeDouble( - "0.0005013".to_string(), + 0.0005013, ), inclination: common::InclinationType { base: common::InclinationRange( - "3.0539".to_string(), + 3.0539, ), units: None, }, ra_of_asc_node: common::AngleType { base: common::AngleRange( - "81.7939".to_string(), + 81.7939, ), units: None, }, arg_of_pericenter: common::AngleType { base: common::AngleRange( - "249.2363".to_string(), + 249.2363, ), units: None, }, mean_anomaly: common::AngleType { base: common::AngleRange( - "150.1602".to_string(), + 150.1602, ), units: None, }, gm: Some( common::GmType { base: common::PositiveDouble( - "398600.8".to_string(), + 398600.8, ), units: None, }, @@ -537,29 +537,29 @@ mod test { }, ), eccentricity: common::NonNegativeDouble( - ".0205751".to_string(), + 0.0205751, ), inclination: common::InclinationType { base: common::InclinationRange( - "49.8237".to_string(), + 49.8237, ), units: None, }, ra_of_asc_node: common::AngleType { base: common::AngleRange( - "93.8140".to_string(), + 93.8140, ), units: None, }, arg_of_pericenter: common::AngleType { base: common::AngleRange( - "224.8348".to_string(), + 224.8348, ), units: None, }, mean_anomaly: common::AngleType { base: common::AngleRange( - "133.5761".to_string(), + 133.5761, ), units: None, }, @@ -732,36 +732,36 @@ mod test { }, ), eccentricity: common::NonNegativeDouble( - "0.0005013".to_string(), + 0.0005013, ), inclination: common::InclinationType { base: common::InclinationRange( - "3.0539".to_string(), + 3.0539, ), units: None, }, ra_of_asc_node: common::AngleType { base: common::AngleRange( - "81.7939".to_string(), + 81.7939, ), units: None, }, arg_of_pericenter: common::AngleType { base: common::AngleRange( - "249.2363".to_string(), + 249.2363, ), units: None, }, mean_anomaly: common::AngleType { base: common::AngleRange( - "150.1602".to_string(), + 150.1602, ), units: None, }, gm: Some( common::GmType { base: common::PositiveDouble( - "398600.8".to_string(), + 398600.8, ), units: None, }, @@ -1030,11 +1030,11 @@ mod test { }, ), eccentricity: common::NonNegativeDouble( - "0.0005013".to_string(), + 0.0005013, ), inclination: common::InclinationType { base: common::InclinationRange( - "3.0539".to_string(), + 3.0539, ), units: Some( common::AngleUnits( @@ -1044,7 +1044,7 @@ mod test { }, ra_of_asc_node: common::AngleType { base: common::AngleRange( - "81.7939".to_string(), + 81.7939, ), units: Some( common::AngleUnits( @@ -1054,7 +1054,7 @@ mod test { }, arg_of_pericenter: common::AngleType { base: common::AngleRange( - "249.2363".to_string(), + 249.2363, ), units: Some( common::AngleUnits( @@ -1064,7 +1064,7 @@ mod test { }, mean_anomaly: common::AngleType { base: common::AngleRange( - "150.1602".to_string(), + 150.1602, ), units: Some( common::AngleUnits( @@ -1075,7 +1075,7 @@ mod test { gm: Some( common::GmType { base: common::PositiveDouble( - "398600.8".to_string(), + 398600.8, ), units: None, }, From f5e3bb4d21d7f1b258cd334c6dd6a5af14349d3b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 21:59:19 +0100 Subject: [PATCH 022/150] Add omm message 3 test --- crates/lox-utils/src/odm/omm.rs | 165 ++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 489d0de5..0cce77d7 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1234,4 +1234,169 @@ mod test { version: "3.0".to_string(), }); } + + + #[test] + fn test_parse_omm_message3() { + let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + 1975-010A + EARTH + TEME + UTC + SGP4 + + + + 2021-03-22T13:21:09.224928 + 13.82309053 + .0205751 + 49.8237 + 93.8140 + 224.8348 + 133.5761 + + + 0 + U + 7646 + 999 + 32997 + -.47102E-5 + -.147E-5 + 0 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + println!("{:#?}", message); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType( + "2021-03-24T23:00:00.000".to_string(), + ), + originator: "CelesTrak".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "STARLETTE".to_string(), + object_id: "1975-010A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2021-03-22T13:21:09.224928".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 13.82309053, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0205751, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 49.8237, + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 93.814, + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 224.8348, + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 133.5761, + ), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: Some( + 0, + ), + classification_type: Some( + "U".to_string(), + ), + norad_cat_id: Some( + 7646, + ), + element_set_no: Some( + ElementSetNoType( + "999".to_string(), + ), + ), + rev_at_epoch: Some( + 32997, + ), + bstar: Some( + BStarType { + base: -4.7102e-6, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } } From c901da869091edb2e13a08891fc871f7eccff85e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 22:02:56 +0100 Subject: [PATCH 023/150] Add test for spurious corrupted data --- crates/lox-utils/src/odm/omm.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 0cce77d7..0ed35c29 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1399,4 +1399,35 @@ mod test { version: "2.0".to_string(), }); } + + + #[test] + fn test_parse_omm_message_spurious() { + let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + 1975-010A + EARTH + TEME + UTC + SGP4 + + + second metadata is an error + + + +
"#; + + let message: Result = from_str(xml); + + assert!(message.is_err()); + } } From 1868b584946371b669ca44879493990afe17de38 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 28 Jan 2024 22:57:25 +0100 Subject: [PATCH 024/150] Add opm test --- crates/lox-utils/src/odm/opm.rs | 248 ++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index fa4ed6bc..aec4d0f2 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -120,3 +120,251 @@ pub struct ManeuverParametersType { #[serde(rename = "MAN_DV_3")] pub man_dv_3: common::VelocityType, } + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_opm_message() { + let xml = r#" + + +
+ THIS IS AN XML VERSION OF THE OPM + 2001-11-06T09:23:57 + JAXA + OPM 201113719185 +
+ + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + OSPREY 5 + 1998-999A + EARTH + TOD + 1998-12-18T14:28:15.1172 + UTC + + + + 1996-12-18T14:28:15.1172 + 6503.514000 + 1239.647000 + -717.490000 + -0.873160 + 8.740420 + -4.191076 + + + 3000.000000 + 18.770000 + 1.000000 + 18.770000 + 2.500000 + + + ITRF1997 + 0.316 + 0.722 + 0.518 + 0.202 + 0.715 + 0.002 + 0.912 + 0.306 + 0.276 + 0.797 + 0.562 + 0.899 + 0.022 + 0.079 + 0.415 + 0.245 + 0.965 + 0.950 + 0.435 + 0.621 + 0.991 + + + + +
"#; + + let message: OpmType = from_str(xml).unwrap(); + + assert_eq!( + message, + OpmType { + header: common::OdmHeader { + comment_list: vec!["THIS IS AN XML VERSION OF THE OPM".to_string(),], + classification_list: vec![], + creation_date: common::EpochType("2001-11-06T09:23:57".to_string(),), + originator: "JAXA".to_string(), + message_id: Some("OPM 201113719185".to_string(),), + }, + body: OpmBody { + segment: OpmSegment { + metadata: OpmMetadata { + comment_list: vec!["GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(),], + object_name: "OSPREY 5".to_string(), + object_id: "1998-999A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TOD".to_string(), + ref_frame_epoch: Some(common::EpochType( + "1998-12-18T14:28:15.1172".to_string(), + ),), + time_system: "UTC".to_string(), + }, + data: OpmData { + comment_list: vec![], + state_vector: common::StateVectorType { + comment_list: vec![], + epoch: common::EpochType("1996-12-18T14:28:15.1172".to_string(),), + x: common::PositionType { + base: 6503.514, + units: None, + }, + y: common::PositionType { + base: 1239.647, + units: None, + }, + z: common::PositionType { + base: -717.49, + units: None, + }, + x_dot: common::VelocityType { + base: -0.87316, + units: None, + }, + y_dot: common::VelocityType { + base: 8.74042, + units: None, + }, + z_dot: common::VelocityType { + base: -4.191076, + units: None, + }, + }, + keplerian_elements: None, + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec![], + mass: Some(common::MassType { + base: common::NonNegativeDouble(3000.0,), + units: None, + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(18.77,), + units: None, + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(18.77,), + units: None, + },), + drag_coeff: Some(common::NonNegativeDouble(2.5,),), + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some("ITRF1997".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.316, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.722, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.518, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: 0.202, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: 0.715, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.002, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: 0.912, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: 0.306, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 0.276, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 0.797, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: 0.562, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: 0.899, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 0.022, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 0.079, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 0.415, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: 0.245, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: 0.965, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 0.95, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 0.435, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 0.621, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 0.991, + units: None, + }, + },), + maneuver_parameters_list: vec![], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "3.0".to_string(), + } + ); + } +} From 265b162c9dc096b3965cc2129291cfe356b759bf Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:15:31 +0100 Subject: [PATCH 025/150] Add OCM test --- crates/lox-utils/src/odm/ocm.rs | 442 ++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/odm/ocm.rs index f7114bcb..ce80d144 100644 --- a/crates/lox-utils/src/odm/ocm.rs +++ b/crates/lox-utils/src/odm/ocm.rs @@ -544,3 +544,445 @@ pub struct OcmOdParametersType { #[serde(rename = "DATA_TYPES")] pub data_types: Option, } + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_ocm_message() { + let xml = r#" + +
+ ODM V.3 Example G-2 + OCM example with space object characteristics and perturbations. + This OCM reflects the latest conditions post-maneuver A67Z + This example shows the specification of multiple comment lines + 1998-11-06T09:23:57 + JAXA + OCM 201113719185 +
+ + + + 1998-999A + R. Rabbit + Flight Dynamics Mission Design Lead + (719)555-1234 + Mr. Rodgers + (719)555-1234 + email@email.XXX + UT1 + 1998-12-18T00:00:00.0000 + 36 + .357 + + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + THIS IS MY SECOND COMMENT LINE + PREDICTED + EFG + CARTPVA + 0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070 + + + Spacecraft Physical Characteristics + 100.0 + 0.03123 + 0.78543 + 0.39158 + 0.47832 + 2.0 + 1.0 + 0.5 + 0.15 + 0.3 + 0.5 + + + Perturbations Specification + NRLMSIS00 + EGM-96: 36D 36O + 398600.4415 + MOON, SUN + 12.0 + 105.0 + 120.0 + + + WGS-84 + + + + +
"#; + + let message: OcmType = from_str(xml).unwrap(); + + assert_eq!(message, OcmType { + header: common::OdmHeader { + comment_list: vec![ + "ODM V.3 Example G-2".to_string(), + "OCM example with space object characteristics and perturbations.".to_string(), + "This OCM reflects the latest conditions post-maneuver A67Z".to_string(), + "This example shows the specification of multiple comment lines".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "1998-11-06T09:23:57".to_string(), + ), + originator: "JAXA".to_string(), + message_id: Some( + "OCM 201113719185".to_string(), + ), + }, + body: OcmBody { + segment: OcmSegment { + metadata: OcmMetadata { + comment_list: vec![], + object_name: None, + international_designator: Some( + "1998-999A".to_string(), + ), + catalog_name: None, + object_designator: None, + alternate_names: None, + originator_poc: Some( + "R. Rabbit".to_string(), + ), + originator_position: Some( + "Flight Dynamics Mission Design Lead".to_string(), + ), + originator_phone: Some( + "(719)555-1234".to_string(), + ), + originator_email: None, + originator_address: None, + tech_org: None, + tech_poc: Some( + "Mr. Rodgers".to_string(), + ), + tech_position: None, + tech_phone: Some( + "(719)555-1234".to_string(), + ), + tech_email: None, + tech_address: Some( + "email@email.XXX".to_string(), + ), + previous_message_id: None, + next_message_id: None, + adm_msg_link: None, + cdm_msg_link: None, + prm_msg_link: None, + rdm_msg_link: None, + tdm_msg_link: None, + operator: None, + owner: None, + country: None, + constellation: None, + object_type: None, + time_system: "UT1".to_string(), + epoch_tzero: common::EpochType( + "1998-12-18T00:00:00.0000".to_string(), + ), + ops_status: None, + orbit_category: None, + ocm_data_elements: None, + sclk_offset_at_epoch: None, + sclk_sec_per_si_sec: None, + previous_message_epoch: None, + next_message_epoch: None, + start_time: None, + stop_time: None, + time_span: None, + taimutc_at_tzero: Some( + common::TimeOffsetType { + base: 36.0, + units: Some( + common::TimeUnits( + "s".to_string(), + ), + ), + }, + ), + next_leap_epoch: None, + next_leap_taimutc: None, + ut1mutc_at_tzero: Some( + common::TimeOffsetType { + base: 0.357, + units: Some( + common::TimeUnits( + "s".to_string(), + ), + ), + }, + ), + eop_source: None, + interp_method_eop: None, + celestial_source: None, + }, + data: OcmData { + traj_list: vec![ + OcmTrajStateType { + comment_list: vec![ + "GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(), + "THIS IS MY SECOND COMMENT LINE".to_string(), + ], + traj_id: None, + traj_prev_id: None, + traj_next_id: None, + traj_basis: Some( + common::TrajBasisType( + "PREDICTED".to_string(), + ), + ), + traj_basis_id: None, + interpolation: None, + interpolation_degree: None, + propagator: None, + center_name: "".to_string(), + traj_ref_frame: "EFG".to_string(), + traj_frame_epoch: None, + useable_start_time: None, + useable_stop_time: None, + orb_revnum: None, + orb_revnum_basis: None, + traj_type: "CARTPVA".to_string(), + orb_averaging: None, + traj_units: None, + traj_line_list: vec![ + "0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070".to_string(), + ], + }, + ], + phys: Some( + OcmPhysicalDescriptionType { + comment_list: vec![ + "Spacecraft Physical Characteristics".to_string(), + ], + manufacturer: None, + bus_model: None, + docked_with: None, + drag_const_area: None, + drag_coeff_nom: None, + drag_uncertainty: None, + initial_wet_mass: None, + wet_mass: Some( + common::MassType { + base: common::NonNegativeDouble( + 100.0, + ), + units: Some( + common::MassUnits( + "kg".to_string(), + ), + ), + }, + ), + dry_mass: None, + oeb_parent_frame: None, + oeb_parent_frame_epoch: None, + oeb_q1: Some( + 0.03123, + ), + oeb_q2: Some( + 0.78543, + ), + oeb_q3: Some( + 0.39158, + ), + oeb_qc: Some( + 0.47832, + ), + oeb_max: Some( + common::OcmLengthType { + base: 2.0, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + oeb_int: Some( + common::OcmLengthType { + base: 1.0, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + oeb_min: Some( + common::OcmLengthType { + base: 0.5, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + area_along_oeb_max: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.15, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_along_oeb_int: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.3, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_along_oeb_min: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.5, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_min_for_pc: None, + area_max_for_pc: None, + area_typ_for_pc: None, + rcs: None, + rcs_min: None, + rcs_max: None, + srp_const_area: None, + solar_rad_coeff: None, + solar_rad_uncertainty: None, + vm_absolute: None, + vm_apparent_min: None, + vm_apparent: None, + vm_apparent_max: None, + reflectance: None, + att_control_mode: None, + att_actuator_type: None, + att_knowledge: None, + att_control: None, + att_pointing: None, + avg_maneuver_freq: None, + max_thrust: None, + dv_bol: None, + dv_remaining: None, + ixx: None, + iyy: None, + izz: None, + ixy: None, + ixz: None, + iyz: None, + }, + ), + cov_list: vec![], + man_list: vec![], + pert: Some( + OcmPerturbationsType { + comment_list: vec![ + "Perturbations Specification".to_string(), + ], + atmospheric_model: Some( + "NRLMSIS00".to_string(), + ), + gravity_model: Some( + "EGM-96: 36D 36O".to_string(), + ), + equatorial_radius: None, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.4415, + ), + units: Some( + common::GmUnits( + "km**3/s**2".to_string(), + ), + ), + }, + ), + n_body_perturbations: Some( + "MOON, SUN".to_string(), + ), + central_body_rotation: None, + oblate_flattening: None, + ocean_tides_model: None, + solid_tides_model: None, + reduction_theory: None, + albedo_model: None, + albedo_grid_size: None, + shadow_model: None, + shadow_bodies: None, + srp_model: None, + sw_data_source: None, + sw_data_epoch: None, + sw_interp_method: None, + fixed_geomag_kp: Some( + common::GeomagType { + base: 12.0, + units: None, + }, + ), + fixed_geomag_ap: None, + fixed_geomag_dst: None, + fixed_f10p7: Some( + common::SolarFluxType { + base: 105.0, + units: None, + }, + ), + fixed_f10p7_mean: Some( + common::SolarFluxType { + base: 120.0, + units: None, + }, + ), + fixed_m10p7: None, + fixed_m10p7_mean: None, + fixed_s10p7: None, + fixed_s10p7_mean: None, + fixed_y10p7: None, + fixed_y10p7_mean: None, + }, + ), + od: None, + user: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "WGS-84".to_string(), + parameter: "EARTH_MODEL".to_string(), + }, + ], + }, + ), + }, + }, + }, + id: "CCSDS_OCM_VERS".to_string(), + version: "3.0".to_string(), + }); + } +} From 04564d0177d14fc59cc8d6b98895afb34228e9cf Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:15:53 +0100 Subject: [PATCH 026/150] Add OPM invalid message test --- crates/lox-utils/src/odm/opm.rs | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index aec4d0f2..4ce9818f 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -367,4 +367,40 @@ mod test { } ); } + + #[test] + fn test_parse_opm_message_spurious() { + let xml = r#" + + +
+ THIS IS AN XML VERSION OF THE OPM + 2001-11-06T09:23:57 + JAXA + OPM 201113719185 +
+ + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + OSPREY 5 + 1998-999A + EARTH + TOD + 1998-12-18T14:28:15.1172 + UTC + + + second metadata is an error + + + +
"#; + + let message: Result = from_str(xml); + + assert!(message.is_err()); + } } From b28c9e03b113b21c2be1000adcd9995cf66a4b1e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:19:54 +0100 Subject: [PATCH 027/150] Make the OMM message test a bit more complicated --- crates/lox-utils/src/odm/omm.rs | 72 ++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 0ed35c29..3fd75f65 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1256,13 +1256,14 @@ mod test { - 2021-03-22T13:21:09.224928 - 13.82309053 - .0205751 - 49.8237 - 93.8140 - 224.8348 - 133.5761 + 2008-09-20T12:25:40.104192 + 15.72125391 + 0.0006703 + 51.6416 + 247.4627 + 130.5360 + 325.0288 + 398600.8 0 @@ -1311,43 +1312,74 @@ mod test { mean_elements: MeanElementsType { comment_list: vec![], epoch: common::EpochType( - "2021-03-22T13:21:09.224928".to_string(), + "2008-09-20T12:25:40.104192".to_string(), ), semi_major_axis: None, mean_motion: Some( RevType { - base: 13.82309053, - units: None, + base: 15.72125391, + units: Some( + RevUnits( + "rev/day".to_string(), + ), + ), }, ), eccentricity: common::NonNegativeDouble( - 0.0205751, + 0.0006703, ), inclination: common::InclinationType { base: common::InclinationRange( - 49.8237, + 51.6416, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), ), - units: None, }, ra_of_asc_node: common::AngleType { base: common::AngleRange( - 93.814, + 247.4627, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), ), - units: None, }, arg_of_pericenter: common::AngleType { base: common::AngleRange( - 224.8348, + 130.536, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), ), - units: None, }, mean_anomaly: common::AngleType { base: common::AngleRange( - 133.5761, + 325.0288, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), ), - units: None, }, - gm: None, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.8, + ), + units: Some( + common::GmUnits( + "km**3/s**2".to_string(), + ), + ), + }, + ), }, spacecraft_parameters: None, tle_parameters: Some( From b960061d060d5bad5f28314b787684e3ef9ce73d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:26:41 +0100 Subject: [PATCH 028/150] Add user defined parameters to list --- crates/lox-utils/src/odm/omm.rs | 78 ++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 3fd75f65..59ca9a5e 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -1241,40 +1241,44 @@ mod test { let xml = r#"
- 2021-03-24T23:00:00.000 - CelesTrak + 2021-03-24T23:00:00.000 + CelesTrak
- STARLETTE - 1975-010A - EARTH - TEME - UTC - SGP4 + STARLETTE + 1975-010A + EARTH + TEME + UTC + SGP4 - - 2008-09-20T12:25:40.104192 - 15.72125391 - 0.0006703 - 51.6416 - 247.4627 - 130.5360 - 325.0288 - 398600.8 - - - 0 - U - 7646 - 999 - 32997 - -.47102E-5 - -.147E-5 - 0 - + + 2008-09-20T12:25:40.104192 + 15.72125391 + 0.0006703 + 51.6416 + 247.4627 + 130.5360 + 325.0288 + 398600.8 + + + 0 + U + 7646 + 999 + 32997 + -.47102E-5 + -.147E-5 + 0 + + + foo enters + a bar + @@ -1282,8 +1286,6 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - println!("{:#?}", message); - assert_eq!(message, OmmType { header: common::OdmHeader { @@ -1423,7 +1425,21 @@ mod test { }, ), covariance_matrix: None, - user_defined_parameters: None, + user_defined_parameters: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "foo enters".to_string(), + parameter: "FOO".to_string(), + }, + common::UserDefinedParameterType { + base: "a bar".to_string(), + parameter: "BAR".to_string(), + }, + ], + }, + ), }, }, }, From 4684bebc3251779992868280b6c3d0fed61f99ea Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:37:24 +0100 Subject: [PATCH 029/150] Add keplereian elements to OPM message test --- crates/lox-utils/src/odm/opm.rs | 159 ++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 61 deletions(-) diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index 4ce9818f..dff35e51 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -142,55 +142,64 @@ mod test { - GEOCENTRIC, CARTESIAN, EARTH FIXED - OSPREY 5 - 1998-999A - EARTH - TOD - 1998-12-18T14:28:15.1172 - UTC + GEOCENTRIC, CARTESIAN, EARTH FIXED + OSPREY 5 + 1998-999A + EARTH + TOD + 1998-12-18T14:28:15.1172 + UTC - - 1996-12-18T14:28:15.1172 - 6503.514000 - 1239.647000 - -717.490000 - -0.873160 - 8.740420 - -4.191076 - - - 3000.000000 - 18.770000 - 1.000000 - 18.770000 - 2.500000 - - - ITRF1997 - 0.316 - 0.722 - 0.518 - 0.202 - 0.715 - 0.002 - 0.912 - 0.306 - 0.276 - 0.797 - 0.562 - 0.899 - 0.022 - 0.079 - 0.415 - 0.245 - 0.965 - 0.950 - 0.435 - 0.621 - 0.991 - + + 2008-09-20T12:25:40.104192 + 4086.147180 + -994.936814 + 5250.678791 + 2.511071 + 7.255240 + -0.583165 + + + 6730.96 + 0.0006703 + 51.6416 + 247.463 + 130.536 + 324.985 + 398600.9368 + + + 3000.000000 + 18.770000 + 1.000000 + 18.770000 + 2.500000 + + + ITRF1997 + 0.316 + 0.722 + 0.518 + 0.202 + 0.715 + 0.002 + 0.912 + 0.306 + 0.276 + 0.797 + 0.562 + 0.899 + 0.022 + 0.079 + 0.415 + 0.245 + 0.965 + 0.950 + 0.435 + 0.621 + 0.991 + @@ -225,33 +234,61 @@ mod test { comment_list: vec![], state_vector: common::StateVectorType { comment_list: vec![], - epoch: common::EpochType("1996-12-18T14:28:15.1172".to_string(),), + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), x: common::PositionType { - base: 6503.514, - units: None, + base: 4086.14718, + units: Some(common::PositionUnits("km".to_string(),),), }, y: common::PositionType { - base: 1239.647, - units: None, + base: -994.936814, + units: Some(common::PositionUnits("km".to_string(),),), }, z: common::PositionType { - base: -717.49, - units: None, + base: 5250.678791, + units: Some(common::PositionUnits("km".to_string(),),), }, x_dot: common::VelocityType { - base: -0.87316, - units: None, + base: 2.511071, + units: Some(common::VelocityUnits("km/s".to_string(),),), }, y_dot: common::VelocityType { - base: 8.74042, - units: None, + base: 7.25524, + units: Some(common::VelocityUnits("km/s".to_string(),),), }, z_dot: common::VelocityType { - base: -4.191076, - units: None, + base: -0.583165, + units: Some(common::VelocityUnits("km/s".to_string(),),), }, }, - keplerian_elements: None, + keplerian_elements: Some(KeplerianElementsType { + comment_list: vec![], + semi_major_axis: common::DistanceType { + base: 6730.96, + units: Some(common::PositionUnits("km".to_string(),),), + }, + eccentricity: common::NonNegativeDouble(0.0006703,), + inclination: common::InclinationType { + base: common::InclinationRange(51.6416,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(247.463,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(130.536,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + true_anomaly: Some(common::AngleType { + base: common::AngleRange(324.985,), + units: Some(common::AngleUnits("deg".to_string(),),), + },), + mean_anomaly: None, + gm: common::GmType { + base: common::PositiveDouble(398600.9368,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + }, + },), spacecraft_parameters: Some(common::SpacecraftParametersType { comment_list: vec![], mass: Some(common::MassType { From 9762c2928933a5688d6617011021fc9da292c1f0 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Jan 2024 23:52:26 +0100 Subject: [PATCH 030/150] Add maneuver parameters to opm test --- crates/lox-utils/src/odm/opm.rs | 78 ++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/odm/opm.rs index dff35e51..ac217baf 100644 --- a/crates/lox-utils/src/odm/opm.rs +++ b/crates/lox-utils/src/odm/opm.rs @@ -200,6 +200,25 @@ mod test { 0.621 0.991 + + Maneuver 1 + 2008-09-20T12:41:09.984493 + 180.000 + -0.001 + RSW + 0.000000 + 0.280000 + 0.000000 + + + 2008-09-20T13:33:11.374985 + 180.000 + -0.001 + RSW + 0.000000 + 0.270000 + 0.000000 +
@@ -207,6 +226,8 @@ mod test { let message: OpmType = from_str(xml).unwrap(); + println!("{:#?}", message); + assert_eq!( message, OpmType { @@ -394,7 +415,62 @@ mod test { units: None, }, },), - maneuver_parameters_list: vec![], + maneuver_parameters_list: vec![ + ManeuverParametersType { + comment_list: vec!["Maneuver 1".to_string(),], + man_epoch_ignition: common::EpochType( + "2008-09-20T12:41:09.984493".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(180.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-0.001,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "RSW".to_string(), + man_dv_1: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 0.28, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + }, + ManeuverParametersType { + comment_list: vec![], + man_epoch_ignition: common::EpochType( + "2008-09-20T13:33:11.374985".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(180.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-0.001,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "RSW".to_string(), + man_dv_1: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 0.27, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + }, + ], user_defined_parameters: None, }, }, From 59d8240ad9442ae244eee1e50d0624bf0e7a8d93 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 17 Feb 2024 14:10:30 +0100 Subject: [PATCH 031/150] Add combined NDM element --- crates/lox-utils/src/odm.rs | 1 + crates/lox-utils/src/odm/ndm.rs | 610 ++++++++++++++++++++++++++++++++ crates/lox-utils/src/odm/omm.rs | 17 +- 3 files changed, 620 insertions(+), 8 deletions(-) create mode 100644 crates/lox-utils/src/odm/ndm.rs diff --git a/crates/lox-utils/src/odm.rs b/crates/lox-utils/src/odm.rs index eea3ebd2..ffe48ce3 100644 --- a/crates/lox-utils/src/odm.rs +++ b/crates/lox-utils/src/odm.rs @@ -1,4 +1,5 @@ pub mod common; +pub mod ndm; pub mod ocm; pub mod oem; pub mod omm; diff --git a/crates/lox-utils/src/odm/ndm.rs b/crates/lox-utils/src/odm/ndm.rs new file mode 100644 index 00000000..1fa05c7f --- /dev/null +++ b/crates/lox-utils/src/odm/ndm.rs @@ -0,0 +1,610 @@ +use serde; + +use super::{ocm, oem, omm, opm}; + +/// Combined instantiation type. Currently does not support AEM, APM, CDM, RDM, TDM +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NdmType { + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + + #[serde(rename = "ocm")] + pub ocm_list: Vec, + #[serde(rename = "oem")] + pub oem_list: Vec, + #[serde(rename = "omm")] + pub omm_list: Vec, + #[serde(rename = "opm")] + pub opm_list: Vec, +} + +mod test { + use super::super::common; + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_combined_ndm() { + let xml = r#" +bla +asdfg + +
+ + +
+ + + + +
+ +
+ + +
+ + + + NUSAT-2 (BATATA) + 2016-033C + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T15:27:01.975104 + 15.30610336 + .0011780 + 97.4090 + 71.7453 + 193.9419 + 272.1492 + + + 0 + U + 41558 + 999 + 25191 + .15913E-3 + 4.64E-5 + 0 + + + + +
+ +
+ + +
+ + + + NUSAT-13 (EMMY) + 2020-079G + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T13:30:01.539648 + 15.31433655 + .0009574 + 97.2663 + 51.2167 + 149.8567 + 322.5146 + + + 0 + U + 46833 + 999 + 434 + .14401E-3 + 4.301E-5 + 0 + + + + +
+ +
+ + +
+ + + + NUSAT-17 (MARY) + 2020-079J + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T16:27:08.698176 + 15.31317097 + .0009674 + 97.2671 + 51.3486 + 160.8608 + 302.2789 + + + 0 + U + 46835 + 999 + 436 + -.13273E-3 + -4.087E-5 + 0 + + + + +
+ +
+ + +
+ + + + NUSAT-18 (VERA) + 2020-079K + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T13:13:33.140064 + 15.32037173 + .0009024 + 97.2666 + 51.2301 + 167.2057 + 304.5569 + + + 0 + U + 46836 + 999 + 434 + .13328E-3 + 4.05E-5 + 0 + + + + +
+
"#; + + let message: NdmType = from_str(xml).unwrap(); + + assert_eq!( + message, + NdmType { + message_id: Some("bla".to_string()), + comment_list: vec!["asdfg".to_string()], + ocm_list: vec![], + oem_list: vec![], + omm_list: vec![ + omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "".to_string(), + object_id: "".to_string(), + center_name: "".to_string(), + ref_frame: "".to_string(), + ref_frame_epoch: None, + time_system: "".to_string(), + mean_element_theory: "".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType("".to_string()), + semi_major_axis: None, + mean_motion: None, + eccentricity: common::NonNegativeDouble(0.0), + inclination: common::InclinationType { + base: common::InclinationRange(0.0), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: None, + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }, + omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-2 (BATATA)".to_string(), + object_id: "2016-033C".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T15:27:01.975104".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.30610336, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.001178), + inclination: common::InclinationType { + base: common::InclinationRange(97.409), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(71.7453), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(193.9419), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(272.1492), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(41558), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(25191), + bstar: Some(omm::BStarType { + base: 0.00015913, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.64e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }, + omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-13 (EMMY)".to_string(), + object_id: "2020-079G".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T13:30:01.539648".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.31433655, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009574), + inclination: common::InclinationType { + base: common::InclinationRange(97.2663), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.2167), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(149.8567), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(322.5146), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46833), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(434), + bstar: Some(omm::BStarType { + base: 0.00014401, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.301e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }, + omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-17 (MARY)".to_string(), + object_id: "2020-079J".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T16:27:08.698176".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.31317097, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009674), + inclination: common::InclinationType { + base: common::InclinationRange(97.2671), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.3486), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(160.8608), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(302.2789), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46835), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(436), + bstar: Some(omm::BStarType { + base: -0.00013273, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: -4.087e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }, + omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-18 (VERA)".to_string(), + object_id: "2020-079K".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T13:13:33.140064".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.32037173, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009024), + inclination: common::InclinationType { + base: common::InclinationRange(97.2666), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.2301), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(167.2057), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(304.5569), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46836), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(434), + bstar: Some(omm::BStarType { + base: 0.00013328, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.05e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }, + ], + opm_list: vec![], + }, + ); + } +} diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/odm/omm.rs index 59ca9a5e..39201ac2 100644 --- a/crates/lox-utils/src/odm/omm.rs +++ b/crates/lox-utils/src/odm/omm.rs @@ -12,35 +12,35 @@ use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BStarUnits(#[serde(rename = "$text")] std::string::String); +pub struct BStarUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BTermUnits(#[serde(rename = "$text")] std::string::String); +pub struct BTermUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AgomUnits(#[serde(rename = "$text")] std::string::String); +pub struct AgomUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ElementSetNoType(#[serde(rename = "$text")] std::string::String); +pub struct ElementSetNoType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RevUnits(#[serde(rename = "$text")] std::string::String); +pub struct RevUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DRevUnits(#[serde(rename = "$text")] std::string::String); +pub struct DRevUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DdRevUnits(#[serde(rename = "$text")] std::string::String); +pub struct DdRevUnits(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct SpacewarnType(#[serde(rename = "$text")] std::string::String); +pub struct SpacewarnType(#[serde(rename = "$text")] pub std::string::String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -1478,4 +1478,5 @@ mod test { assert!(message.is_err()); } + } From 7deb4dec539c49f0149861b4961d5c6dbdbee1f7 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 17 Feb 2024 14:11:26 +0100 Subject: [PATCH 032/150] Rename folder to ndm --- crates/lox-utils/src/lib.rs | 2 +- crates/lox-utils/src/ndm.rs | 6 ++++++ crates/lox-utils/src/{odm => ndm}/common.rs | 0 crates/lox-utils/src/{odm => ndm}/ndm.rs | 0 crates/lox-utils/src/{odm => ndm}/ocm.rs | 0 crates/lox-utils/src/{odm => ndm}/oem.rs | 0 crates/lox-utils/src/{odm => ndm}/omm.rs | 0 crates/lox-utils/src/{odm => ndm}/opm.rs | 0 8 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 crates/lox-utils/src/ndm.rs rename crates/lox-utils/src/{odm => ndm}/common.rs (100%) rename crates/lox-utils/src/{odm => ndm}/ndm.rs (100%) rename crates/lox-utils/src/{odm => ndm}/ocm.rs (100%) rename crates/lox-utils/src/{odm => ndm}/oem.rs (100%) rename crates/lox-utils/src/{odm => ndm}/omm.rs (100%) rename crates/lox-utils/src/{odm => ndm}/opm.rs (100%) diff --git a/crates/lox-utils/src/lib.rs b/crates/lox-utils/src/lib.rs index 8a1065d4..b623a9a5 100644 --- a/crates/lox-utils/src/lib.rs +++ b/crates/lox-utils/src/lib.rs @@ -10,7 +10,7 @@ pub mod constants; pub mod is_close; pub mod linear_algebra; pub mod math; -pub mod odm; +pub mod ndm; pub mod series; pub mod slices; pub mod types; diff --git a/crates/lox-utils/src/ndm.rs b/crates/lox-utils/src/ndm.rs new file mode 100644 index 00000000..ffe48ce3 --- /dev/null +++ b/crates/lox-utils/src/ndm.rs @@ -0,0 +1,6 @@ +pub mod common; +pub mod ndm; +pub mod ocm; +pub mod oem; +pub mod omm; +pub mod opm; diff --git a/crates/lox-utils/src/odm/common.rs b/crates/lox-utils/src/ndm/common.rs similarity index 100% rename from crates/lox-utils/src/odm/common.rs rename to crates/lox-utils/src/ndm/common.rs diff --git a/crates/lox-utils/src/odm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs similarity index 100% rename from crates/lox-utils/src/odm/ndm.rs rename to crates/lox-utils/src/ndm/ndm.rs diff --git a/crates/lox-utils/src/odm/ocm.rs b/crates/lox-utils/src/ndm/ocm.rs similarity index 100% rename from crates/lox-utils/src/odm/ocm.rs rename to crates/lox-utils/src/ndm/ocm.rs diff --git a/crates/lox-utils/src/odm/oem.rs b/crates/lox-utils/src/ndm/oem.rs similarity index 100% rename from crates/lox-utils/src/odm/oem.rs rename to crates/lox-utils/src/ndm/oem.rs diff --git a/crates/lox-utils/src/odm/omm.rs b/crates/lox-utils/src/ndm/omm.rs similarity index 100% rename from crates/lox-utils/src/odm/omm.rs rename to crates/lox-utils/src/ndm/omm.rs diff --git a/crates/lox-utils/src/odm/opm.rs b/crates/lox-utils/src/ndm/opm.rs similarity index 100% rename from crates/lox-utils/src/odm/opm.rs rename to crates/lox-utils/src/ndm/opm.rs From 1c52c509846cac5798cc7bfdbb9acfe5a00fce17 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 17 Feb 2024 14:49:05 +0100 Subject: [PATCH 033/150] Implement support for mixed sequences --- crates/lox-utils/src/ndm/ndm.rs | 587 ++++++++++++++++++++++++++++++-- 1 file changed, 565 insertions(+), 22 deletions(-) diff --git a/crates/lox-utils/src/ndm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs index 1fa05c7f..d92dfa43 100644 --- a/crates/lox-utils/src/ndm/ndm.rs +++ b/crates/lox-utils/src/ndm/ndm.rs @@ -2,6 +2,22 @@ use serde; use super::{ocm, oem, omm, opm}; +#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde()] +pub enum NdmChildChoice { + #[serde(rename = "ocm")] + Ocm(ocm::OcmType), + + #[serde(rename = "oem")] + Oem(oem::OemType), + + #[serde(rename = "omm")] + Omm(omm::OmmType), + + #[serde(rename = "opm")] + Opm(opm::OpmType), +} + /// Combined instantiation type. Currently does not support AEM, APM, CDM, RDM, TDM #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -11,14 +27,8 @@ pub struct NdmType { #[serde(rename = "COMMENT")] pub comment_list: Vec, - #[serde(rename = "ocm")] - pub ocm_list: Vec, - #[serde(rename = "oem")] - pub oem_list: Vec, - #[serde(rename = "omm")] - pub omm_list: Vec, - #[serde(rename = "opm")] - pub opm_list: Vec, + #[serde(rename = "$value")] + pub child_list: Vec, } mod test { @@ -81,6 +91,160 @@ mod test {
+ +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + + + final COMMENT, I think + + 2004-100T00:00:00Z + 1 + 1 + 1 + 1 + 1 + 1 + + + 1 + 0 + 45 + 0 + 15 + 15 + 398644 + + + 100 + 2 + 1 + 2 + 2.0 + + + 2004-125T00:00:00Z + 0 + -1 + GRC + 1 + 1 + 1 + + + + +
+ + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + + + + this is a comment + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + This is a COMMENT + 100 + 2 + 1 + 2 + 2.0 + + + This is a COMMENT + 2004-125T00:00:00 + 0 + -1 + GRC + 1 + 1 + 1 + + + + +
+ + + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + 2004-100T00:00:00.000000 + 2004-100T01:00:00.000000 + Hermite + 1 + + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + + +
@@ -198,19 +362,19 @@ mod test { + "#; let message: NdmType = from_str(xml).unwrap(); + println!("{:#?}", message); assert_eq!( message, NdmType { message_id: Some("bla".to_string()), comment_list: vec!["asdfg".to_string()], - ocm_list: vec![], - oem_list: vec![], - omm_list: vec![ - omm::OmmType { + child_list: vec![ + NdmChildChoice::Omm(omm::OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], @@ -265,8 +429,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }, - omm::OmmType { + }), + NdmChildChoice::Omm(omm::OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], @@ -349,8 +513,388 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }, - omm::OmmType { + }), + NdmChildChoice::Opm(opm::OpmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string()), + originator: "me".to_string(), + message_id: None, + }, + body: opm::OpmBody { + segment: opm::OpmSegment { + metadata: opm::OpmMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + }, + data: opm::OpmData { + comment_list: vec!["final COMMENT, I think".to_string(),], + state_vector: common::StateVectorType { + comment_list: vec![], + epoch: common::EpochType("2004-100T00:00:00Z".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + }, + keplerian_elements: Some(opm::KeplerianElementsType { + comment_list: vec![], + semi_major_axis: common::DistanceType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + eccentricity: common::NonNegativeDouble(0.0,), + inclination: common::InclinationType { + base: common::InclinationRange(45.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(0.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(15.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + true_anomaly: Some(common::AngleType { + base: common::AngleRange(15.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + },), + mean_anomaly: None, + gm: common::GmType { + base: common::PositiveDouble(398644.0,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + }, + },), + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec![], + mass: Some(common::MassType { + base: common::NonNegativeDouble(100.0,), + units: Some(common::MassUnits("kg".to_string(),),), + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + drag_coeff: Some(common::NonNegativeDouble(2.0,),), + },), + covariance_matrix: None, + maneuver_parameters_list: vec![opm::ManeuverParametersType { + comment_list: vec![], + man_epoch_ignition: common::EpochType( + "2004-125T00:00:00Z".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(0.0,), + units: None, + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-1.0,), + units: None, + }, + man_ref_frame: "GRC".to_string(), + man_dv_1: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + },], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Opm(opm::OpmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: opm::OpmBody { + segment: opm::OpmSegment { + metadata: opm::OpmMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + }, + data: opm::OpmData { + comment_list: vec![], + state_vector: common::StateVectorType { + comment_list: vec!["this is a comment".to_string(),], + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + }, + keplerian_elements: None, + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec!["This is a COMMENT".to_string(),], + mass: Some(common::MassType { + base: common::NonNegativeDouble(100.0,), + units: None, + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: None, + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + drag_coeff: Some(common::NonNegativeDouble(2.0,),), + },), + covariance_matrix: None, + maneuver_parameters_list: vec![opm::ManeuverParametersType { + comment_list: vec!["This is a COMMENT".to_string(),], + man_epoch_ignition: common::EpochType( + "2004-125T00:00:00".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(0.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-1.0,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "GRC".to_string(), + man_dv_1: common::VelocityType { + base: 1.0, + units: None, + }, + man_dv_2: common::VelocityType { + base: 1.0, + units: None, + }, + man_dv_3: common::VelocityType { + base: 1.0, + units: None, + }, + },], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Oem(oem::OemType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: oem::OemBody { + segment_list: vec![oem::OemSegment { + metadata: oem::OemMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType( + "2004-100T00:00:00.000000".to_string(), + ), + useable_start_time: None, + useable_stop_time: None, + stop_time: common::EpochType( + "2004-100T01:00:00.000000".to_string(), + ), + interpolation: Some("Hermite".to_string(),), + interpolation_degree: Some(1,), + }, + data: oem::OemData { + comment_list: vec![], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + ], + covariance_matrix_list: vec![], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Omm(omm::OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], @@ -433,8 +977,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }, - omm::OmmType { + }), + NdmChildChoice::Omm(omm::OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], @@ -517,8 +1061,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }, - omm::OmmType { + }), + NdmChildChoice::Omm(omm::OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], @@ -601,9 +1145,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }, + }), ], - opm_list: vec![], }, ); } From a6bf2082bab70c35add7c84e8ed4b6db3562a944 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 19 Mar 2024 23:27:52 +0100 Subject: [PATCH 034/150] Move the xml parser to its own folder --- crates/lox-utils/src/ndm.rs | 7 +- crates/lox-utils/src/ndm/xml.rs | 6 + crates/lox-utils/src/ndm/xml/common.rs | 1146 ++++++++++++++++++ crates/lox-utils/src/ndm/xml/ndm.rs | 1153 ++++++++++++++++++ crates/lox-utils/src/ndm/xml/ocm.rs | 988 ++++++++++++++++ crates/lox-utils/src/ndm/xml/oem.rs | 684 +++++++++++ crates/lox-utils/src/ndm/xml/omm.rs | 1482 ++++++++++++++++++++++++ crates/lox-utils/src/ndm/xml/opm.rs | 517 +++++++++ 8 files changed, 5977 insertions(+), 6 deletions(-) create mode 100644 crates/lox-utils/src/ndm/xml.rs create mode 100644 crates/lox-utils/src/ndm/xml/common.rs create mode 100644 crates/lox-utils/src/ndm/xml/ndm.rs create mode 100644 crates/lox-utils/src/ndm/xml/ocm.rs create mode 100644 crates/lox-utils/src/ndm/xml/oem.rs create mode 100644 crates/lox-utils/src/ndm/xml/omm.rs create mode 100644 crates/lox-utils/src/ndm/xml/opm.rs diff --git a/crates/lox-utils/src/ndm.rs b/crates/lox-utils/src/ndm.rs index ffe48ce3..2910ec69 100644 --- a/crates/lox-utils/src/ndm.rs +++ b/crates/lox-utils/src/ndm.rs @@ -1,6 +1 @@ -pub mod common; -pub mod ndm; -pub mod ocm; -pub mod oem; -pub mod omm; -pub mod opm; +pub mod xml; diff --git a/crates/lox-utils/src/ndm/xml.rs b/crates/lox-utils/src/ndm/xml.rs new file mode 100644 index 00000000..ffe48ce3 --- /dev/null +++ b/crates/lox-utils/src/ndm/xml.rs @@ -0,0 +1,6 @@ +pub mod common; +pub mod ndm; +pub mod ocm; +pub mod oem; +pub mod omm; +pub mod opm; diff --git a/crates/lox-utils/src/ndm/xml/common.rs b/crates/lox-utils/src/ndm/xml/common.rs new file mode 100644 index 00000000..3aa1997b --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/common.rs @@ -0,0 +1,1146 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use serde; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AccUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRange(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngMomentumUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AreaUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DayIntervalUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct FrequencyUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GmUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct InclinationRange(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LengthUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MassUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MomentUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct WkgUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Ms2Units(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2Units(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2sUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2s2Units(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct VecDouble { + pub items: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec3Double(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec6Double(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Vec9Double(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct EpochType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeSystemType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NonPositiveDouble(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Range100Type(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ProbabilityType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentageUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct YesNoType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TrajBasisType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevNumBasisType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct CovBasisType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManBasisType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManDcType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NumPerYearUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ThrustUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct CovOrderType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GeomagUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SolarFluxUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatRange(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AltRange(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LonRange(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatLonUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ControlledType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DisintegrationType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionComponentType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotDirectionType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotseqType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleKeywordType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ApmRateFrameType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TorqueUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OdmHeader { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "CLASSIFICATION")] + pub classification_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: EpochType, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AccType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngleRateType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngMomentumType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: AngMomentumUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "REF_FRAME_A")] + pub ref_frame_a: String, + #[serde(rename = "REF_FRAME_B")] + pub ref_frame_b: String, + #[serde(rename = "ANGVEL_FRAME")] + pub angvel_frame: AngVelFrameType, + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AngVelType { + #[serde(rename = "ANGVEL_X")] + pub angvel_x: AngVelComponentType, + #[serde(rename = "ANGVEL_Y")] + pub angvel_y: AngVelComponentType, + #[serde(rename = "ANGVEL_Z")] + pub angvel_z: AngVelComponentType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AreaType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: DayIntervalUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmDayIntervalType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DeltamassType { + #[serde(rename = "$text")] + pub base: NegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DeltamassTypeZ { + #[serde(rename = "$text")] + pub base: NonPositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct FrequencyType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GmType { + #[serde(rename = "$text")] + pub base: PositiveDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct InclinationType { + #[serde(rename = "$text")] + pub base: InclinationRange, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: LengthUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmLengthType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MassType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MomentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct WkgType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: WkgUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TIME_LASTOB_START")] + pub time_lastob_start: Option, + #[serde(rename = "TIME_LASTOB_END")] + pub time_lastob_end: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "RESIDUALS_ACCEPTED")] + pub residuals_accepted: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MASS")] + pub mass: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct StateVectorType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct StateVectorAccType { + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "X")] + pub x: PositionType, + #[serde(rename = "Y")] + pub y: PositionType, + #[serde(rename = "Z")] + pub z: PositionType, + #[serde(rename = "X_DOT")] + pub x_dot: VelocityType, + #[serde(rename = "Y_DOT")] + pub y_dot: VelocityType, + #[serde(rename = "Z_DOT")] + pub z_dot: VelocityType, + #[serde(rename = "X_DDOT")] + pub x_ddot: Option, + #[serde(rename = "Y_DDOT")] + pub y_ddot: Option, + #[serde(rename = "Z_DDOT")] + pub z_ddot: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Ms2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Ms2Units, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2sType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct Km2s2Type { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DistanceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmPositionType { + #[serde(rename = "$text")] + pub base: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmVelocityType { + #[serde(rename = "$text")] + pub base: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DurationType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RelTimeType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TimeOffsetType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PercentageType { + #[serde(rename = "$text")] + pub base: Range100Type, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManeuverFreqType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ThrustType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GeomagType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SolarFluxType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemCovarianceMatrixType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: EpochType, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmCovarianceMatrixType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, + #[serde(rename = "CX_X")] + pub cx_x: PositionCovarianceType, + #[serde(rename = "CY_X")] + pub cy_x: PositionCovarianceType, + #[serde(rename = "CY_Y")] + pub cy_y: PositionCovarianceType, + #[serde(rename = "CZ_X")] + pub cz_x: PositionCovarianceType, + #[serde(rename = "CZ_Y")] + pub cz_y: PositionCovarianceType, + #[serde(rename = "CZ_Z")] + pub cz_z: PositionCovarianceType, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: PositionVelocityCovarianceType, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: VelocityCovarianceType, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: VelocityCovarianceType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct VelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct PositionVelocityCovarianceType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AtmosphericReentryParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ORBIT_LIFETIME")] + pub orbit_lifetime: DayIntervalType, + #[serde(rename = "REENTRY_ALTITUDE")] + pub reentry_altitude: PositionType, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] + pub orbit_lifetime_window_start: Option, + #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] + pub orbit_lifetime_window_end: Option, + #[serde(rename = "NOMINAL_REENTRY_EPOCH")] + pub nominal_reentry_epoch: Option, + #[serde(rename = "REENTRY_WINDOW_START")] + pub reentry_window_start: Option, + #[serde(rename = "REENTRY_WINDOW_END")] + pub reentry_window_end: Option, + #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] + pub orbit_lifetime_confidence_level: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct GroundImpactParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "PROBABILITY_OF_IMPACT")] + pub probability_of_impact: Option, + #[serde(rename = "PROBABILITY_OF_BURN_UP")] + pub probability_of_burn_up: Option, + #[serde(rename = "PROBABILITY_OF_BREAK_UP")] + pub probability_of_break_up: Option, + #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] + pub probability_of_land_impact: Option, + #[serde(rename = "PROBABILITY_OF_CASUALTY")] + pub probability_of_casualty: Option, + #[serde(rename = "NOMINAL_IMPACT_EPOCH")] + pub nominal_impact_epoch: Option, + #[serde(rename = "IMPACT_WINDOW_START")] + pub impact_window_start: Option, + #[serde(rename = "IMPACT_WINDOW_END")] + pub impact_window_end: Option, + #[serde(rename = "IMPACT_REF_FRAME")] + pub impact_ref_frame: Option, + #[serde(rename = "NOMINAL_IMPACT_LON")] + pub nominal_impact_lon: Option, + #[serde(rename = "NOMINAL_IMPACT_LAT")] + pub nominal_impact_lat: Option, + #[serde(rename = "NOMINAL_IMPACT_ALT")] + pub nominal_impact_alt: Option, + #[serde(rename = "IMPACT_1_CONFIDENCE")] + pub impact_1_confidence: Option, + #[serde(rename = "IMPACT_1_START_LON")] + pub impact_1_start_lon: Option, + #[serde(rename = "IMPACT_1_START_LAT")] + pub impact_1_start_lat: Option, + #[serde(rename = "IMPACT_1_STOP_LON")] + pub impact_1_stop_lon: Option, + #[serde(rename = "IMPACT_1_STOP_LAT")] + pub impact_1_stop_lat: Option, + #[serde(rename = "IMPACT_1_CROSS_TRACK")] + pub impact_1_cross_track: Option, + #[serde(rename = "IMPACT_2_CONFIDENCE")] + pub impact_2_confidence: Option, + #[serde(rename = "IMPACT_2_START_LON")] + pub impact_2_start_lon: Option, + #[serde(rename = "IMPACT_2_START_LAT")] + pub impact_2_start_lat: Option, + #[serde(rename = "IMPACT_2_STOP_LON")] + pub impact_2_stop_lon: Option, + #[serde(rename = "IMPACT_2_STOP_LAT")] + pub impact_2_stop_lat: Option, + #[serde(rename = "IMPACT_2_CROSS_TRACK")] + pub impact_2_cross_track: Option, + #[serde(rename = "IMPACT_3_CONFIDENCE")] + pub impact_3_confidence: Option, + #[serde(rename = "IMPACT_3_START_LON")] + pub impact_3_start_lon: Option, + #[serde(rename = "IMPACT_3_START_LAT")] + pub impact_3_start_lat: Option, + #[serde(rename = "IMPACT_3_STOP_LON")] + pub impact_3_stop_lon: Option, + #[serde(rename = "IMPACT_3_STOP_LAT")] + pub impact_3_stop_lat: Option, + #[serde(rename = "IMPACT_3_CROSS_TRACK")] + pub impact_3_cross_track: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RdmSpacecraftParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "HAZARDOUS_SUBSTANCES")] + pub hazardous_substances: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "BALLISTIC_COEFF")] + pub ballistic_coeff: Option, + #[serde(rename = "THRUST_ACCELERATION")] + pub thrust_acceleration: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AltType { + #[serde(rename = "$text")] + pub base: AltRange, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BallisticCoeffType { + #[serde(rename = "$text")] + pub base: NonNegativeDouble, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LatType { + #[serde(rename = "$text")] + pub base: LatRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LonType { + #[serde(rename = "$text")] + pub base: LonRange, + #[serde(rename = "@units")] + pub units: LatLonUnits, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct UserDefinedType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "USER_DEFINED")] + pub user_defined_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct UserDefinedParameterType { + #[serde(rename = "$text")] + pub base: String, + #[serde(rename = "@parameter")] + pub parameter: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionType {} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionRateType {} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct QuaternionDotType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleType { + #[serde(rename = "rotation1")] + pub rotation1: RotationAngleComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationAngleComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationAngleComponentType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleComponentTypeold { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@value")] + pub value: AngleRange, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationAngleComponentType { + #[serde(rename = "$text")] + pub base: AngleRange, + #[serde(rename = "@angle")] + pub angle: AngleKeywordType, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateType { + #[serde(rename = "rotation1")] + pub rotation1: RotationRateComponentType, + #[serde(rename = "rotation2")] + pub rotation2: RotationRateComponentType, + #[serde(rename = "rotation3")] + pub rotation3: RotationRateComponentType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateComponentTypeOld { + #[serde(rename = "@units")] + pub units: Option, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@value")] + pub value: f64, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RotationRateComponentType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@rate")] + pub rate: AngleRateKeywordType, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TorqueType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} diff --git a/crates/lox-utils/src/ndm/xml/ndm.rs b/crates/lox-utils/src/ndm/xml/ndm.rs new file mode 100644 index 00000000..d92dfa43 --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/ndm.rs @@ -0,0 +1,1153 @@ +use serde; + +use super::{ocm, oem, omm, opm}; + +#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde()] +pub enum NdmChildChoice { + #[serde(rename = "ocm")] + Ocm(ocm::OcmType), + + #[serde(rename = "oem")] + Oem(oem::OemType), + + #[serde(rename = "omm")] + Omm(omm::OmmType), + + #[serde(rename = "opm")] + Opm(opm::OpmType), +} + +/// Combined instantiation type. Currently does not support AEM, APM, CDM, RDM, TDM +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct NdmType { + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + + #[serde(rename = "$value")] + pub child_list: Vec, +} + +mod test { + use super::super::common; + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_combined_ndm() { + let xml = r#" +bla +asdfg + +
+ + +
+ + + + +
+ +
+ + +
+ + + + NUSAT-2 (BATATA) + 2016-033C + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T15:27:01.975104 + 15.30610336 + .0011780 + 97.4090 + 71.7453 + 193.9419 + 272.1492 + + + 0 + U + 41558 + 999 + 25191 + .15913E-3 + 4.64E-5 + 0 + + + + +
+ +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + + + final COMMENT, I think + + 2004-100T00:00:00Z + 1 + 1 + 1 + 1 + 1 + 1 + + + 1 + 0 + 45 + 0 + 15 + 15 + 398644 + + + 100 + 2 + 1 + 2 + 2.0 + + + 2004-125T00:00:00Z + 0 + -1 + GRC + 1 + 1 + 1 + + + + +
+ + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + + + + this is a comment + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + This is a COMMENT + 100 + 2 + 1 + 2 + 2.0 + + + This is a COMMENT + 2004-125T00:00:00 + 0 + -1 + GRC + 1 + 1 + 1 + + + + +
+ + + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + 2004-100T00:00:00.000000 + 2004-100T01:00:00.000000 + Hermite + 1 + + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + + +
+ +
+ + +
+ + + + NUSAT-13 (EMMY) + 2020-079G + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T13:30:01.539648 + 15.31433655 + .0009574 + 97.2663 + 51.2167 + 149.8567 + 322.5146 + + + 0 + U + 46833 + 999 + 434 + .14401E-3 + 4.301E-5 + 0 + + + + +
+ +
+ + +
+ + + + NUSAT-17 (MARY) + 2020-079J + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T16:27:08.698176 + 15.31317097 + .0009674 + 97.2671 + 51.3486 + 160.8608 + 302.2789 + + + 0 + U + 46835 + 999 + 436 + -.13273E-3 + -4.087E-5 + 0 + + + + +
+ +
+ + +
+ + + + NUSAT-18 (VERA) + 2020-079K + EARTH + TEME + UTC + SGP4 + + + + 2020-12-04T13:13:33.140064 + 15.32037173 + .0009024 + 97.2666 + 51.2301 + 167.2057 + 304.5569 + + + 0 + U + 46836 + 999 + 434 + .13328E-3 + 4.05E-5 + 0 + + + + +
+ +
"#; + + let message: NdmType = from_str(xml).unwrap(); + + println!("{:#?}", message); + assert_eq!( + message, + NdmType { + message_id: Some("bla".to_string()), + comment_list: vec!["asdfg".to_string()], + child_list: vec![ + NdmChildChoice::Omm(omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "".to_string(), + object_id: "".to_string(), + center_name: "".to_string(), + ref_frame: "".to_string(), + ref_frame_epoch: None, + time_system: "".to_string(), + mean_element_theory: "".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType("".to_string()), + semi_major_axis: None, + mean_motion: None, + eccentricity: common::NonNegativeDouble(0.0), + inclination: common::InclinationType { + base: common::InclinationRange(0.0), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(0.0), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: None, + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }), + NdmChildChoice::Omm(omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-2 (BATATA)".to_string(), + object_id: "2016-033C".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T15:27:01.975104".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.30610336, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.001178), + inclination: common::InclinationType { + base: common::InclinationRange(97.409), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(71.7453), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(193.9419), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(272.1492), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(41558), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(25191), + bstar: Some(omm::BStarType { + base: 0.00015913, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.64e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }), + NdmChildChoice::Opm(opm::OpmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string()), + originator: "me".to_string(), + message_id: None, + }, + body: opm::OpmBody { + segment: opm::OpmSegment { + metadata: opm::OpmMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + }, + data: opm::OpmData { + comment_list: vec!["final COMMENT, I think".to_string(),], + state_vector: common::StateVectorType { + comment_list: vec![], + epoch: common::EpochType("2004-100T00:00:00Z".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + }, + keplerian_elements: Some(opm::KeplerianElementsType { + comment_list: vec![], + semi_major_axis: common::DistanceType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + eccentricity: common::NonNegativeDouble(0.0,), + inclination: common::InclinationType { + base: common::InclinationRange(45.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(0.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(15.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + true_anomaly: Some(common::AngleType { + base: common::AngleRange(15.0,), + units: Some(common::AngleUnits("deg".to_string(),),), + },), + mean_anomaly: None, + gm: common::GmType { + base: common::PositiveDouble(398644.0,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + }, + },), + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec![], + mass: Some(common::MassType { + base: common::NonNegativeDouble(100.0,), + units: Some(common::MassUnits("kg".to_string(),),), + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + drag_coeff: Some(common::NonNegativeDouble(2.0,),), + },), + covariance_matrix: None, + maneuver_parameters_list: vec![opm::ManeuverParametersType { + comment_list: vec![], + man_epoch_ignition: common::EpochType( + "2004-125T00:00:00Z".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(0.0,), + units: None, + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-1.0,), + units: None, + }, + man_ref_frame: "GRC".to_string(), + man_dv_1: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + },], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Opm(opm::OpmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: opm::OpmBody { + segment: opm::OpmSegment { + metadata: opm::OpmMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + }, + data: opm::OpmData { + comment_list: vec![], + state_vector: common::StateVectorType { + comment_list: vec!["this is a comment".to_string(),], + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + }, + keplerian_elements: None, + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec!["This is a COMMENT".to_string(),], + mass: Some(common::MassType { + base: common::NonNegativeDouble(100.0,), + units: None, + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: None, + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(2.0,), + units: Some(common::AreaUnits("m**2".to_string(),),), + },), + drag_coeff: Some(common::NonNegativeDouble(2.0,),), + },), + covariance_matrix: None, + maneuver_parameters_list: vec![opm::ManeuverParametersType { + comment_list: vec!["This is a COMMENT".to_string(),], + man_epoch_ignition: common::EpochType( + "2004-125T00:00:00".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(0.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-1.0,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "GRC".to_string(), + man_dv_1: common::VelocityType { + base: 1.0, + units: None, + }, + man_dv_2: common::VelocityType { + base: 1.0, + units: None, + }, + man_dv_3: common::VelocityType { + base: 1.0, + units: None, + }, + },], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Oem(oem::OemType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: oem::OemBody { + segment_list: vec![oem::OemSegment { + metadata: oem::OemMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType( + "2004-100T00:00:00.000000".to_string(), + ), + useable_start_time: None, + useable_stop_time: None, + stop_time: common::EpochType( + "2004-100T01:00:00.000000".to_string(), + ), + interpolation: Some("Hermite".to_string(),), + interpolation_degree: Some(1,), + }, + data: oem::OemData { + comment_list: vec![], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType( + "2004-100T00:00:00".to_string(), + ), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits( + "km".to_string(), + ),), + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits( + "km/s".to_string(), + ),), + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + ], + covariance_matrix_list: vec![], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "2.0".to_string(), + },), + NdmChildChoice::Omm(omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-13 (EMMY)".to_string(), + object_id: "2020-079G".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T13:30:01.539648".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.31433655, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009574), + inclination: common::InclinationType { + base: common::InclinationRange(97.2663), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.2167), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(149.8567), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(322.5146), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46833), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(434), + bstar: Some(omm::BStarType { + base: 0.00014401, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.301e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }), + NdmChildChoice::Omm(omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-17 (MARY)".to_string(), + object_id: "2020-079J".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T16:27:08.698176".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.31317097, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009674), + inclination: common::InclinationType { + base: common::InclinationRange(97.2671), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.3486), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(160.8608), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(302.2789), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46835), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(436), + bstar: Some(omm::BStarType { + base: -0.00013273, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: -4.087e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }), + NdmChildChoice::Omm(omm::OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("".to_string()), + originator: "".to_string(), + message_id: None, + }, + body: omm::OmmBody { + segment: omm::OmmSegment { + metadata: omm::OmmMetadata { + comment_list: vec![], + object_name: "NUSAT-18 (VERA)".to_string(), + object_id: "2020-079K".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: omm::OmmData { + comment_list: vec![], + mean_elements: omm::MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2020-12-04T13:13:33.140064".to_string() + ), + semi_major_axis: None, + mean_motion: Some(omm::RevType { + base: 15.32037173, + units: None, + }), + eccentricity: common::NonNegativeDouble(0.0009024), + inclination: common::InclinationType { + base: common::InclinationRange(97.2666), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(51.2301), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(167.2057), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange(304.5569), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some(omm::TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0), + classification_type: Some("U".to_string()), + norad_cat_id: Some(46836), + element_set_no: Some(omm::ElementSetNoType( + "999".to_string() + )), + rev_at_epoch: Some(434), + bstar: Some(omm::BStarType { + base: 0.00013328, + units: None, + }), + bterm: None, + mean_motion_dot: omm::DRevType { + base: 4.05e-5, + units: None, + }, + mean_motion_ddot: Some(omm::DRevType { + base: 0.0, + units: None, + }), + agom: None, + }), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }), + ], + }, + ); + } +} diff --git a/crates/lox-utils/src/ndm/xml/ocm.rs b/crates/lox-utils/src/ndm/xml/ocm.rs new file mode 100644 index 00000000..ce80d144 --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/ocm.rs @@ -0,0 +1,988 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use serde; + +use super::common; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OcmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmBody { + #[serde(rename = "segment")] + pub segment: OcmSegment, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmSegment { + #[serde(rename = "metadata")] + pub metadata: OcmMetadata, + #[serde(rename = "data")] + pub data: OcmData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: Option, + #[serde(rename = "INTERNATIONAL_DESIGNATOR")] + pub international_designator: Option, + #[serde(rename = "CATALOG_NAME")] + pub catalog_name: Option, + #[serde(rename = "OBJECT_DESIGNATOR")] + pub object_designator: Option, + #[serde(rename = "ALTERNATE_NAMES")] + pub alternate_names: Option, + #[serde(rename = "ORIGINATOR_POC")] + pub originator_poc: Option, + #[serde(rename = "ORIGINATOR_POSITION")] + pub originator_position: Option, + #[serde(rename = "ORIGINATOR_PHONE")] + pub originator_phone: Option, + #[serde(rename = "ORIGINATOR_EMAIL")] + pub originator_email: Option, + #[serde(rename = "ORIGINATOR_ADDRESS")] + pub originator_address: Option, + #[serde(rename = "TECH_ORG")] + pub tech_org: Option, + #[serde(rename = "TECH_POC")] + pub tech_poc: Option, + #[serde(rename = "TECH_POSITION")] + pub tech_position: Option, + #[serde(rename = "TECH_PHONE")] + pub tech_phone: Option, + #[serde(rename = "TECH_EMAIL")] + pub tech_email: Option, + #[serde(rename = "TECH_ADDRESS")] + pub tech_address: Option, + #[serde(rename = "PREVIOUS_MESSAGE_ID")] + pub previous_message_id: Option, + #[serde(rename = "NEXT_MESSAGE_ID")] + pub next_message_id: Option, + #[serde(rename = "ADM_MSG_LINK")] + pub adm_msg_link: Option, + #[serde(rename = "CDM_MSG_LINK")] + pub cdm_msg_link: Option, + #[serde(rename = "PRM_MSG_LINK")] + pub prm_msg_link: Option, + #[serde(rename = "RDM_MSG_LINK")] + pub rdm_msg_link: Option, + #[serde(rename = "TDM_MSG_LINK")] + pub tdm_msg_link: Option, + #[serde(rename = "OPERATOR")] + pub operator: Option, + #[serde(rename = "OWNER")] + pub owner: Option, + #[serde(rename = "COUNTRY")] + pub country: Option, + #[serde(rename = "CONSTELLATION")] + pub constellation: Option, + #[serde(rename = "OBJECT_TYPE")] + pub object_type: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "EPOCH_TZERO")] + pub epoch_tzero: common::EpochType, + #[serde(rename = "OPS_STATUS")] + pub ops_status: Option, + #[serde(rename = "ORBIT_CATEGORY")] + pub orbit_category: Option, + #[serde(rename = "OCM_DATA_ELEMENTS")] + pub ocm_data_elements: Option, + #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] + pub sclk_offset_at_epoch: Option, + #[serde(rename = "SCLK_SEC_PER_SI_SEC")] + pub sclk_sec_per_si_sec: Option, + #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] + pub previous_message_epoch: Option, + #[serde(rename = "NEXT_MESSAGE_EPOCH")] + pub next_message_epoch: Option, + #[serde(rename = "START_TIME")] + pub start_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: Option, + #[serde(rename = "TIME_SPAN")] + pub time_span: Option, + #[serde(rename = "TAIMUTC_AT_TZERO")] + pub taimutc_at_tzero: Option, + #[serde(rename = "NEXT_LEAP_EPOCH")] + pub next_leap_epoch: Option, + #[serde(rename = "NEXT_LEAP_TAIMUTC")] + pub next_leap_taimutc: Option, + #[serde(rename = "UT1MUTC_AT_TZERO")] + pub ut1mutc_at_tzero: Option, + #[serde(rename = "EOP_SOURCE")] + pub eop_source: Option, + #[serde(rename = "INTERP_METHOD_EOP")] + pub interp_method_eop: Option, + #[serde(rename = "CELESTIAL_SOURCE")] + pub celestial_source: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmData { + #[serde(rename = "traj")] + pub traj_list: Vec, + #[serde(rename = "phys")] + pub phys: Option, + #[serde(rename = "cov")] + pub cov_list: Vec, + #[serde(rename = "man")] + pub man_list: Vec, + #[serde(rename = "pert")] + pub pert: Option, + #[serde(rename = "od")] + pub od: Option, + #[serde(rename = "user")] + pub user: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmTrajStateType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "TRAJ_ID")] + pub traj_id: Option, + #[serde(rename = "TRAJ_PREV_ID")] + pub traj_prev_id: Option, + #[serde(rename = "TRAJ_NEXT_ID")] + pub traj_next_id: Option, + #[serde(rename = "TRAJ_BASIS")] + pub traj_basis: Option, + #[serde(rename = "TRAJ_BASIS_ID")] + pub traj_basis_id: Option, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, + #[serde(rename = "PROPAGATOR")] + pub propagator: Option, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "TRAJ_REF_FRAME")] + pub traj_ref_frame: String, + #[serde(rename = "TRAJ_FRAME_EPOCH")] + pub traj_frame_epoch: Option, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "ORB_REVNUM")] + pub orb_revnum: Option, + #[serde(rename = "ORB_REVNUM_BASIS")] + pub orb_revnum_basis: Option, + #[serde(rename = "TRAJ_TYPE")] + pub traj_type: String, + #[serde(rename = "ORB_AVERAGING")] + pub orb_averaging: Option, + #[serde(rename = "TRAJ_UNITS")] + pub traj_units: Option, + #[serde(rename = "trajLine")] + pub traj_line_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmPhysicalDescriptionType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MANUFACTURER")] + pub manufacturer: Option, + #[serde(rename = "BUS_MODEL")] + pub bus_model: Option, + #[serde(rename = "DOCKED_WITH")] + pub docked_with: Option, + #[serde(rename = "DRAG_CONST_AREA")] + pub drag_const_area: Option, + #[serde(rename = "DRAG_COEFF_NOM")] + pub drag_coeff_nom: Option, + #[serde(rename = "DRAG_UNCERTAINTY")] + pub drag_uncertainty: Option, + #[serde(rename = "INITIAL_WET_MASS")] + pub initial_wet_mass: Option, + #[serde(rename = "WET_MASS")] + pub wet_mass: Option, + #[serde(rename = "DRY_MASS")] + pub dry_mass: Option, + #[serde(rename = "OEB_PARENT_FRAME")] + pub oeb_parent_frame: Option, + #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] + pub oeb_parent_frame_epoch: Option, + #[serde(rename = "OEB_Q1")] + pub oeb_q1: Option, + #[serde(rename = "OEB_Q2")] + pub oeb_q2: Option, + #[serde(rename = "OEB_Q3")] + pub oeb_q3: Option, + #[serde(rename = "OEB_QC")] + pub oeb_qc: Option, + #[serde(rename = "OEB_MAX")] + pub oeb_max: Option, + #[serde(rename = "OEB_INT")] + pub oeb_int: Option, + #[serde(rename = "OEB_MIN")] + pub oeb_min: Option, + #[serde(rename = "AREA_ALONG_OEB_MAX")] + pub area_along_oeb_max: Option, + #[serde(rename = "AREA_ALONG_OEB_INT")] + pub area_along_oeb_int: Option, + #[serde(rename = "AREA_ALONG_OEB_MIN")] + pub area_along_oeb_min: Option, + #[serde(rename = "AREA_MIN_FOR_PC")] + pub area_min_for_pc: Option, + #[serde(rename = "AREA_MAX_FOR_PC")] + pub area_max_for_pc: Option, + #[serde(rename = "AREA_TYP_FOR_PC")] + pub area_typ_for_pc: Option, + #[serde(rename = "RCS")] + pub rcs: Option, + #[serde(rename = "RCS_MIN")] + pub rcs_min: Option, + #[serde(rename = "RCS_MAX")] + pub rcs_max: Option, + #[serde(rename = "SRP_CONST_AREA")] + pub srp_const_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] + pub solar_rad_uncertainty: Option, + #[serde(rename = "VM_ABSOLUTE")] + pub vm_absolute: Option, + #[serde(rename = "VM_APPARENT_MIN")] + pub vm_apparent_min: Option, + #[serde(rename = "VM_APPARENT")] + pub vm_apparent: Option, + #[serde(rename = "VM_APPARENT_MAX")] + pub vm_apparent_max: Option, + #[serde(rename = "REFLECTANCE")] + pub reflectance: Option, + #[serde(rename = "ATT_CONTROL_MODE")] + pub att_control_mode: Option, + #[serde(rename = "ATT_ACTUATOR_TYPE")] + pub att_actuator_type: Option, + #[serde(rename = "ATT_KNOWLEDGE")] + pub att_knowledge: Option, + #[serde(rename = "ATT_CONTROL")] + pub att_control: Option, + #[serde(rename = "ATT_POINTING")] + pub att_pointing: Option, + #[serde(rename = "AVG_MANEUVER_FREQ")] + pub avg_maneuver_freq: Option, + #[serde(rename = "MAX_THRUST")] + pub max_thrust: Option, + #[serde(rename = "DV_BOL")] + pub dv_bol: Option, + #[serde(rename = "DV_REMAINING")] + pub dv_remaining: Option, + #[serde(rename = "IXX")] + pub ixx: Option, + #[serde(rename = "IYY")] + pub iyy: Option, + #[serde(rename = "IZZ")] + pub izz: Option, + #[serde(rename = "IXY")] + pub ixy: Option, + #[serde(rename = "IXZ")] + pub ixz: Option, + #[serde(rename = "IYZ")] + pub iyz: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmCovarianceMatrixType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "COV_ID")] + pub cov_id: Option, + #[serde(rename = "COV_PREV_ID")] + pub cov_prev_id: Option, + #[serde(rename = "COV_NEXT_ID")] + pub cov_next_id: Option, + #[serde(rename = "COV_BASIS")] + pub cov_basis: Option, + #[serde(rename = "COV_BASIS_ID")] + pub cov_basis_id: Option, + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: String, + #[serde(rename = "COV_FRAME_EPOCH")] + pub cov_frame_epoch: Option, + #[serde(rename = "COV_SCALE_MIN")] + pub cov_scale_min: Option, + #[serde(rename = "COV_SCALE_MAX")] + pub cov_scale_max: Option, + #[serde(rename = "COV_CONFIDENCE")] + pub cov_confidence: Option, + #[serde(rename = "COV_TYPE")] + pub cov_type: String, + #[serde(rename = "COV_ORDERING")] + pub cov_ordering: common::CovOrderType, + #[serde(rename = "COV_UNITS")] + pub cov_units: Option, + #[serde(rename = "covLine")] + pub cov_line_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_ID")] + pub man_id: String, + #[serde(rename = "MAN_PREV_ID")] + pub man_prev_id: Option, + #[serde(rename = "MAN_NEXT_ID")] + pub man_next_id: Option, + #[serde(rename = "MAN_BASIS")] + pub man_basis: Option, + #[serde(rename = "MAN_BASIS_ID")] + pub man_basis_id: Option, + #[serde(rename = "MAN_DEVICE_ID")] + pub man_device_id: String, + #[serde(rename = "MAN_PREV_EPOCH")] + pub man_prev_epoch: Option, + #[serde(rename = "MAN_NEXT_EPOCH")] + pub man_next_epoch: Option, + #[serde(rename = "MAN_PURPOSE")] + pub man_purpose: Option, + #[serde(rename = "MAN_PRED_SOURCE")] + pub man_pred_source: Option, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_FRAME_EPOCH")] + pub man_frame_epoch: Option, + #[serde(rename = "GRAV_ASSIST_NAME")] + pub grav_assist_name: Option, + #[serde(rename = "DC_TYPE")] + pub dc_type: common::ManDcType, + #[serde(rename = "DC_WIN_OPEN")] + pub dc_win_open: Option, + #[serde(rename = "DC_WIN_CLOSE")] + pub dc_win_close: Option, + #[serde(rename = "DC_MIN_CYCLES")] + pub dc_min_cycles: Option, + #[serde(rename = "DC_MAX_CYCLES")] + pub dc_max_cycles: Option, + #[serde(rename = "DC_EXEC_START")] + pub dc_exec_start: Option, + #[serde(rename = "DC_EXEC_STOP")] + pub dc_exec_stop: Option, + #[serde(rename = "DC_REF_TIME")] + pub dc_ref_time: Option, + #[serde(rename = "DC_TIME_PULSE_DURATION")] + pub dc_time_pulse_duration: Option, + #[serde(rename = "DC_TIME_PULSE_PERIOD")] + pub dc_time_pulse_period: Option, + #[serde(rename = "DC_REF_DIR")] + pub dc_ref_dir: Option, + #[serde(rename = "DC_BODY_FRAME")] + pub dc_body_frame: Option, + #[serde(rename = "DC_BODY_TRIGGER")] + pub dc_body_trigger: Option, + #[serde(rename = "DC_PA_START_ANGLE")] + pub dc_pa_start_angle: Option, + #[serde(rename = "DC_PA_STOP_ANGLE")] + pub dc_pa_stop_angle: Option, + #[serde(rename = "MAN_COMPOSITION")] + pub man_composition: String, + #[serde(rename = "MAN_UNITS")] + pub man_units: Option, + #[serde(rename = "manLine")] + pub man_line_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmPerturbationsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "ATMOSPHERIC_MODEL")] + pub atmospheric_model: Option, + #[serde(rename = "GRAVITY_MODEL")] + pub gravity_model: Option, + #[serde(rename = "EQUATORIAL_RADIUS")] + pub equatorial_radius: Option, + #[serde(rename = "GM")] + pub gm: Option, + #[serde(rename = "N_BODY_PERTURBATIONS")] + pub n_body_perturbations: Option, + #[serde(rename = "CENTRAL_BODY_ROTATION")] + pub central_body_rotation: Option, + #[serde(rename = "OBLATE_FLATTENING")] + pub oblate_flattening: Option, + #[serde(rename = "OCEAN_TIDES_MODEL")] + pub ocean_tides_model: Option, + #[serde(rename = "SOLID_TIDES_MODEL")] + pub solid_tides_model: Option, + #[serde(rename = "REDUCTION_THEORY")] + pub reduction_theory: Option, + #[serde(rename = "ALBEDO_MODEL")] + pub albedo_model: Option, + #[serde(rename = "ALBEDO_GRID_SIZE")] + pub albedo_grid_size: Option, + #[serde(rename = "SHADOW_MODEL")] + pub shadow_model: Option, + #[serde(rename = "SHADOW_BODIES")] + pub shadow_bodies: Option, + #[serde(rename = "SRP_MODEL")] + pub srp_model: Option, + #[serde(rename = "SW_DATA_SOURCE")] + pub sw_data_source: Option, + #[serde(rename = "SW_DATA_EPOCH")] + pub sw_data_epoch: Option, + #[serde(rename = "SW_INTERP_METHOD")] + pub sw_interp_method: Option, + #[serde(rename = "FIXED_GEOMAG_KP")] + pub fixed_geomag_kp: Option, + #[serde(rename = "FIXED_GEOMAG_AP")] + pub fixed_geomag_ap: Option, + #[serde(rename = "FIXED_GEOMAG_DST")] + pub fixed_geomag_dst: Option, + #[serde(rename = "FIXED_F10P7")] + pub fixed_f10p7: Option, + #[serde(rename = "FIXED_F10P7_MEAN")] + pub fixed_f10p7_mean: Option, + #[serde(rename = "FIXED_M10P7")] + pub fixed_m10p7: Option, + #[serde(rename = "FIXED_M10P7_MEAN")] + pub fixed_m10p7_mean: Option, + #[serde(rename = "FIXED_S10P7")] + pub fixed_s10p7: Option, + #[serde(rename = "FIXED_S10P7_MEAN")] + pub fixed_s10p7_mean: Option, + #[serde(rename = "FIXED_Y10P7")] + pub fixed_y10p7: Option, + #[serde(rename = "FIXED_Y10P7_MEAN")] + pub fixed_y10p7_mean: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OcmOdParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OD_ID")] + pub od_id: String, + #[serde(rename = "OD_PREV_ID")] + pub od_prev_id: Option, + #[serde(rename = "OD_METHOD")] + pub od_method: String, + #[serde(rename = "OD_EPOCH")] + pub od_epoch: common::EpochType, + #[serde(rename = "DAYS_SINCE_FIRST_OBS")] + pub days_since_first_obs: Option, + #[serde(rename = "DAYS_SINCE_LAST_OBS")] + pub days_since_last_obs: Option, + #[serde(rename = "RECOMMENDED_OD_SPAN")] + pub recommended_od_span: Option, + #[serde(rename = "ACTUAL_OD_SPAN")] + pub actual_od_span: Option, + #[serde(rename = "OBS_AVAILABLE")] + pub obs_available: Option, + #[serde(rename = "OBS_USED")] + pub obs_used: Option, + #[serde(rename = "TRACKS_AVAILABLE")] + pub tracks_available: Option, + #[serde(rename = "TRACKS_USED")] + pub tracks_used: Option, + #[serde(rename = "MAXIMUM_OBS_GAP")] + pub maximum_obs_gap: Option, + #[serde(rename = "OD_EPOCH_EIGMAJ")] + pub od_epoch_eigmaj: Option, + #[serde(rename = "OD_EPOCH_EIGINT")] + pub od_epoch_eigint: Option, + #[serde(rename = "OD_EPOCH_EIGMIN")] + pub od_epoch_eigmin: Option, + #[serde(rename = "OD_MAX_PRED_EIGMAJ")] + pub od_max_pred_eigmaj: Option, + #[serde(rename = "OD_MIN_PRED_EIGMIN")] + pub od_min_pred_eigmin: Option, + #[serde(rename = "OD_CONFIDENCE")] + pub od_confidence: Option, + #[serde(rename = "GDOP")] + pub gdop: Option, + #[serde(rename = "SOLVE_N")] + pub solve_n: Option, + #[serde(rename = "SOLVE_STATES")] + pub solve_states: Option, + #[serde(rename = "CONSIDER_N")] + pub consider_n: Option, + #[serde(rename = "CONSIDER_PARAMS")] + pub consider_params: Option, + #[serde(rename = "SEDR")] + pub sedr: Option, + #[serde(rename = "SENSORS_N")] + pub sensors_n: Option, + #[serde(rename = "SENSORS")] + pub sensors: Option, + #[serde(rename = "WEIGHTED_RMS")] + pub weighted_rms: Option, + #[serde(rename = "DATA_TYPES")] + pub data_types: Option, +} + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_ocm_message() { + let xml = r#" + +
+ ODM V.3 Example G-2 + OCM example with space object characteristics and perturbations. + This OCM reflects the latest conditions post-maneuver A67Z + This example shows the specification of multiple comment lines + 1998-11-06T09:23:57 + JAXA + OCM 201113719185 +
+ + + + 1998-999A + R. Rabbit + Flight Dynamics Mission Design Lead + (719)555-1234 + Mr. Rodgers + (719)555-1234 + email@email.XXX + UT1 + 1998-12-18T00:00:00.0000 + 36 + .357 + + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + THIS IS MY SECOND COMMENT LINE + PREDICTED + EFG + CARTPVA + 0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070 + + + Spacecraft Physical Characteristics + 100.0 + 0.03123 + 0.78543 + 0.39158 + 0.47832 + 2.0 + 1.0 + 0.5 + 0.15 + 0.3 + 0.5 + + + Perturbations Specification + NRLMSIS00 + EGM-96: 36D 36O + 398600.4415 + MOON, SUN + 12.0 + 105.0 + 120.0 + + + WGS-84 + + + + +
"#; + + let message: OcmType = from_str(xml).unwrap(); + + assert_eq!(message, OcmType { + header: common::OdmHeader { + comment_list: vec![ + "ODM V.3 Example G-2".to_string(), + "OCM example with space object characteristics and perturbations.".to_string(), + "This OCM reflects the latest conditions post-maneuver A67Z".to_string(), + "This example shows the specification of multiple comment lines".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "1998-11-06T09:23:57".to_string(), + ), + originator: "JAXA".to_string(), + message_id: Some( + "OCM 201113719185".to_string(), + ), + }, + body: OcmBody { + segment: OcmSegment { + metadata: OcmMetadata { + comment_list: vec![], + object_name: None, + international_designator: Some( + "1998-999A".to_string(), + ), + catalog_name: None, + object_designator: None, + alternate_names: None, + originator_poc: Some( + "R. Rabbit".to_string(), + ), + originator_position: Some( + "Flight Dynamics Mission Design Lead".to_string(), + ), + originator_phone: Some( + "(719)555-1234".to_string(), + ), + originator_email: None, + originator_address: None, + tech_org: None, + tech_poc: Some( + "Mr. Rodgers".to_string(), + ), + tech_position: None, + tech_phone: Some( + "(719)555-1234".to_string(), + ), + tech_email: None, + tech_address: Some( + "email@email.XXX".to_string(), + ), + previous_message_id: None, + next_message_id: None, + adm_msg_link: None, + cdm_msg_link: None, + prm_msg_link: None, + rdm_msg_link: None, + tdm_msg_link: None, + operator: None, + owner: None, + country: None, + constellation: None, + object_type: None, + time_system: "UT1".to_string(), + epoch_tzero: common::EpochType( + "1998-12-18T00:00:00.0000".to_string(), + ), + ops_status: None, + orbit_category: None, + ocm_data_elements: None, + sclk_offset_at_epoch: None, + sclk_sec_per_si_sec: None, + previous_message_epoch: None, + next_message_epoch: None, + start_time: None, + stop_time: None, + time_span: None, + taimutc_at_tzero: Some( + common::TimeOffsetType { + base: 36.0, + units: Some( + common::TimeUnits( + "s".to_string(), + ), + ), + }, + ), + next_leap_epoch: None, + next_leap_taimutc: None, + ut1mutc_at_tzero: Some( + common::TimeOffsetType { + base: 0.357, + units: Some( + common::TimeUnits( + "s".to_string(), + ), + ), + }, + ), + eop_source: None, + interp_method_eop: None, + celestial_source: None, + }, + data: OcmData { + traj_list: vec![ + OcmTrajStateType { + comment_list: vec![ + "GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(), + "THIS IS MY SECOND COMMENT LINE".to_string(), + ], + traj_id: None, + traj_prev_id: None, + traj_next_id: None, + traj_basis: Some( + common::TrajBasisType( + "PREDICTED".to_string(), + ), + ), + traj_basis_id: None, + interpolation: None, + interpolation_degree: None, + propagator: None, + center_name: "".to_string(), + traj_ref_frame: "EFG".to_string(), + traj_frame_epoch: None, + useable_start_time: None, + useable_stop_time: None, + orb_revnum: None, + orb_revnum_basis: None, + traj_type: "CARTPVA".to_string(), + orb_averaging: None, + traj_units: None, + traj_line_list: vec![ + "0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070".to_string(), + ], + }, + ], + phys: Some( + OcmPhysicalDescriptionType { + comment_list: vec![ + "Spacecraft Physical Characteristics".to_string(), + ], + manufacturer: None, + bus_model: None, + docked_with: None, + drag_const_area: None, + drag_coeff_nom: None, + drag_uncertainty: None, + initial_wet_mass: None, + wet_mass: Some( + common::MassType { + base: common::NonNegativeDouble( + 100.0, + ), + units: Some( + common::MassUnits( + "kg".to_string(), + ), + ), + }, + ), + dry_mass: None, + oeb_parent_frame: None, + oeb_parent_frame_epoch: None, + oeb_q1: Some( + 0.03123, + ), + oeb_q2: Some( + 0.78543, + ), + oeb_q3: Some( + 0.39158, + ), + oeb_qc: Some( + 0.47832, + ), + oeb_max: Some( + common::OcmLengthType { + base: 2.0, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + oeb_int: Some( + common::OcmLengthType { + base: 1.0, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + oeb_min: Some( + common::OcmLengthType { + base: 0.5, + units: Some( + common::LengthUnits( + "m".to_string(), + ), + ), + }, + ), + area_along_oeb_max: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.15, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_along_oeb_int: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.3, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_along_oeb_min: Some( + common::AreaType { + base: common::NonNegativeDouble( + 0.5, + ), + units: Some( + common::AreaUnits( + "m**2".to_string(), + ), + ), + }, + ), + area_min_for_pc: None, + area_max_for_pc: None, + area_typ_for_pc: None, + rcs: None, + rcs_min: None, + rcs_max: None, + srp_const_area: None, + solar_rad_coeff: None, + solar_rad_uncertainty: None, + vm_absolute: None, + vm_apparent_min: None, + vm_apparent: None, + vm_apparent_max: None, + reflectance: None, + att_control_mode: None, + att_actuator_type: None, + att_knowledge: None, + att_control: None, + att_pointing: None, + avg_maneuver_freq: None, + max_thrust: None, + dv_bol: None, + dv_remaining: None, + ixx: None, + iyy: None, + izz: None, + ixy: None, + ixz: None, + iyz: None, + }, + ), + cov_list: vec![], + man_list: vec![], + pert: Some( + OcmPerturbationsType { + comment_list: vec![ + "Perturbations Specification".to_string(), + ], + atmospheric_model: Some( + "NRLMSIS00".to_string(), + ), + gravity_model: Some( + "EGM-96: 36D 36O".to_string(), + ), + equatorial_radius: None, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.4415, + ), + units: Some( + common::GmUnits( + "km**3/s**2".to_string(), + ), + ), + }, + ), + n_body_perturbations: Some( + "MOON, SUN".to_string(), + ), + central_body_rotation: None, + oblate_flattening: None, + ocean_tides_model: None, + solid_tides_model: None, + reduction_theory: None, + albedo_model: None, + albedo_grid_size: None, + shadow_model: None, + shadow_bodies: None, + srp_model: None, + sw_data_source: None, + sw_data_epoch: None, + sw_interp_method: None, + fixed_geomag_kp: Some( + common::GeomagType { + base: 12.0, + units: None, + }, + ), + fixed_geomag_ap: None, + fixed_geomag_dst: None, + fixed_f10p7: Some( + common::SolarFluxType { + base: 105.0, + units: None, + }, + ), + fixed_f10p7_mean: Some( + common::SolarFluxType { + base: 120.0, + units: None, + }, + ), + fixed_m10p7: None, + fixed_m10p7_mean: None, + fixed_s10p7: None, + fixed_s10p7_mean: None, + fixed_y10p7: None, + fixed_y10p7_mean: None, + }, + ), + od: None, + user: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "WGS-84".to_string(), + parameter: "EARTH_MODEL".to_string(), + }, + ], + }, + ), + }, + }, + }, + id: "CCSDS_OCM_VERS".to_string(), + version: "3.0".to_string(), + }); + } +} diff --git a/crates/lox-utils/src/ndm/xml/oem.rs b/crates/lox-utils/src/ndm/xml/oem.rs new file mode 100644 index 00000000..0158b8ee --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/oem.rs @@ -0,0 +1,684 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use serde; + +use super::common; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OemBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemBody { + #[serde(rename = "segment")] + pub segment_list: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemSegment { + #[serde(rename = "metadata")] + pub metadata: OemMetadata, + #[serde(rename = "data")] + pub data: OemData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "START_TIME")] + pub start_time: common::EpochType, + #[serde(rename = "USEABLE_START_TIME")] + pub useable_start_time: Option, + #[serde(rename = "USEABLE_STOP_TIME")] + pub useable_stop_time: Option, + #[serde(rename = "STOP_TIME")] + pub stop_time: common::EpochType, + #[serde(rename = "INTERPOLATION")] + pub interpolation: Option, + #[serde(rename = "INTERPOLATION_DEGREE")] + pub interpolation_degree: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OemData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector_list: Vec, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix_list: Vec, +} + +#[cfg(test)] +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_oem_message1() { + let xml = r#" + + +
+ 2004-281T17:26:06 + me +
+ + + + Cassini + 1997-061A + Saturn + IAU-Saturn + UTC + 2004-100T00:00:00.000000 + 2004-100T01:00:00.000000 + Hermite + 1 + + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + 2004-100T00:00:00 + 1 + 1 + 1 + 1 + 1 + 1 + + + + +
"#; + + let message: OemType = from_str(xml).unwrap(); + + assert_eq!( + message, + OemType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + originator: "me".to_string(), + message_id: None, + }, + body: OemBody { + segment_list: vec![OemSegment { + metadata: OemMetadata { + comment_list: vec![], + object_name: "Cassini".to_string(), + object_id: "1997-061A".to_string(), + center_name: "Saturn".to_string(), + ref_frame: "IAU-Saturn".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType("2004-100T00:00:00.000000".to_string(),), + useable_start_time: None, + useable_stop_time: None, + stop_time: common::EpochType("2004-100T01:00:00.000000".to_string(),), + interpolation: Some("Hermite".to_string(),), + interpolation_degree: Some(1,), + }, + data: OemData { + comment_list: vec![], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + z: common::PositionType { + base: 1.0, + units: None, + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + z_dot: common::VelocityType { + base: 1.0, + units: None, + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + common::StateVectorAccType { + epoch: common::EpochType("2004-100T00:00:00".to_string(),), + x: common::PositionType { + base: 1.0, + units: None, + }, + y: common::PositionType { + base: 1.0, + units: None, + }, + z: common::PositionType { + base: 1.0, + units: Some(common::PositionUnits("km".to_string(),),), + }, + x_dot: common::VelocityType { + base: 1.0, + units: None, + }, + y_dot: common::VelocityType { + base: 1.0, + units: None, + }, + z_dot: common::VelocityType { + base: 1.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + x_ddot: None, + y_ddot: None, + z_ddot: None, + }, + ], + covariance_matrix_list: vec![], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "2.0".to_string(), + } + ); + } + + #[test] + fn test_parse_oem_message2() { + let xml = r#" + + +
+ OEM WITH OPTIONAL ACCELERATIONS + 1996-11-04T17:22:31 + NASA/JPL + OEM 201113719185 +
+ + + + MARS GLOBAL SURVEYOR + 2000-028A + MARS BARYCENTER + J2000 + UTC + 1996-12-18T12:00:00.331 + 1996-12-18T12:10:00.331 + 1996-12-28T21:23:00.331 + 1996-12-28T21:28:00.331 + HERMITE + 7 + + + Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is + to be used for DSN scheduling purposes only. + + 1996-12-18T12:00:00.331 + 2789.6 + -280.0 + -1746.8 + 4.73 + -2.50 + -1.04 + 0.008 + 0.001 + -0.159 + + + 1996-12-18T12:01:00.331 + 2783.4 + -308.1 + -1877.1 + 5.19 + -2.42 + -2.00 + 0.008 + 0.001 + 0.001 + + + 1996-12-18T12:02:00.331 + 2776.0 + -336.9 + -2008.7 + 5.64 + -2.34 + -1.95 + 0.008 + 0.001 + 0.159 + + + 1996-12-28T21:28:00.331 + -3881.0 + 564.0 + -682.8 + -3.29 + -3.67 + 1.64 + -0.003 + 0.000 + 0.000 + + + blabla + 1996-12-28T22:28:00.331 + ITRF1997 + 0.316 + 0.722 + 0.518 + 0.202 + 0.715 + 0.002 + 0.912 + 0.306 + 0.276 + 0.797 + 0.562 + 0.899 + 0.022 + 0.079 + 0.415 + 0.245 + 0.965 + 0.950 + 0.435 + 0.621 + 0.991 + + + + +
"#; + + let message: OemType = from_str(xml).unwrap(); + + assert_eq!( + message, + OemType { + header: common::OdmHeader { + comment_list: vec!["OEM WITH OPTIONAL ACCELERATIONS".to_string(),], + classification_list: vec![], + creation_date: common::EpochType("1996-11-04T17:22:31".to_string(),), + originator: "NASA/JPL".to_string(), + message_id: Some("OEM 201113719185".to_string(),), + }, + body: OemBody { + segment_list: vec![OemSegment { + metadata: OemMetadata { + comment_list: vec![], + object_name: "MARS GLOBAL SURVEYOR".to_string(), + object_id: "2000-028A".to_string(), + center_name: "MARS BARYCENTER".to_string(), + ref_frame: "J2000".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + start_time: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + useable_start_time: Some(common::EpochType( + "1996-12-18T12:10:00.331".to_string(), + ),), + useable_stop_time: Some(common::EpochType( + "1996-12-28T21:23:00.331".to_string(), + ),), + stop_time: common::EpochType("1996-12-28T21:28:00.331".to_string(),), + interpolation: Some("HERMITE".to_string(),), + interpolation_degree: Some(7,), + }, + data: OemData { + comment_list: vec![ + "Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is" + .to_string(), + "to be used for DSN scheduling purposes only.".to_string(), + ], + state_vector_list: vec![ + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + x: common::PositionType { + base: 2789.6, + units: None, + }, + y: common::PositionType { + base: -280.0, + units: None, + }, + z: common::PositionType { + base: -1746.8, + units: None, + }, + x_dot: common::VelocityType { + base: 4.73, + units: None, + }, + y_dot: common::VelocityType { + base: -2.5, + units: None, + }, + z_dot: common::VelocityType { + base: -1.04, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: -0.159, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:01:00.331".to_string(),), + x: common::PositionType { + base: 2783.4, + units: None, + }, + y: common::PositionType { + base: -308.1, + units: None, + }, + z: common::PositionType { + base: -1877.1, + units: None, + }, + x_dot: common::VelocityType { + base: 5.19, + units: None, + }, + y_dot: common::VelocityType { + base: -2.42, + units: None, + }, + z_dot: common::VelocityType { + base: -2.0, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-18T12:02:00.331".to_string(),), + x: common::PositionType { + base: 2776.0, + units: None, + }, + y: common::PositionType { + base: -336.9, + units: None, + }, + z: common::PositionType { + base: -2008.7, + units: None, + }, + x_dot: common::VelocityType { + base: 5.64, + units: None, + }, + y_dot: common::VelocityType { + base: -2.34, + units: None, + }, + z_dot: common::VelocityType { + base: -1.95, + units: None, + }, + x_ddot: Some(common::AccType { + base: 0.008, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.001, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.159, + units: None, + },), + }, + common::StateVectorAccType { + epoch: common::EpochType("1996-12-28T21:28:00.331".to_string(),), + x: common::PositionType { + base: -3881.0, + units: None, + }, + y: common::PositionType { + base: 564.0, + units: None, + }, + z: common::PositionType { + base: -682.8, + units: None, + }, + x_dot: common::VelocityType { + base: -3.29, + units: None, + }, + y_dot: common::VelocityType { + base: -3.67, + units: None, + }, + z_dot: common::VelocityType { + base: 1.64, + units: None, + }, + x_ddot: Some(common::AccType { + base: -0.003, + units: None, + },), + y_ddot: Some(common::AccType { + base: 0.0, + units: None, + },), + z_ddot: Some(common::AccType { + base: 0.0, + units: None, + },), + }, + ], + covariance_matrix_list: vec![common::OemCovarianceMatrixType { + comment_list: vec!["blabla".to_string(),], + epoch: common::EpochType("1996-12-28T22:28:00.331".to_string(),), + cov_ref_frame: Some("ITRF1997".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.316, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.722, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.518, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: 0.202, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: 0.715, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.002, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: 0.912, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: 0.306, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 0.276, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 0.797, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: 0.562, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: 0.899, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 0.022, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 0.079, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 0.415, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: 0.245, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: 0.965, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 0.95, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 0.435, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 0.621, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 0.991, + units: None, + }, + },], + }, + },], + }, + id: "CCSDS_OEM_VERS".to_string(), + version: "3.0".to_string(), + } + ); + } +} diff --git a/crates/lox-utils/src/ndm/xml/omm.rs b/crates/lox-utils/src/ndm/xml/omm.rs new file mode 100644 index 00000000..39201ac2 --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/omm.rs @@ -0,0 +1,1482 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use serde; + +use super::common; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BStarUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BTermUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AgomUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ElementSetNoType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DRevUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DdRevUnits(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SpacewarnType(#[serde(rename = "$text")] pub std::string::String); + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OmmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmBody { + #[serde(rename = "segment")] + pub segment: OmmSegment, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmSegment { + #[serde(rename = "metadata")] + pub metadata: OmmMetadata, + #[serde(rename = "data")] + pub data: OmmData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "MEAN_ELEMENT_THEORY")] + pub mean_element_theory: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "meanElements")] + pub mean_elements: MeanElementsType, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: Option, + #[serde(rename = "tleParameters")] + pub tle_parameters: Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MeanElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPOCH")] + pub epoch: common::EpochType, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: Option, + #[serde(rename = "MEAN_MOTION")] + pub mean_motion: Option, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: common::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: common::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: common::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: common::AngleType, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: common::AngleType, + #[serde(rename = "GM")] + pub gm: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TleParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "EPHEMERIS_TYPE")] + pub ephemeris_type: Option, + #[serde(rename = "CLASSIFICATION_TYPE")] + pub classification_type: Option, + #[serde(rename = "NORAD_CAT_ID")] + pub norad_cat_id: Option, + #[serde(rename = "ELEMENT_SET_NO")] + pub element_set_no: Option, + #[serde(rename = "REV_AT_EPOCH")] + pub rev_at_epoch: Option, + #[serde(rename = "BSTAR")] + pub bstar: Option, + #[serde(rename = "BTERM")] + pub bterm: Option, + #[serde(rename = "MEAN_MOTION_DOT")] + pub mean_motion_dot: DRevType, + #[serde(rename = "MEAN_MOTION_DDOT")] + pub mean_motion_ddot: Option, + #[serde(rename = "AGOM")] + pub agom: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BStarType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct BTermType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct AgomType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct RevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct DdRevType { + #[serde(rename = "$text")] + pub base: f64, + #[serde(rename = "@units")] + pub units: Option, +} + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_omm_message1() { + let xml = r#" + + +
+ THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2 + 2007-065T16:00:00 + NOAA/USA +
+ + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + TLE + + + USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA + + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + xyz + 9 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA/USA".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "TLE".to_string(), + }, + data: OmmData { + comment_list: vec![ + "USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA".to_string(), + ], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0005013, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 3.0539, + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 81.7939, + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 249.2363, + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 150.1602, + ), + units: None, + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.8, + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC0".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC1".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC2".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC3".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC4".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC5".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC6".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC7".to_string(), + }, + common::UserDefinedParameterType { + base: "xyz".to_string(), + parameter: "ABC8".to_string(), + }, + common::UserDefinedParameterType { + base: "9".to_string(), + parameter: "ABC9".to_string(), + }, + ], + }, + ), + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } + + #[test] + fn test_parse_omm_message_with_empty_object_id() { + // According to Orekit this should fail to parse due to having an empty object id. However, the XSD type of + // the object id is just xsd:string, which allows empty strings too. + + let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + + EARTH + TEME + UTC + SGP4 + + + + 2021-03-22T13:21:09.224928 + 13.82309053 + .0205751 + 49.8237 + 93.8140 + 224.8348 + 133.5761 + + + 0 + U + 7646 + 999 + 32997 + -.47102E-5 + -.147E-5 + 0 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType( + "2021-03-24T23:00:00.000".to_string(), + ), + originator: "CelesTrak".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "STARLETTE".to_string(), + object_id: "".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2021-03-22T13:21:09.224928".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 13.82309053, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0205751, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 49.8237, + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 93.8140, + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 224.8348, + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 133.5761, + ), + units: None, + }, + gm: None, + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: Some( + 0, + ), + classification_type: Some( + "U".to_string(), + ), + norad_cat_id: Some( + 7646, + ), + element_set_no: Some( + ElementSetNoType( + "999".to_string(), + ), + ), + rev_at_epoch: Some( + 32997, + ), + bstar: Some( + BStarType { + base: -4.7102e-6, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } + + #[test] + fn test_parse_omm_message2() { + let xml = r#" + +
+ THIS IS AN XML VERSION OF THE OMM + 2007-065T16:00:00 + NOAA + OMM 201113719185 +
+ + + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + SGP/SGP4 + + + + + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + TEME + 3.331349476038534e-04 + 4.618927349220216e-04 + 6.782421679971363e-04 + -3.070007847730449e-04 + -4.221234189514228e-04 + 3.231931992380369e-04 + -3.349365033922630e-07 + -4.686084221046758e-07 + 2.484949578400095e-07 + 4.296022805587290e-10 + -2.211832501084875e-07 + -2.864186892102733e-07 + 1.798098699846038e-07 + 2.608899201686016e-10 + 1.767514756338532e-10 + -3.041346050686871e-07 + -4.989496988610662e-07 + 3.540310904497689e-07 + 1.869263192954590e-10 + 1.008862586240695e-10 + 6.224444338635500e-10 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS IS AN XML VERSION OF THE OMM".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA".to_string(), + message_id: Some( + "OMM 201113719185".to_string(), + ), + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP/SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: None, + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0005013, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 3.0539, + ), + units: None, + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 81.7939, + ), + units: None, + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 249.2363, + ), + units: None, + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 150.1602, + ), + units: None, + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.8, + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: Some( + common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some( + "TEME".to_string(), + ), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + }, + ), + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "3.0".to_string(), + }); + } + + #[test] + fn test_parse_omm_message_with_units() { + let xml = r#" + +
+ THIS IS AN XML VERSION OF THE OMM + 2007-065T16:00:00 + NOAA + OMM 201113719185 +
+ + + + + GOES-9 + 1995-025A + EARTH + TEME + UTC + SGP/SGP4 + + + + + mean Elements + 2007-064T10:34:41.4264 + 1.00273272 + 0.0005013 + 3.0539 + 81.7939 + 249.2363 + 150.1602 + 398600.8 + + + tle Parameters + 23581 + 0925 + 4316 + 0.0001 + -0.00000113 + 0.0 + + + covariance Matrix + TEME + 3.331349476038534e-04 + 4.618927349220216e-04 + 6.782421679971363e-04 + -3.070007847730449e-04 + -4.221234189514228e-04 + 3.231931992380369e-04 + -3.349365033922630e-07 + -4.686084221046758e-07 + 2.484949578400095e-07 + 4.296022805587290e-10 + -2.211832501084875e-07 + -2.864186892102733e-07 + 1.798098699846038e-07 + 2.608899201686016e-10 + 1.767514756338532e-10 + -3.041346050686871e-07 + -4.989496988610662e-07 + 3.540310904497689e-07 + 1.869263192954590e-10 + 1.008862586240695e-10 + 6.224444338635500e-10 + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "THIS IS AN XML VERSION OF THE OMM".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA".to_string(), + message_id: Some( + "OMM 201113719185".to_string(), + ), + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "GOES-9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP/SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![ + "mean Elements".to_string(), + ], + epoch: common::EpochType( + "2007-064T10:34:41.4264".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 1.00273272, + units: Some( + RevUnits( + "rev/day".to_string(), + ), + ), + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0005013, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 3.0539, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 81.7939, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 249.2363, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 150.1602, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.8, + ), + units: None, + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![ + "tle Parameters".to_string(), + ], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some( + 23581, + ), + element_set_no: Some( + ElementSetNoType( + "0925".to_string(), + ), + ), + rev_at_epoch: Some( + 4316, + ), + bstar: Some( + BStarType { + base: 0.0001, + units: Some( + BStarUnits( + "1/ER".to_string(), + ), + ), + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: Some( + DRevUnits( + "rev/day**2".to_string(), + ), + ), + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: Some( + DRevUnits( + "rev/day**3".to_string(), + ), + ), + }, + ), + agom: None, + }, + ), + covariance_matrix: Some( + common::OpmCovarianceMatrixType { + comment_list: vec![ + "covariance Matrix".to_string(), + ], + cov_ref_frame: Some( + "TEME".to_string(), + ), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + }, + ), + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "3.0".to_string(), + }); + } + + + #[test] + fn test_parse_omm_message3() { + let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + 1975-010A + EARTH + TEME + UTC + SGP4 + + + + 2008-09-20T12:25:40.104192 + 15.72125391 + 0.0006703 + 51.6416 + 247.4627 + 130.5360 + 325.0288 + 398600.8 + + + 0 + U + 7646 + 999 + 32997 + -.47102E-5 + -.147E-5 + 0 + + + foo enters + a bar + + + + +
"#; + + let message: OmmType = from_str(xml).unwrap(); + + assert_eq!(message, + OmmType { + header: common::OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: common::EpochType( + "2021-03-24T23:00:00.000".to_string(), + ), + originator: "CelesTrak".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![], + object_name: "STARLETTE".to_string(), + object_id: "1975-010A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), + ref_frame_epoch: None, + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), + }, + data: OmmData { + comment_list: vec![], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2008-09-20T12:25:40.104192".to_string(), + ), + semi_major_axis: None, + mean_motion: Some( + RevType { + base: 15.72125391, + units: Some( + RevUnits( + "rev/day".to_string(), + ), + ), + }, + ), + eccentricity: common::NonNegativeDouble( + 0.0006703, + ), + inclination: common::InclinationType { + base: common::InclinationRange( + 51.6416, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange( + 247.4627, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange( + 130.536, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + mean_anomaly: common::AngleType { + base: common::AngleRange( + 325.0288, + ), + units: Some( + common::AngleUnits( + "deg".to_string(), + ), + ), + }, + gm: Some( + common::GmType { + base: common::PositiveDouble( + 398600.8, + ), + units: Some( + common::GmUnits( + "km**3/s**2".to_string(), + ), + ), + }, + ), + }, + spacecraft_parameters: None, + tle_parameters: Some( + TleParametersType { + comment_list: vec![], + ephemeris_type: Some( + 0, + ), + classification_type: Some( + "U".to_string(), + ), + norad_cat_id: Some( + 7646, + ), + element_set_no: Some( + ElementSetNoType( + "999".to_string(), + ), + ), + rev_at_epoch: Some( + 32997, + ), + bstar: Some( + BStarType { + base: -4.7102e-6, + units: None, + }, + ), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, + }, + mean_motion_ddot: Some( + DRevType { + base: 0.0, + units: None, + }, + ), + agom: None, + }, + ), + covariance_matrix: None, + user_defined_parameters: Some( + common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "foo enters".to_string(), + parameter: "FOO".to_string(), + }, + common::UserDefinedParameterType { + base: "a bar".to_string(), + parameter: "BAR".to_string(), + }, + ], + }, + ), + }, + }, + }, + id: "CCSDS_OMM_VERS".to_string(), + version: "2.0".to_string(), + }); + } + + + #[test] + fn test_parse_omm_message_spurious() { + let xml = r#" + +
+ 2021-03-24T23:00:00.000 + CelesTrak +
+ + + + STARLETTE + 1975-010A + EARTH + TEME + UTC + SGP4 + + + second metadata is an error + + + +
"#; + + let message: Result = from_str(xml); + + assert!(message.is_err()); + } + +} diff --git a/crates/lox-utils/src/ndm/xml/opm.rs b/crates/lox-utils/src/ndm/xml/opm.rs new file mode 100644 index 00000000..efbbe876 --- /dev/null +++ b/crates/lox-utils/src/ndm/xml/opm.rs @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use serde; + +use super::common; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmType { + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OpmBody, + #[serde(rename = "@id")] + pub id: String, + #[serde(rename = "@version")] + pub version: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmBody { + #[serde(rename = "segment")] + pub segment: OpmSegment, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmSegment { + #[serde(rename = "metadata")] + pub metadata: OpmMetadata, + #[serde(rename = "data")] + pub data: OpmData, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmData { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "stateVector")] + pub state_vector: common::StateVectorType, + #[serde(rename = "keplerianElements")] + pub keplerian_elements: Option, + #[serde(rename = "spacecraftParameters")] + pub spacecraft_parameters: Option, + #[serde(rename = "covarianceMatrix")] + pub covariance_matrix: Option, + #[serde(rename = "maneuverParameters")] + pub maneuver_parameters_list: Vec, + #[serde(rename = "userDefinedParameters")] + pub user_defined_parameters: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct KeplerianElementsType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: common::DistanceType, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: common::NonNegativeDouble, + #[serde(rename = "INCLINATION")] + pub inclination: common::InclinationType, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: common::AngleType, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: common::AngleType, + #[serde(rename = "TRUE_ANOMALY")] + pub true_anomaly: Option, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: Option, + #[serde(rename = "GM")] + pub gm: common::GmType, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ManeuverParametersType { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "MAN_EPOCH_IGNITION")] + pub man_epoch_ignition: common::EpochType, + #[serde(rename = "MAN_DURATION")] + pub man_duration: common::DurationType, + #[serde(rename = "MAN_DELTA_MASS")] + pub man_delta_mass: common::DeltamassType, + #[serde(rename = "MAN_REF_FRAME")] + pub man_ref_frame: String, + #[serde(rename = "MAN_DV_1")] + pub man_dv_1: common::VelocityType, + #[serde(rename = "MAN_DV_2")] + pub man_dv_2: common::VelocityType, + #[serde(rename = "MAN_DV_3")] + pub man_dv_3: common::VelocityType, +} + +mod test { + use super::*; + + use quick_xml::de::from_str; + + #[test] + fn test_parse_opm_message() { + let xml = r#" + + +
+ THIS IS AN XML VERSION OF THE OPM + 2001-11-06T09:23:57 + JAXA + OPM 201113719185 +
+ + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + OSPREY 5 + 1998-999A + EARTH + TOD + 1998-12-18T14:28:15.1172 + UTC + + + + 2008-09-20T12:25:40.104192 + 4086.147180 + -994.936814 + 5250.678791 + 2.511071 + 7.255240 + -0.583165 + + + 6730.96 + 0.0006703 + 51.6416 + 247.463 + 130.536 + 324.985 + 398600.9368 + + + 3000.000000 + 18.770000 + 1.000000 + 18.770000 + 2.500000 + + + ITRF1997 + 0.316 + 0.722 + 0.518 + 0.202 + 0.715 + 0.002 + 0.912 + 0.306 + 0.276 + 0.797 + 0.562 + 0.899 + 0.022 + 0.079 + 0.415 + 0.245 + 0.965 + 0.950 + 0.435 + 0.621 + 0.991 + + + Maneuver 1 + 2008-09-20T12:41:09.984493 + 180.000 + -0.001 + RSW + 0.000000 + 0.280000 + 0.000000 + + + 2008-09-20T13:33:11.374985 + 180.000 + -0.001 + RSW + 0.000000 + 0.270000 + 0.000000 + + + + +
"#; + + let message: OpmType = from_str(xml).unwrap(); + + assert_eq!( + message, + OpmType { + header: common::OdmHeader { + comment_list: vec!["THIS IS AN XML VERSION OF THE OPM".to_string(),], + classification_list: vec![], + creation_date: common::EpochType("2001-11-06T09:23:57".to_string(),), + originator: "JAXA".to_string(), + message_id: Some("OPM 201113719185".to_string(),), + }, + body: OpmBody { + segment: OpmSegment { + metadata: OpmMetadata { + comment_list: vec!["GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(),], + object_name: "OSPREY 5".to_string(), + object_id: "1998-999A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TOD".to_string(), + ref_frame_epoch: Some(common::EpochType( + "1998-12-18T14:28:15.1172".to_string(), + ),), + time_system: "UTC".to_string(), + }, + data: OpmData { + comment_list: vec![], + state_vector: common::StateVectorType { + comment_list: vec![], + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), + x: common::PositionType { + base: 4086.14718, + units: Some(common::PositionUnits("km".to_string(),),), + }, + y: common::PositionType { + base: -994.936814, + units: Some(common::PositionUnits("km".to_string(),),), + }, + z: common::PositionType { + base: 5250.678791, + units: Some(common::PositionUnits("km".to_string(),),), + }, + x_dot: common::VelocityType { + base: 2.511071, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + y_dot: common::VelocityType { + base: 7.25524, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + z_dot: common::VelocityType { + base: -0.583165, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + }, + keplerian_elements: Some(KeplerianElementsType { + comment_list: vec![], + semi_major_axis: common::DistanceType { + base: 6730.96, + units: Some(common::PositionUnits("km".to_string(),),), + }, + eccentricity: common::NonNegativeDouble(0.0006703,), + inclination: common::InclinationType { + base: common::InclinationRange(51.6416,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + ra_of_asc_node: common::AngleType { + base: common::AngleRange(247.463,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + arg_of_pericenter: common::AngleType { + base: common::AngleRange(130.536,), + units: Some(common::AngleUnits("deg".to_string(),),), + }, + true_anomaly: Some(common::AngleType { + base: common::AngleRange(324.985,), + units: Some(common::AngleUnits("deg".to_string(),),), + },), + mean_anomaly: None, + gm: common::GmType { + base: common::PositiveDouble(398600.9368,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + }, + },), + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec![], + mass: Some(common::MassType { + base: common::NonNegativeDouble(3000.0,), + units: None, + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(18.77,), + units: None, + },), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(18.77,), + units: None, + },), + drag_coeff: Some(common::NonNegativeDouble(2.5,),), + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some("ITRF1997".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.316, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.722, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.518, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: 0.202, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: 0.715, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.002, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: 0.912, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: 0.306, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 0.276, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 0.797, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: 0.562, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: 0.899, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 0.022, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 0.079, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 0.415, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: 0.245, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: 0.965, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 0.95, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 0.435, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 0.621, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 0.991, + units: None, + }, + },), + maneuver_parameters_list: vec![ + ManeuverParametersType { + comment_list: vec!["Maneuver 1".to_string(),], + man_epoch_ignition: common::EpochType( + "2008-09-20T12:41:09.984493".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(180.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-0.001,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "RSW".to_string(), + man_dv_1: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 0.28, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + }, + ManeuverParametersType { + comment_list: vec![], + man_epoch_ignition: common::EpochType( + "2008-09-20T13:33:11.374985".to_string(), + ), + man_duration: common::DurationType { + base: common::NonNegativeDouble(180.0,), + units: Some(common::TimeUnits("s".to_string(),),), + }, + man_delta_mass: common::DeltamassType { + base: common::NegativeDouble(-0.001,), + units: Some(common::MassUnits("kg".to_string(),),), + }, + man_ref_frame: "RSW".to_string(), + man_dv_1: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_2: common::VelocityType { + base: 0.27, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + man_dv_3: common::VelocityType { + base: 0.0, + units: Some(common::VelocityUnits("km/s".to_string(),),), + }, + }, + ], + user_defined_parameters: None, + }, + }, + }, + id: "CCSDS_OPM_VERS".to_string(), + version: "3.0".to_string(), + } + ); + } + + #[test] + fn test_parse_opm_message_spurious() { + let xml = r#" + + +
+ THIS IS AN XML VERSION OF THE OPM + 2001-11-06T09:23:57 + JAXA + OPM 201113719185 +
+ + + + GEOCENTRIC, CARTESIAN, EARTH FIXED + OSPREY 5 + 1998-999A + EARTH + TOD + 1998-12-18T14:28:15.1172 + UTC + + + second metadata is an error + + + +
"#; + + let message: Result = from_str(xml); + + assert!(message.is_err()); + } +} From 2b8a8e961f97f964b55f4f457dec2646a1ef253e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 19 Mar 2024 23:55:47 +0100 Subject: [PATCH 035/150] Implement OMM JSON parsing --- crates/lox-utils/Cargo.toml | 2 + crates/lox-utils/src/ndm.rs | 1 + crates/lox-utils/src/ndm/json.rs | 1 + crates/lox-utils/src/ndm/json/omm.rs | 293 +++++++++++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 crates/lox-utils/src/ndm/json.rs create mode 100644 crates/lox-utils/src/ndm/json/omm.rs diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 417f9e48..9f81299e 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -10,6 +10,8 @@ nom = "7.1.3" fast_polynomial = "0.1.0" quick-xml = { version = "0.31.0", features = ["serde"] } serde = { version = "1.0.194", features = ["serde_derive"] } +serde_json = "1.0.113" +error = "0.1.9" [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/ndm.rs b/crates/lox-utils/src/ndm.rs index 2910ec69..160b532f 100644 --- a/crates/lox-utils/src/ndm.rs +++ b/crates/lox-utils/src/ndm.rs @@ -1 +1,2 @@ +pub mod json; pub mod xml; diff --git a/crates/lox-utils/src/ndm/json.rs b/crates/lox-utils/src/ndm/json.rs new file mode 100644 index 00000000..9e0899c1 --- /dev/null +++ b/crates/lox-utils/src/ndm/json.rs @@ -0,0 +1 @@ +pub mod omm; diff --git a/crates/lox-utils/src/ndm/json/omm.rs b/crates/lox-utils/src/ndm/json/omm.rs new file mode 100644 index 00000000..80063700 --- /dev/null +++ b/crates/lox-utils/src/ndm/json/omm.rs @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use std::collections::HashMap; + +use serde; + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct SpacecraftParametersType { + #[serde(rename = "MASS")] + pub mass: Option, + #[serde(rename = "SOLAR_RAD_AREA")] + pub solar_rad_area: Option, + #[serde(rename = "SOLAR_RAD_COEFF")] + pub solar_rad_coeff: Option, + #[serde(rename = "DRAG_AREA")] + pub drag_area: Option, + #[serde(rename = "DRAG_COEFF")] + pub drag_coeff: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct MeanElementsType { + #[serde(rename = "EPOCH")] + pub epoch: String, + #[serde(rename = "SEMI_MAJOR_AXIS")] + pub semi_major_axis: Option, + #[serde(rename = "MEAN_MOTION")] + pub mean_motion: f64, + #[serde(rename = "ECCENTRICITY")] + pub eccentricity: f64, + #[serde(rename = "INCLINATION")] + pub inclination: f64, + #[serde(rename = "RA_OF_ASC_NODE")] + pub ra_of_asc_node: f64, + #[serde(rename = "ARG_OF_PERICENTER")] + pub arg_of_pericenter: f64, + #[serde(rename = "MEAN_ANOMALY")] + pub mean_anomaly: f64, + #[serde(rename = "GM")] + pub gm: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TleParametersType { + #[serde(rename = "EPHEMERIS_TYPE")] + pub ephemeris_type: Option, + #[serde(rename = "CLASSIFICATION_TYPE")] + pub classification_type: Option, + #[serde(rename = "NORAD_CAT_ID")] + pub norad_cat_id: Option, + #[serde(rename = "ELEMENT_SET_NO")] + pub element_set_no: Option, + #[serde(rename = "REV_AT_EPOCH")] + pub rev_at_epoch: Option, + #[serde(rename = "BSTAR")] + pub bstar: Option, + #[serde(rename = "BTERM")] + pub bterm: Option, + #[serde(rename = "MEAN_MOTION_DOT")] + pub mean_motion_dot: f64, + #[serde(rename = "MEAN_MOTION_DDOT")] + pub mean_motion_ddot: Option, + #[serde(rename = "AGOM")] + pub agom: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OpmCovarianceMatrixType { + #[serde(rename = "COV_REF_FRAME")] + pub cov_ref_frame: Option, + #[serde(rename = "CX_X")] + pub cx_x: f64, + #[serde(rename = "CY_X")] + pub cy_x: f64, + #[serde(rename = "CY_Y")] + pub cy_y: f64, + #[serde(rename = "CZ_X")] + pub cz_x: f64, + #[serde(rename = "CZ_Y")] + pub cz_y: f64, + #[serde(rename = "CZ_Z")] + pub cz_z: f64, + #[serde(rename = "CX_DOT_X")] + pub cx_dot_x: f64, + #[serde(rename = "CX_DOT_Y")] + pub cx_dot_y: f64, + #[serde(rename = "CX_DOT_Z")] + pub cx_dot_z: f64, + #[serde(rename = "CX_DOT_X_DOT")] + pub cx_dot_x_dot: f64, + #[serde(rename = "CY_DOT_X")] + pub cy_dot_x: f64, + #[serde(rename = "CY_DOT_Y")] + pub cy_dot_y: f64, + #[serde(rename = "CY_DOT_Z")] + pub cy_dot_z: f64, + #[serde(rename = "CY_DOT_X_DOT")] + pub cy_dot_x_dot: f64, + #[serde(rename = "CY_DOT_Y_DOT")] + pub cy_dot_y_dot: f64, + #[serde(rename = "CZ_DOT_X")] + pub cz_dot_x: f64, + #[serde(rename = "CZ_DOT_Y")] + pub cz_dot_y: f64, + #[serde(rename = "CZ_DOT_Z")] + pub cz_dot_z: f64, + #[serde(rename = "CZ_DOT_X_DOT")] + pub cz_dot_x_dot: f64, + #[serde(rename = "CZ_DOT_Y_DOT")] + pub cz_dot_y_dot: f64, + #[serde(rename = "CZ_DOT_Z_DOT")] + pub cz_dot_z_dot: f64, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmMetadata { + #[serde(rename = "COMMENT")] + pub comment_list: Vec, + #[serde(rename = "OBJECT_NAME")] + pub object_name: String, + #[serde(rename = "OBJECT_ID")] + pub object_id: String, + #[serde(rename = "CENTER_NAME")] + pub center_name: String, + #[serde(rename = "REF_FRAME")] + pub ref_frame: String, + #[serde(rename = "REF_FRAME_EPOCH")] + pub ref_frame_epoch: Option, + #[serde(rename = "TIME_SYSTEM")] + pub time_system: String, + #[serde(rename = "MEAN_ELEMENT_THEORY")] + pub mean_element_theory: String, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OdmHeader { + #[serde(rename = "COMMENT")] //@TODO + pub comment_list: Vec, + #[serde(rename = "CLASSIFICATION")] + pub classification_list: Vec, + #[serde(rename = "CREATION_DATE")] + pub creation_date: String, + #[serde(rename = "ORIGINATOR")] + pub originator: String, + #[serde(rename = "MESSAGE_ID")] + pub message_id: Option, +} + +#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct OmmType { + #[serde(flatten)] + pub header: OdmHeader, + + #[serde(flatten)] + pub metadata: OmmMetadata, + + #[serde(flatten)] + pub mean_elements: MeanElementsType, + #[serde(flatten)] + pub spacecraft_parameters: Option, + #[serde(flatten)] + pub tle_parameters: Option, + #[serde(flatten)] + pub covariance_matrix: Option, + + #[serde(flatten)] + pub user_defined_parameters: HashMap, +} + +mod test { + use super::*; + + #[test] + fn test_parse_json() { + let json = r#" + { + "OBJECT_NAME": "SORAYA", + "OBJECT_ID": "2024-015A", + "EPOCH": "2024-02-18T10:40:46.668576", + "MEAN_MOTION": 14.41921171, + "ECCENTRICITY": 0.0010889, + "INCLINATION": 64.5147, + "RA_OF_ASC_NODE": 28.0601, + "ARG_OF_PERICENTER": 260.5688, + "MEAN_ANOMALY": 99.4167, + "EPHEMERIS_TYPE": 0, + "CLASSIFICATION_TYPE": "U", + "NORAD_CAT_ID": 58817, + "ELEMENT_SET_NO": 999, + "REV_AT_EPOCH": 421, + "BSTAR": 0.00015073, + "MEAN_MOTION_DOT": 0.00000388, + "MEAN_MOTION_DDOT": 0, + "USER_DEFINED_FOO": "asd" + }"#; + + let message: OmmType = serde_json::de::from_str(json).unwrap(); + + assert_eq!( + message, + OmmType { + header: OdmHeader { + comment_list: vec![], + classification_list: vec![], + creation_date: "".to_string(), + originator: "".to_string(), + message_id: None, + }, + metadata: OmmMetadata { + comment_list: vec![], + object_name: "SORAYA".to_string(), + object_id: "2024-015A".to_string(), + center_name: "".to_string(), + ref_frame: "".to_string(), + ref_frame_epoch: None, + time_system: "".to_string(), + mean_element_theory: "".to_string(), + }, + mean_elements: MeanElementsType { + epoch: "2024-02-18T10:40:46.668576".to_string(), + semi_major_axis: None, + mean_motion: 14.41921171, + eccentricity: 0.0010889, + inclination: 64.5147, + ra_of_asc_node: 28.0601, + arg_of_pericenter: 260.5688, + mean_anomaly: 99.4167, + gm: None, + }, + spacecraft_parameters: Some(SpacecraftParametersType { + mass: None, + solar_rad_area: None, + solar_rad_coeff: None, + drag_area: None, + drag_coeff: None, + },), + tle_parameters: Some(TleParametersType { + ephemeris_type: Some(0,), + classification_type: Some("U".to_string(),), + norad_cat_id: Some(58817,), + element_set_no: Some(999,), + rev_at_epoch: Some(421,), + bstar: Some(0.00015073,), + bterm: None, + mean_motion_dot: 3.88e-6, + mean_motion_ddot: Some(0.0,), + agom: None, + },), + covariance_matrix: Some(OpmCovarianceMatrixType { + cov_ref_frame: None, + cx_x: 0.0, + cy_x: 0.0, + cy_y: 0.0, + cz_x: 0.0, + cz_y: 0.0, + cz_z: 0.0, + cx_dot_x: 0.0, + cx_dot_y: 0.0, + cx_dot_z: 0.0, + cx_dot_x_dot: 0.0, + cy_dot_x: 0.0, + cy_dot_y: 0.0, + cy_dot_z: 0.0, + cy_dot_x_dot: 0.0, + cy_dot_y_dot: 0.0, + cz_dot_x: 0.0, + cz_dot_y: 0.0, + cz_dot_z: 0.0, + cz_dot_x_dot: 0.0, + cz_dot_y_dot: 0.0, + cz_dot_z_dot: 0.0, + },), + user_defined_parameters: HashMap::from([( + "USER_DEFINED_FOO".to_string(), + "asd".to_string() + )]) + } + ); + } +} From d70e6fb453f780c0e7d42475b9f99810e847749c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 22 Mar 2024 00:17:17 +0100 Subject: [PATCH 036/150] Expand test and add support for string numbers --- crates/lox-utils/Cargo.toml | 1 + crates/lox-utils/src/ndm/json/omm.rs | 353 +++++++++++++++++++-------- 2 files changed, 257 insertions(+), 97 deletions(-) diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 9f81299e..d84235bc 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -12,6 +12,7 @@ quick-xml = { version = "0.31.0", features = ["serde"] } serde = { version = "1.0.194", features = ["serde_derive"] } serde_json = "1.0.113" error = "0.1.9" +serde-aux = "4.5.0" [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/ndm/json/omm.rs b/crates/lox-utils/src/ndm/json/omm.rs index 80063700..53c75dcb 100644 --- a/crates/lox-utils/src/ndm/json/omm.rs +++ b/crates/lox-utils/src/ndm/json/omm.rs @@ -6,22 +6,36 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +use serde_aux::prelude::*; use std::collections::HashMap; -use serde; - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct SpacecraftParametersType { - #[serde(rename = "MASS")] + #[serde( + rename = "MASS", + deserialize_with = "deserialize_option_number_from_string" + )] pub mass: Option, - #[serde(rename = "SOLAR_RAD_AREA")] + #[serde( + rename = "SOLAR_RAD_AREA", + deserialize_with = "deserialize_option_number_from_string" + )] pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] + #[serde( + rename = "SOLAR_RAD_COEFF", + deserialize_with = "deserialize_option_number_from_string" + )] pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] + #[serde( + rename = "DRAG_AREA", + deserialize_with = "deserialize_option_number_from_string" + )] pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] + #[serde( + rename = "DRAG_COEFF", + deserialize_with = "deserialize_option_number_from_string" + )] pub drag_coeff: Option, } @@ -32,44 +46,92 @@ pub struct MeanElementsType { pub epoch: String, #[serde(rename = "SEMI_MAJOR_AXIS")] pub semi_major_axis: Option, - #[serde(rename = "MEAN_MOTION")] + #[serde( + rename = "MEAN_MOTION", + deserialize_with = "deserialize_number_from_string" + )] pub mean_motion: f64, - #[serde(rename = "ECCENTRICITY")] + #[serde( + rename = "ECCENTRICITY", + deserialize_with = "deserialize_number_from_string" + )] pub eccentricity: f64, - #[serde(rename = "INCLINATION")] + #[serde( + rename = "INCLINATION", + deserialize_with = "deserialize_number_from_string" + )] pub inclination: f64, - #[serde(rename = "RA_OF_ASC_NODE")] + #[serde( + rename = "RA_OF_ASC_NODE", + deserialize_with = "deserialize_number_from_string" + )] pub ra_of_asc_node: f64, - #[serde(rename = "ARG_OF_PERICENTER")] + #[serde( + rename = "ARG_OF_PERICENTER", + deserialize_with = "deserialize_number_from_string" + )] pub arg_of_pericenter: f64, - #[serde(rename = "MEAN_ANOMALY")] + #[serde( + rename = "MEAN_ANOMALY", + deserialize_with = "deserialize_number_from_string" + )] pub mean_anomaly: f64, - #[serde(rename = "GM")] + #[serde( + rename = "GM", + deserialize_with = "deserialize_option_number_from_string" + )] pub gm: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct TleParametersType { - #[serde(rename = "EPHEMERIS_TYPE")] + #[serde( + rename = "EPHEMERIS_TYPE", + deserialize_with = "deserialize_option_number_from_string" + )] pub ephemeris_type: Option, #[serde(rename = "CLASSIFICATION_TYPE")] pub classification_type: Option, - #[serde(rename = "NORAD_CAT_ID")] + #[serde( + rename = "NORAD_CAT_ID", + deserialize_with = "deserialize_option_number_from_string" + )] pub norad_cat_id: Option, - #[serde(rename = "ELEMENT_SET_NO")] + #[serde( + rename = "ELEMENT_SET_NO", + deserialize_with = "deserialize_option_number_from_string" + )] pub element_set_no: Option, - #[serde(rename = "REV_AT_EPOCH")] + #[serde( + rename = "REV_AT_EPOCH", + deserialize_with = "deserialize_option_number_from_string" + )] pub rev_at_epoch: Option, - #[serde(rename = "BSTAR")] + #[serde( + rename = "BSTAR", + deserialize_with = "deserialize_option_number_from_string" + )] pub bstar: Option, - #[serde(rename = "BTERM")] + #[serde( + rename = "BTERM", + deserialize_with = "deserialize_option_number_from_string" + )] pub bterm: Option, - #[serde(rename = "MEAN_MOTION_DOT")] + #[serde( + rename = "MEAN_MOTION_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub mean_motion_dot: f64, - #[serde(rename = "MEAN_MOTION_DDOT")] + #[serde( + rename = "MEAN_MOTION_DDOT", + deserialize_with = "deserialize_option_number_from_string" + )] pub mean_motion_ddot: Option, - #[serde(rename = "AGOM")] + #[serde( + rename = "AGOM", + deserialize_with = "deserialize_option_number_from_string" + )] pub agom: Option, } @@ -78,47 +140,92 @@ pub struct TleParametersType { pub struct OpmCovarianceMatrixType { #[serde(rename = "COV_REF_FRAME")] pub cov_ref_frame: Option, - #[serde(rename = "CX_X")] + #[serde(rename = "CX_X", deserialize_with = "deserialize_number_from_string")] pub cx_x: f64, - #[serde(rename = "CY_X")] + #[serde(rename = "CY_X", deserialize_with = "deserialize_number_from_string")] pub cy_x: f64, - #[serde(rename = "CY_Y")] + #[serde(rename = "CY_Y", deserialize_with = "deserialize_number_from_string")] pub cy_y: f64, - #[serde(rename = "CZ_X")] + #[serde(rename = "CZ_X", deserialize_with = "deserialize_number_from_string")] pub cz_x: f64, - #[serde(rename = "CZ_Y")] + #[serde(rename = "CZ_Y", deserialize_with = "deserialize_number_from_string")] pub cz_y: f64, - #[serde(rename = "CZ_Z")] + #[serde(rename = "CZ_Z", deserialize_with = "deserialize_number_from_string")] pub cz_z: f64, - #[serde(rename = "CX_DOT_X")] + #[serde( + rename = "CX_DOT_X", + deserialize_with = "deserialize_number_from_string" + )] pub cx_dot_x: f64, - #[serde(rename = "CX_DOT_Y")] + #[serde( + rename = "CX_DOT_Y", + deserialize_with = "deserialize_number_from_string" + )] pub cx_dot_y: f64, - #[serde(rename = "CX_DOT_Z")] + #[serde( + rename = "CX_DOT_Z", + deserialize_with = "deserialize_number_from_string" + )] pub cx_dot_z: f64, - #[serde(rename = "CX_DOT_X_DOT")] + #[serde( + rename = "CX_DOT_X_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cx_dot_x_dot: f64, - #[serde(rename = "CY_DOT_X")] + #[serde( + rename = "CY_DOT_X", + deserialize_with = "deserialize_number_from_string" + )] pub cy_dot_x: f64, - #[serde(rename = "CY_DOT_Y")] + #[serde( + rename = "CY_DOT_Y", + deserialize_with = "deserialize_number_from_string" + )] pub cy_dot_y: f64, - #[serde(rename = "CY_DOT_Z")] + #[serde( + rename = "CY_DOT_Z", + deserialize_with = "deserialize_number_from_string" + )] pub cy_dot_z: f64, - #[serde(rename = "CY_DOT_X_DOT")] + #[serde( + rename = "CY_DOT_X_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cy_dot_x_dot: f64, - #[serde(rename = "CY_DOT_Y_DOT")] + #[serde( + rename = "CY_DOT_Y_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cy_dot_y_dot: f64, - #[serde(rename = "CZ_DOT_X")] + #[serde( + rename = "CZ_DOT_X", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_x: f64, - #[serde(rename = "CZ_DOT_Y")] + #[serde( + rename = "CZ_DOT_Y", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_y: f64, - #[serde(rename = "CZ_DOT_Z")] + #[serde( + rename = "CZ_DOT_Z", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_z: f64, - #[serde(rename = "CZ_DOT_X_DOT")] + #[serde( + rename = "CZ_DOT_X_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_x_dot: f64, - #[serde(rename = "CZ_DOT_Y_DOT")] + #[serde( + rename = "CZ_DOT_Y_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_y_dot: f64, - #[serde(rename = "CZ_DOT_Z_DOT")] + #[serde( + rename = "CZ_DOT_Z_DOT", + deserialize_with = "deserialize_number_from_string" + )] pub cz_dot_z_dot: f64, } @@ -126,7 +233,7 @@ pub struct OpmCovarianceMatrixType { #[serde(default)] pub struct OmmMetadata { #[serde(rename = "COMMENT")] - pub comment_list: Vec, + pub comment: Vec, #[serde(rename = "OBJECT_NAME")] pub object_name: String, #[serde(rename = "OBJECT_ID")] @@ -146,8 +253,8 @@ pub struct OmmMetadata { #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OdmHeader { - #[serde(rename = "COMMENT")] //@TODO - pub comment_list: Vec, + #[serde(rename = "COMMENT")] + pub comment_list: String, #[serde(rename = "CLASSIFICATION")] pub classification_list: Vec, #[serde(rename = "CREATION_DATE")] @@ -177,7 +284,7 @@ pub struct OmmType { pub covariance_matrix: Option, #[serde(flatten)] - pub user_defined_parameters: HashMap, + pub user_defined_parameters: HashMap>, } mod test { @@ -185,59 +292,82 @@ mod test { #[test] fn test_parse_json() { - let json = r#" - { - "OBJECT_NAME": "SORAYA", - "OBJECT_ID": "2024-015A", - "EPOCH": "2024-02-18T10:40:46.668576", - "MEAN_MOTION": 14.41921171, - "ECCENTRICITY": 0.0010889, - "INCLINATION": 64.5147, - "RA_OF_ASC_NODE": 28.0601, - "ARG_OF_PERICENTER": 260.5688, - "MEAN_ANOMALY": 99.4167, - "EPHEMERIS_TYPE": 0, - "CLASSIFICATION_TYPE": "U", - "NORAD_CAT_ID": 58817, - "ELEMENT_SET_NO": 999, - "REV_AT_EPOCH": 421, - "BSTAR": 0.00015073, - "MEAN_MOTION_DOT": 0.00000388, - "MEAN_MOTION_DDOT": 0, - "USER_DEFINED_FOO": "asd" - }"#; + let json = r#"[ + { + "CCSDS_OMM_VERS": "2.0", + "COMMENT": "GENERATED VIA SPACE-TRACK.ORG API", + "CREATION_DATE": "2020-12-29T06:26:10", + "ORIGINATOR": "18 SPCS", + "OBJECT_NAME": "NUSAT-8 (MARIE)", + "OBJECT_ID": "2020-003C", + "CENTER_NAME": "EARTH", + "REF_FRAME": "TEME", + "TIME_SYSTEM": "UTC", + "MEAN_ELEMENT_THEORY": "SGP4", + "EPOCH": "2020-12-29T03:57:59.406624", + "MEAN_MOTION": "15.27989249", + "ECCENTRICITY": "0.00133560", + "INCLINATION": "97.2970", + "RA_OF_ASC_NODE": "66.4161", + "ARG_OF_PERICENTER": "110.6345", + "MEAN_ANOMALY": "334.7107", + "EPHEMERIS_TYPE": "0", + "CLASSIFICATION_TYPE": "U", + "NORAD_CAT_ID": "45018", + "ELEMENT_SET_NO": "999", + "REV_AT_EPOCH": "5327", + "BSTAR": "0.00008455300000", + "MEAN_MOTION_DOT": "0.00002241", + "MEAN_MOTION_DDOT": "0.0000000000000", + "SEMIMAJOR_AXIS": "6859.961", + "PERIOD": "94.242", + "APOAPSIS": "490.988", + "PERIAPSIS": "472.664", + "OBJECT_TYPE": "PAYLOAD", + "RCS_SIZE": "MEDIUM", + "COUNTRY_CODE": "ARGN", + "LAUNCH_DATE": "2020-01-15", + "SITE": "TSC", + "DECAY_DATE": null, + "FILE": "2911831", + "GP_ID": "168552672", + "TLE_LINE0": "0 NUSAT-8 (MARIE)", + "TLE_LINE1": "1 45018U 20003C 20364.16527091 .00002241 00000-0 84553-4 0 9997", + "TLE_LINE2": "2 45018 97.2970 66.4161 0013356 110.6345 334.7107 15.27989249 53274" + } +]"#; - let message: OmmType = serde_json::de::from_str(json).unwrap(); + let message: Vec = serde_json::de::from_str(json).unwrap(); assert_eq!( message, - OmmType { + [OmmType { header: OdmHeader { - comment_list: vec![], + comment_list: "GENERATED VIA SPACE-TRACK.ORG API".to_string(), classification_list: vec![], - creation_date: "".to_string(), - originator: "".to_string(), + creation_date: "2020-12-29T06:26:10".to_string(), + originator: "18 SPCS".to_string(), message_id: None, }, metadata: OmmMetadata { - comment_list: vec![], - object_name: "SORAYA".to_string(), - object_id: "2024-015A".to_string(), - center_name: "".to_string(), - ref_frame: "".to_string(), + comment: vec![], + object_name: "NUSAT-8 (MARIE)".to_string(), + object_id: "2020-003C".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TEME".to_string(), ref_frame_epoch: None, - time_system: "".to_string(), - mean_element_theory: "".to_string(), + time_system: "UTC".to_string(), + mean_element_theory: "SGP4".to_string(), }, mean_elements: MeanElementsType { - epoch: "2024-02-18T10:40:46.668576".to_string(), + epoch: "2020-12-29T03:57:59.406624".to_string(), semi_major_axis: None, - mean_motion: 14.41921171, - eccentricity: 0.0010889, - inclination: 64.5147, - ra_of_asc_node: 28.0601, - arg_of_pericenter: 260.5688, - mean_anomaly: 99.4167, + mean_motion: 15.27989249, + eccentricity: 0.0013356, + inclination: 97.297, + ra_of_asc_node: 66.4161, + arg_of_pericenter: 110.6345, + mean_anomaly: 334.7107, gm: None, }, spacecraft_parameters: Some(SpacecraftParametersType { @@ -250,12 +380,12 @@ mod test { tle_parameters: Some(TleParametersType { ephemeris_type: Some(0,), classification_type: Some("U".to_string(),), - norad_cat_id: Some(58817,), + norad_cat_id: Some(45018,), element_set_no: Some(999,), - rev_at_epoch: Some(421,), - bstar: Some(0.00015073,), + rev_at_epoch: Some(5327,), + bstar: Some(8.4553e-5,), bterm: None, - mean_motion_dot: 3.88e-6, + mean_motion_dot: 2.241e-5, mean_motion_ddot: Some(0.0,), agom: None, },), @@ -283,11 +413,40 @@ mod test { cz_dot_y_dot: 0.0, cz_dot_z_dot: 0.0, },), - user_defined_parameters: HashMap::from([( - "USER_DEFINED_FOO".to_string(), - "asd".to_string() - )]) - } + user_defined_parameters: HashMap::from([ + ("RCS_SIZE".to_string(), Some("MEDIUM".to_string(),)), + ( + "TLE_LINE2".to_string(), + Some( + "2 45018 97.2970 66.4161 0013356 110.6345 334.7107 15.27989249 53274" + .to_string(), + ) + ), + ("SITE".to_string(), Some("TSC".to_string(),)), + ("LAUNCH_DATE".to_string(), Some("2020-01-15".to_string(),)), + ("CCSDS_OMM_VERS".to_string(), Some("2.0".to_string(),)), + ("DECAY_DATE".to_string(), None), + ("FILE".to_string(), Some("2911831".to_string(),)), + ("GP_ID".to_string(), Some("168552672".to_string(),)), + ("OBJECT_TYPE".to_string(), Some("PAYLOAD".to_string(),)), + ("APOAPSIS".to_string(), Some("490.988".to_string(),)), + ( + "TLE_LINE0".to_string(), + Some("0 NUSAT-8 (MARIE)".to_string(),) + ), + ("PERIOD".to_string(), Some("94.242".to_string(),)), + ("SEMIMAJOR_AXIS".to_string(), Some("6859.961".to_string(),)), + ("COUNTRY_CODE".to_string(), Some("ARGN".to_string(),)), + ( + "TLE_LINE1".to_string(), + Some( + "1 45018U 20003C 20364.16527091 .00002241 00000-0 84553-4 0 9997" + .to_string(), + ) + ), + ("PERIAPSIS".to_string(), Some("472.664".to_string(),)), + ]), + },] ); } } From 7e83e2c00bcc7d9f03b87187c2f9bd42281ac1d7 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 31 Mar 2024 20:58:05 +0200 Subject: [PATCH 037/150] Initial KVN parser --- crates/lox-utils/src/ndm.rs | 1 + crates/lox-utils/src/ndm/kvn.rs | 1 + crates/lox-utils/src/ndm/kvn/opm.rs | 178 ++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 crates/lox-utils/src/ndm/kvn.rs create mode 100644 crates/lox-utils/src/ndm/kvn/opm.rs diff --git a/crates/lox-utils/src/ndm.rs b/crates/lox-utils/src/ndm.rs index 160b532f..4f8a1dab 100644 --- a/crates/lox-utils/src/ndm.rs +++ b/crates/lox-utils/src/ndm.rs @@ -1,2 +1,3 @@ pub mod json; +pub mod kvn; pub mod xml; diff --git a/crates/lox-utils/src/ndm/kvn.rs b/crates/lox-utils/src/ndm/kvn.rs new file mode 100644 index 00000000..887a48d8 --- /dev/null +++ b/crates/lox-utils/src/ndm/kvn.rs @@ -0,0 +1 @@ +pub mod opm; diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs new file mode 100644 index 00000000..6fdab01d --- /dev/null +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -0,0 +1,178 @@ +// KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf + +use nom::bytes::complete as nb; +use nom::character::complete as nc; +use nom::sequence as ns; + +#[derive(PartialEq, Debug)] +pub enum KvnParserErr { + NomError(nom::Err>), + EmptyValue, + EmptyKey, +} + +#[derive(PartialEq, Debug)] +pub struct KvnValue { + pub value: V, + pub unit: Option, +} + +fn parse_kvn_line<'a>( + key: &'a str, + input: &'a str, +) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnParserErr<&'a str>> { + let equals = ns::tuple(( + nc::space0::<_, nom::error::Error<_>>, + nc::char('='), + nc::space0, + )); + + let value = nc::not_line_ending; + + let kvn = ns::separated_pair(nb::tag(key), equals, value); + + let mut kvn_line = ns::terminated(kvn, nc::multispace0); + + let (remaining, result) = kvn_line(input).map_err(|e| KvnParserErr::NomError(e))?; + + let value = result.1; + + if value.len() == 0 { + return Err(KvnParserErr::EmptyValue); + } + + let value = value.trim_end(); + + Ok((remaining, KvnValue { value, unit: None })) +} + +mod test { + use super::*; + + #[test] + fn test_kvn_line_parse() { + // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values + // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG\n"), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: None + } + )) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG\n"), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: None + } + )) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG\n"), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: None + } + )) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD = \n"), + Err(KvnParserErr::EmptyValue) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD = \n"), + Err(KvnParserErr::EmptyValue) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD =\n"), + Err(KvnParserErr::EmptyValue) + ); + + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG \n"), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: None + } + )) + ); + + // assert_eq!(parse_kvn_line("ASD", "ASD = ASDFG [km]\n"), Ok(("", "ASDFG"))); + // assert_eq!(parse_kvn_line("ASD", "ASD = [km]\n"), Ok(("", "ASDFG"))); //@TODO unit + // assert_eq!( + // parse_kvn_line("ASD", "ASD [km]\n"), + // Err(KvnParserErr::EmptyValue) + // ); + // assert_eq!(parse_kvn_line("ASD", " = [km]\n"), Ok(("", "ASDFG"))); //@TODO + + // 7.4.4 Keywords must be uppercase and must not contain blanks + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + //@TODO parse dates and floats and integers + } + + #[test] + fn test_parse_json() { + let kvn = r#"CCSDS_OPM_VERS = 3.0 +COMMENT Generated by GSOC, R. Kiehling +COMMENT Current intermediate orbit IO2 and maneuver planning data +CREATION_DATE = 2021-06-03T05:33:00.000 +ORIGINATOR = GSOC +OBJECT_NAME = EUTELSAT W4 +OBJECT_ID = 2021-028A +CENTER_NAME = EARTH +REF_FRAME = TOD +TIME_SYSTEM = UTC +COMMENT State Vector +EPOCH = 2021-06-03T00:00:00.000 +X = 6655.9942 [km] +Y = -40218.5751 [km] +Z = -82.9177 [km] +X_DOT = 3.11548208 [km/s] +Y_DOT = 0.47042605 [km/s] +Z_DOT = -0.00101495 [km/s] +COMMENT Keplerian elements +SEMI_MAJOR_AXIS = 41399.5123 [km] +ECCENTRICITY = 0.020842611 +INCLINATION = 0.117746 [deg] +RA_OF_ASC_NODE = 17.604721 [deg] +ARG_OF_PERICENTER = 218.242943 [deg] +TRUE_ANOMALY = 41.922339 [deg] +GM = 398600.4415 [km**3/s**2] +COMMENT Spacecraft parameters +MASS = 1913.000 [kg] +SOLAR_RAD_AREA = 10.000 [m**2] +SOLAR_RAD_COEFF = 1.300 +DRAG_AREA = 10.000 [m**2] +DRAG_COEFF = 2.300 +COMMENT 2 planned maneuvers +COMMENT First maneuver: AMF-3 +COMMENT Non-impulsive, thrust direction fixed in inertial frame +MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 +MAN_DURATION = 132.60 [s] +MAN_DELTA_MASS = -18.418 [kg] +MAN_REF_FRAME = EME2000 +MAN_DV_1 = -0.02325700 [km/s] +MAN_DV_2 = 0.01683160 [km/s] +MAN_DV_3 = -0.00893444 [km/s] +COMMENT Second maneuver: first station acquisition maneuver +COMMENT impulsive, thrust direction fixed in RTN frame +MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 +MAN_DURATION = 0.00 [s] +MAN_DELTA_MASS = -1.469 [kg] +MAN_REF_FRAME = RTN +MAN_DV_1 = 0.00101500 [km/s] +MAN_DV_2 = -0.00187300 [km/s] +MAN_DV_3 = 0.00000000 [km/s]"#; + } +} From d23754d9d0362b05a98291625db09b6b07110a5a Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 31 Mar 2024 21:49:36 +0200 Subject: [PATCH 038/150] Implement units --- crates/lox-utils/Cargo.toml | 1 + crates/lox-utils/src/ndm/kvn/opm.rs | 76 +++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index d84235bc..f54a97c1 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -13,6 +13,7 @@ serde = { version = "1.0.194", features = ["serde_derive"] } serde_json = "1.0.113" error = "0.1.9" serde-aux = "4.5.0" +regex = "1.10.4" [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 6fdab01d..6818434b 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -3,6 +3,7 @@ use nom::bytes::complete as nb; use nom::character::complete as nc; use nom::sequence as ns; +use regex::Regex; #[derive(PartialEq, Debug)] pub enum KvnParserErr { @@ -20,6 +21,7 @@ pub struct KvnValue { fn parse_kvn_line<'a>( key: &'a str, input: &'a str, + with_unit: bool, ) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnParserErr<&'a str>> { let equals = ns::tuple(( nc::space0::<_, nom::error::Error<_>>, @@ -35,26 +37,47 @@ fn parse_kvn_line<'a>( let (remaining, result) = kvn_line(input).map_err(|e| KvnParserErr::NomError(e))?; - let value = result.1; + let parsed_right_hand_side = result.1; - if value.len() == 0 { + let (parsed_value, parsed_unit) = if with_unit { + // This unwrap is okay here because this regex never changes after testing + let re = Regex::new(r"(.*?)(\[(.*)\])?$").unwrap(); + + // This unwrap is okay because .* will always match + let captures = re.captures(parsed_right_hand_side).unwrap(); + + ( + captures.get(1).unwrap().as_str(), + captures.get(3).map(|f| f.as_str()), + ) + } else { + (parsed_right_hand_side, None) + }; + + if parsed_value.len() == 0 { return Err(KvnParserErr::EmptyValue); } - let value = value.trim_end(); + let parsed_value = parsed_value.trim_end(); - Ok((remaining, KvnValue { value, unit: None })) + Ok(( + remaining, + KvnValue { + value: parsed_value, + unit: parsed_unit, + }, + )) } mod test { use super::*; #[test] - fn test_kvn_line_parse() { + fn test_parse_kvn_line() { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n"), + parse_kvn_line("ASD", "ASD = ASDFG\n", true), Ok(( "", KvnValue { @@ -64,7 +87,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n"), + parse_kvn_line("ASD", "ASD = ASDFG\n", true), Ok(( "", KvnValue { @@ -74,7 +97,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n"), + parse_kvn_line("ASD", "ASD = ASDFG\n", true), Ok(( "", KvnValue { @@ -84,21 +107,21 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = \n"), + parse_kvn_line("ASD", "ASD = \n", true), Err(KvnParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD = \n"), + parse_kvn_line("ASD", "ASD = \n", true), Err(KvnParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD =\n"), + parse_kvn_line("ASD", "ASD =\n", true), Err(KvnParserErr::EmptyValue) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG \n"), + parse_kvn_line("ASD", "ASD = ASDFG \n", true), Ok(( "", KvnValue { @@ -108,10 +131,33 @@ mod test { )) ); - // assert_eq!(parse_kvn_line("ASD", "ASD = ASDFG [km]\n"), Ok(("", "ASDFG"))); - // assert_eq!(parse_kvn_line("ASD", "ASD = [km]\n"), Ok(("", "ASDFG"))); //@TODO unit + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG [km]\n", true), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: Some("km") + } + )) + ); + assert_eq!( + parse_kvn_line("ASD", "ASD = ASDFG [km]\n", true), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: Some("km") + } + )) + ); + + assert_eq!( + parse_kvn_line("ASD", "ASD = [km]\n", true), + Err(KvnParserErr::EmptyValue) + ); // assert_eq!( - // parse_kvn_line("ASD", "ASD [km]\n"), + // parse_kvn_line("ASD", "ASD [km]\n", true), // Err(KvnParserErr::EmptyValue) // ); // assert_eq!(parse_kvn_line("ASD", " = [km]\n"), Ok(("", "ASDFG"))); //@TODO From 73c08157494131be8fb441f28a54d25ee0d1372e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 31 Mar 2024 23:51:30 +0200 Subject: [PATCH 039/150] Add some negative tests for kvn parser --- crates/lox-utils/src/ndm/kvn/opm.rs | 44 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 6818434b..92e6d2ac 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -6,8 +6,8 @@ use nom::sequence as ns; use regex::Regex; #[derive(PartialEq, Debug)] -pub enum KvnParserErr { - NomError(nom::Err>), +pub enum KvnLineParserErr { + ParseError(nom::Err>), EmptyValue, EmptyKey, } @@ -22,7 +22,7 @@ fn parse_kvn_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnParserErr<&'a str>> { +) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnLineParserErr<&'a str>> { let equals = ns::tuple(( nc::space0::<_, nom::error::Error<_>>, nc::char('='), @@ -35,7 +35,7 @@ fn parse_kvn_line<'a>( let mut kvn_line = ns::terminated(kvn, nc::multispace0); - let (remaining, result) = kvn_line(input).map_err(|e| KvnParserErr::NomError(e))?; + let (remaining, result) = kvn_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; let parsed_right_hand_side = result.1; @@ -55,7 +55,7 @@ fn parse_kvn_line<'a>( }; if parsed_value.len() == 0 { - return Err(KvnParserErr::EmptyValue); + return Err(KvnLineParserErr::EmptyValue); } let parsed_value = parsed_value.trim_end(); @@ -108,15 +108,15 @@ mod test { ); assert_eq!( parse_kvn_line("ASD", "ASD = \n", true), - Err(KvnParserErr::EmptyValue) + Err(KvnLineParserErr::EmptyValue) ); assert_eq!( parse_kvn_line("ASD", "ASD = \n", true), - Err(KvnParserErr::EmptyValue) + Err(KvnLineParserErr::EmptyValue) ); assert_eq!( parse_kvn_line("ASD", "ASD =\n", true), - Err(KvnParserErr::EmptyValue) + Err(KvnLineParserErr::EmptyValue) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. @@ -131,6 +131,8 @@ mod test { )) ); + // a) there must be at least one blank character between the value and the units text; + // b) the units must be enclosed within square brackets (e.g., ‘[m]’); assert_eq!( parse_kvn_line("ASD", "ASD = ASDFG [km]\n", true), Ok(( @@ -154,13 +156,27 @@ mod test { assert_eq!( parse_kvn_line("ASD", "ASD = [km]\n", true), - Err(KvnParserErr::EmptyValue) + Err(KvnLineParserErr::EmptyValue) + ); + + assert_eq!( + parse_kvn_line("ASD", "ASD [km]\n", true), + Err(KvnLineParserErr::ParseError(nom::Err::Error( + nom::error::Error { + input: "[km]\n", + code: nom::error::ErrorKind::Char + } + ))) + ); + assert_eq!( + parse_kvn_line("ASD", " = [km]\n", true), + Err(KvnLineParserErr::ParseError(nom::Err::Error( + nom::error::Error { + input: " = [km]\n", + code: nom::error::ErrorKind::Tag + } + ))) ); - // assert_eq!( - // parse_kvn_line("ASD", "ASD [km]\n", true), - // Err(KvnParserErr::EmptyValue) - // ); - // assert_eq!(parse_kvn_line("ASD", " = [km]\n"), Ok(("", "ASDFG"))); //@TODO // 7.4.4 Keywords must be uppercase and must not contain blanks // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. From 2da47cb95df3c356afd3cd2bb61b29a50068b2e3 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sun, 31 Mar 2024 23:58:23 +0200 Subject: [PATCH 040/150] Allow flexibility for whitespace at start --- crates/lox-utils/src/ndm/kvn/opm.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 92e6d2ac..2ff23d38 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -33,7 +33,7 @@ fn parse_kvn_line<'a>( let kvn = ns::separated_pair(nb::tag(key), equals, value); - let mut kvn_line = ns::terminated(kvn, nc::multispace0); + let mut kvn_line = ns::delimited(nc::space0, kvn, nc::multispace0); let (remaining, result) = kvn_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; @@ -172,14 +172,25 @@ mod test { parse_kvn_line("ASD", " = [km]\n", true), Err(KvnLineParserErr::ParseError(nom::Err::Error( nom::error::Error { - input: " = [km]\n", + input: "= [km]\n", code: nom::error::ErrorKind::Tag } ))) ); - // 7.4.4 Keywords must be uppercase and must not contain blanks // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + assert_eq!( + parse_kvn_line("ASD", " ASD = ASDFG\n", true), + Ok(( + "", + KvnValue { + value: "ASDFG", + unit: None + } + )) + ); + + // 7.4.4 Keywords must be uppercase and must not contain blanks //@TODO parse dates and floats and integers } From 84271174028be1fc46b924622c5ed6a3996f16b8 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 1 Apr 2024 00:00:46 +0200 Subject: [PATCH 041/150] Change the parser to not be line-aware --- crates/lox-utils/src/ndm/kvn/opm.rs | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 2ff23d38..7503890b 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -33,7 +33,7 @@ fn parse_kvn_line<'a>( let kvn = ns::separated_pair(nb::tag(key), equals, value); - let mut kvn_line = ns::delimited(nc::space0, kvn, nc::multispace0); + let mut kvn_line = ns::delimited(nc::space0, kvn, nc::space0); let (remaining, result) = kvn_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; @@ -77,7 +77,7 @@ mod test { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n", true), + parse_kvn_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -87,7 +87,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n", true), + parse_kvn_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -97,7 +97,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG\n", true), + parse_kvn_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -107,21 +107,21 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = \n", true), + parse_kvn_line("ASD", "ASD = ", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD = \n", true), + parse_kvn_line("ASD", "ASD = ", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD =\n", true), + parse_kvn_line("ASD", "ASD =", true), Err(KvnLineParserErr::EmptyValue) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG \n", true), + parse_kvn_line("ASD", "ASD = ASDFG ", true), Ok(( "", KvnValue { @@ -134,7 +134,7 @@ mod test { // a) there must be at least one blank character between the value and the units text; // b) the units must be enclosed within square brackets (e.g., ‘[m]’); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG [km]\n", true), + parse_kvn_line("ASD", "ASD = ASDFG [km]", true), Ok(( "", KvnValue { @@ -144,7 +144,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG [km]\n", true), + parse_kvn_line("ASD", "ASD = ASDFG [km]", true), Ok(( "", KvnValue { @@ -155,24 +155,24 @@ mod test { ); assert_eq!( - parse_kvn_line("ASD", "ASD = [km]\n", true), + parse_kvn_line("ASD", "ASD = [km]", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD [km]\n", true), + parse_kvn_line("ASD", "ASD [km]", true), Err(KvnLineParserErr::ParseError(nom::Err::Error( nom::error::Error { - input: "[km]\n", + input: "[km]", code: nom::error::ErrorKind::Char } ))) ); assert_eq!( - parse_kvn_line("ASD", " = [km]\n", true), + parse_kvn_line("ASD", " = [km]", true), Err(KvnLineParserErr::ParseError(nom::Err::Error( nom::error::Error { - input: "= [km]\n", + input: "= [km]", code: nom::error::ErrorKind::Tag } ))) @@ -180,7 +180,7 @@ mod test { // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. assert_eq!( - parse_kvn_line("ASD", " ASD = ASDFG\n", true), + parse_kvn_line("ASD", " ASD = ASDFG", true), Ok(( "", KvnValue { From 587c4286fd21807dca40dec19a8a713f9e960d79 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 1 Apr 2024 01:04:44 +0200 Subject: [PATCH 042/150] Add COMMENT parsing --- crates/lox-utils/src/ndm/kvn/opm.rs | 86 ++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 7503890b..6ddcedab 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -18,11 +18,15 @@ pub struct KvnValue { pub unit: Option, } -fn parse_kvn_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnLineParserErr<&'a str>> { +fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { + let (input, _) = nc::space0(input)?; + + let (remaining, _) = nb::tag("COMMENT ")(input)?; + + Ok(("", remaining)) +} + +fn kvn_line<'a>(key: &'a str, input: &'a str) -> nom::IResult<&'a str, (&'a str, &'a str)> { let equals = ns::tuple(( nc::space0::<_, nom::error::Error<_>>, nc::char('='), @@ -33,9 +37,27 @@ fn parse_kvn_line<'a>( let kvn = ns::separated_pair(nb::tag(key), equals, value); - let mut kvn_line = ns::delimited(nc::space0, kvn, nc::space0); + ns::delimited(nc::space0, kvn, nc::space0)(input) +} - let (remaining, result) = kvn_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; +fn parse_kvn_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnLineParserErr<&'a str>> { + if key == "COMMENT" { + let (_, comment) = comment_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; + + return Ok(( + "", + KvnValue { + value: comment, + unit: None, + }, + )); + } + + let (remaining, result) = kvn_line(key, input).map_err(|e| KvnLineParserErr::ParseError(e))?; let parsed_right_hand_side = result.1; @@ -190,8 +212,34 @@ mod test { )) ); + // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. + // [...] White space shall be retained (shall be significant) in comment values. + + assert_eq!( + parse_kvn_line("COMMENT", " COMMENT asd a asd a ads as ", true), + Ok(( + "", + KvnValue { + value: "asd a asd a ads as ", + unit: None + } + )) + ); + + assert_eq!( + parse_kvn_line("COMMENT", " COMMENT ", true), + Ok(( + "", + KvnValue { + value: "", + unit: None + } + )) + ); + // 7.4.4 Keywords must be uppercase and must not contain blanks //@TODO parse dates and floats and integers + //@TODO return error code when the key doesn't exist } #[test] @@ -247,5 +295,29 @@ MAN_REF_FRAME = RTN MAN_DV_1 = 0.00101500 [km/s] MAN_DV_2 = -0.00187300 [km/s] MAN_DV_3 = 0.00000000 [km/s]"#; + + let mut lines = kvn.lines(); + + assert_eq!( + parse_kvn_line("CCSDS_OPM_VERS", lines.next().unwrap(), false), + Ok(( + "", + KvnValue { + value: "3.0", + unit: None, + }, + ),) + ); + + assert_eq!( + parse_kvn_line("COMMENT", lines.next().unwrap(), false), + Ok(( + "", + KvnValue { + value: "Generated by GSOC, R. Kiehling", + unit: None, + }, + ),) + ); } } From 3e35e6e47b7a6ecdbaedaff157bb07bddc77e84f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 17 Apr 2024 19:34:19 +0200 Subject: [PATCH 043/150] Implement KVN date parser --- crates/lox-utils/src/ndm/kvn/opm.rs | 216 +++++++++++++++++++++++++--- 1 file changed, 195 insertions(+), 21 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 6ddcedab..1c631a2d 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -9,7 +9,13 @@ use regex::Regex; pub enum KvnLineParserErr { ParseError(nom::Err>), EmptyValue, - EmptyKey, +} + +#[derive(PartialEq, Debug)] +pub enum KvnDateTimeParserErr { + ParseError(nom::Err>), + InvalidDateFormat, + EmptyValue, } #[derive(PartialEq, Debug)] @@ -18,6 +24,17 @@ pub struct KvnValue { pub unit: Option, } +#[derive(PartialEq, Debug)] +pub struct KvnDateTimeValue { + year: u16, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, + fractional_second: f64, +} + fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { let (input, _) = nc::space0(input)?; @@ -40,7 +57,7 @@ fn kvn_line<'a>(key: &'a str, input: &'a str) -> nom::IResult<&'a str, (&'a str, ns::delimited(nc::space0, kvn, nc::space0)(input) } -fn parse_kvn_line<'a>( +fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, with_unit: bool, @@ -91,15 +108,95 @@ fn parse_kvn_line<'a>( )) } +fn parse_kvn_datetime_line<'a>( + key: &'a str, + input: &'a str, +) -> Result<(&'a str, KvnDateTimeValue), KvnDateTimeParserErr<&'a str>> { + let (_, result) = kvn_line(key, input).map_err(|e| KvnDateTimeParserErr::ParseError(e))?; + + let parsed_value = result.1; + + if parsed_value.len() == 0 { + return Err(KvnDateTimeParserErr::EmptyValue); + } + + let parsed_value = parsed_value.trim_end(); + + // Taken from CCSDS 502.0-B-3 Figure F-5: Regex Pattern for CCSDS Timecode + // This unwrap is okay here because this regex never changes after testing + let re = Regex::new( + r"^(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))$", + ) + .unwrap(); + + let captures = re + .captures(parsed_value) + .ok_or(KvnDateTimeParserErr::InvalidDateFormat)?; + + // yr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let year = captures + .name("yr") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + // We don't do full validation of the date values. We only care if they + // have the expected number of digits + + // mo is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let month = captures.name("mo").unwrap().as_str().parse::().unwrap(); + + // day is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let day = captures.name("dy").unwrap().as_str().parse::().unwrap(); + + // hr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let hour = captures.name("hr").unwrap().as_str().parse::().unwrap(); + + // mn is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let minute = captures.name("mn").unwrap().as_str().parse::().unwrap(); + + // sc is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let full_second = captures + .name("sc") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + let second = full_second.floor() as u8; + + let fractional_second = full_second.fract(); + + Ok(( + "", + KvnDateTimeValue { + year, + month, + day, + hour, + minute, + second, + fractional_second, + }, + )) +} + mod test { use super::*; #[test] - fn test_parse_kvn_line() { + fn test_parse_kvn_string_line() { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG", true), + parse_kvn_string_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -109,7 +206,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG", true), + parse_kvn_string_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -119,7 +216,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG", true), + parse_kvn_string_line("ASD", "ASD = ASDFG", true), Ok(( "", KvnValue { @@ -129,21 +226,21 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ", true), + parse_kvn_string_line("ASD", "ASD = ", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ", true), + parse_kvn_string_line("ASD", "ASD = ", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD =", true), + parse_kvn_string_line("ASD", "ASD =", true), Err(KvnLineParserErr::EmptyValue) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG ", true), + parse_kvn_string_line("ASD", "ASD = ASDFG ", true), Ok(( "", KvnValue { @@ -156,7 +253,7 @@ mod test { // a) there must be at least one blank character between the value and the units text; // b) the units must be enclosed within square brackets (e.g., ‘[m]’); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG [km]", true), + parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), Ok(( "", KvnValue { @@ -166,7 +263,7 @@ mod test { )) ); assert_eq!( - parse_kvn_line("ASD", "ASD = ASDFG [km]", true), + parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), Ok(( "", KvnValue { @@ -177,12 +274,12 @@ mod test { ); assert_eq!( - parse_kvn_line("ASD", "ASD = [km]", true), + parse_kvn_string_line("ASD", "ASD = [km]", true), Err(KvnLineParserErr::EmptyValue) ); assert_eq!( - parse_kvn_line("ASD", "ASD [km]", true), + parse_kvn_string_line("ASD", "ASD [km]", true), Err(KvnLineParserErr::ParseError(nom::Err::Error( nom::error::Error { input: "[km]", @@ -191,7 +288,7 @@ mod test { ))) ); assert_eq!( - parse_kvn_line("ASD", " = [km]", true), + parse_kvn_string_line("ASD", " = [km]", true), Err(KvnLineParserErr::ParseError(nom::Err::Error( nom::error::Error { input: "= [km]", @@ -202,7 +299,7 @@ mod test { // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. assert_eq!( - parse_kvn_line("ASD", " ASD = ASDFG", true), + parse_kvn_string_line("ASD", " ASD = ASDFG", true), Ok(( "", KvnValue { @@ -216,7 +313,7 @@ mod test { // [...] White space shall be retained (shall be significant) in comment values. assert_eq!( - parse_kvn_line("COMMENT", " COMMENT asd a asd a ads as ", true), + parse_kvn_string_line("COMMENT", " COMMENT asd a asd a ads as ", true), Ok(( "", KvnValue { @@ -227,7 +324,7 @@ mod test { ); assert_eq!( - parse_kvn_line("COMMENT", " COMMENT ", true), + parse_kvn_string_line("COMMENT", " COMMENT ", true), Ok(( "", KvnValue { @@ -242,12 +339,62 @@ mod test { //@TODO return error code when the key doesn't exist } + #[test] + fn test_parse_kvn_datetime_line() { + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:00.123"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + )) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:01"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 1, + fractional_second: 0.0, + }, + )) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), + Err(KvnDateTimeParserErr::InvalidDateFormat) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), + Err(KvnDateTimeParserErr::InvalidDateFormat) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), + Err(KvnDateTimeParserErr::EmptyValue) + ); + } + #[test] fn test_parse_json() { let kvn = r#"CCSDS_OPM_VERS = 3.0 COMMENT Generated by GSOC, R. Kiehling COMMENT Current intermediate orbit IO2 and maneuver planning data -CREATION_DATE = 2021-06-03T05:33:00.000 +CREATION_DATE = 2021-06-03T05:33:00.123 ORIGINATOR = GSOC OBJECT_NAME = EUTELSAT W4 OBJECT_ID = 2021-028A @@ -299,7 +446,7 @@ MAN_DV_3 = 0.00000000 [km/s]"#; let mut lines = kvn.lines(); assert_eq!( - parse_kvn_line("CCSDS_OPM_VERS", lines.next().unwrap(), false), + parse_kvn_string_line("CCSDS_OPM_VERS", lines.next().unwrap(), false), Ok(( "", KvnValue { @@ -310,7 +457,7 @@ MAN_DV_3 = 0.00000000 [km/s]"#; ); assert_eq!( - parse_kvn_line("COMMENT", lines.next().unwrap(), false), + parse_kvn_string_line("COMMENT", lines.next().unwrap(), false), Ok(( "", KvnValue { @@ -319,5 +466,32 @@ MAN_DV_3 = 0.00000000 [km/s]"#; }, ),) ); + + assert_eq!( + parse_kvn_string_line("COMMENT", lines.next().unwrap(), false), + Ok(( + "", + KvnValue { + value: "Current intermediate orbit IO2 and maneuver planning data", + unit: None, + }, + ),) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", lines.next().unwrap()), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + )) + ); } } From 8a1f9003383849e95e5774e8e3cad7e016b80365 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 19 Apr 2024 18:14:48 +0200 Subject: [PATCH 044/150] Implement integer line support --- crates/lox-utils/src/ndm/kvn/opm.rs | 126 +++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 11 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 1c631a2d..d19aabb1 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -6,11 +6,18 @@ use nom::sequence as ns; use regex::Regex; #[derive(PartialEq, Debug)] -pub enum KvnLineParserErr { +pub enum KvnStringLineParserErr { ParseError(nom::Err>), EmptyValue, } +#[derive(PartialEq, Debug)] +pub enum KvnIntegerLineParserErr { + ParseError(nom::Err>), + EmptyValue, + InvalidFormat, +} + #[derive(PartialEq, Debug)] pub enum KvnDateTimeParserErr { ParseError(nom::Err>), @@ -61,9 +68,10 @@ fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnLineParserErr<&'a str>> { +) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnStringLineParserErr<&'a str>> { if key == "COMMENT" { - let (_, comment) = comment_line(input).map_err(|e| KvnLineParserErr::ParseError(e))?; + let (_, comment) = + comment_line(input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; return Ok(( "", @@ -74,7 +82,8 @@ fn parse_kvn_string_line<'a>( )); } - let (remaining, result) = kvn_line(key, input).map_err(|e| KvnLineParserErr::ParseError(e))?; + let (remaining, result) = + kvn_line(key, input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; let parsed_right_hand_side = result.1; @@ -94,7 +103,7 @@ fn parse_kvn_string_line<'a>( }; if parsed_value.len() == 0 { - return Err(KvnLineParserErr::EmptyValue); + return Err(KvnStringLineParserErr::EmptyValue); } let parsed_value = parsed_value.trim_end(); @@ -108,6 +117,33 @@ fn parse_kvn_string_line<'a>( )) } +fn parse_kvn_integer_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnValue), KvnIntegerLineParserErr<&'a str>> { + parse_kvn_string_line(key, input, with_unit) + .map_err(|e| match e { + KvnStringLineParserErr::EmptyValue => KvnIntegerLineParserErr::EmptyValue, + KvnStringLineParserErr::ParseError(e) => KvnIntegerLineParserErr::ParseError(e), + }) + .and_then(|result| { + let value = result + .1 + .value + .parse::() + .map_err(|_| KvnIntegerLineParserErr::InvalidFormat)?; + + Ok(( + "", + KvnValue { + value, + unit: result.1.unit, + }, + )) + }) +} + fn parse_kvn_datetime_line<'a>( key: &'a str, input: &'a str, @@ -227,15 +263,15 @@ mod test { ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnLineParserErr::EmptyValue) + Err(KvnStringLineParserErr::EmptyValue) ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnLineParserErr::EmptyValue) + Err(KvnStringLineParserErr::EmptyValue) ); assert_eq!( parse_kvn_string_line("ASD", "ASD =", true), - Err(KvnLineParserErr::EmptyValue) + Err(KvnStringLineParserErr::EmptyValue) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. @@ -275,12 +311,12 @@ mod test { assert_eq!( parse_kvn_string_line("ASD", "ASD = [km]", true), - Err(KvnLineParserErr::EmptyValue) + Err(KvnStringLineParserErr::EmptyValue) ); assert_eq!( parse_kvn_string_line("ASD", "ASD [km]", true), - Err(KvnLineParserErr::ParseError(nom::Err::Error( + Err(KvnStringLineParserErr::ParseError(nom::Err::Error( nom::error::Error { input: "[km]", code: nom::error::ErrorKind::Char @@ -289,7 +325,7 @@ mod test { ); assert_eq!( parse_kvn_string_line("ASD", " = [km]", true), - Err(KvnLineParserErr::ParseError(nom::Err::Error( + Err(KvnStringLineParserErr::ParseError(nom::Err::Error( nom::error::Error { input: "= [km]", code: nom::error::ErrorKind::Tag @@ -339,6 +375,74 @@ mod test { //@TODO return error code when the key doesn't exist } + #[test] + fn test_parse_kvn_integer_line() { + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = 28800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s") + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = 00028800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s") + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = -28800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: -28800, + unit: Some("s") + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = -28800", + true + ), + Ok(( + "", + KvnValue { + value: -28800, + unit: None + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), + Err(KvnIntegerLineParserErr::EmptyValue) + ); + } + #[test] fn test_parse_kvn_datetime_line() { assert_eq!( From b6e6f6c3f21386179b957e6a39bf2cf73d7c04d3 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 19 Apr 2024 19:06:01 +0200 Subject: [PATCH 045/150] Test parsing an invalid integer --- crates/lox-utils/src/ndm/kvn/opm.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index d19aabb1..8ca71f3d 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -437,6 +437,11 @@ mod test { )) ); + assert_eq!( + parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), + Err(KvnIntegerLineParserErr::InvalidFormat) + ); + assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), Err(KvnIntegerLineParserErr::EmptyValue) From 7da82592587e8088d78825360f00ed0dc9106a9f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 19 Apr 2024 19:46:57 +0200 Subject: [PATCH 046/150] Implement float ODM parsing --- crates/lox-utils/Cargo.toml | 1 + crates/lox-utils/src/ndm/kvn/opm.rs | 76 ++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index f54a97c1..6c76b8b5 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -14,6 +14,7 @@ serde_json = "1.0.113" error = "0.1.9" serde-aux = "4.5.0" regex = "1.10.4" +fast-float = "0.2.0" [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 8ca71f3d..82bf0c20 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -12,7 +12,7 @@ pub enum KvnStringLineParserErr { } #[derive(PartialEq, Debug)] -pub enum KvnIntegerLineParserErr { +pub enum KvnNumberLineParserErr { ParseError(nom::Err>), EmptyValue, InvalidFormat, @@ -121,18 +121,42 @@ fn parse_kvn_integer_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue), KvnIntegerLineParserErr<&'a str>> { +) -> Result<(&'a str, KvnValue), KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { - KvnStringLineParserErr::EmptyValue => KvnIntegerLineParserErr::EmptyValue, - KvnStringLineParserErr::ParseError(e) => KvnIntegerLineParserErr::ParseError(e), + KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, + KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), }) .and_then(|result| { let value = result .1 .value .parse::() - .map_err(|_| KvnIntegerLineParserErr::InvalidFormat)?; + .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; + + Ok(( + "", + KvnValue { + value, + unit: result.1.unit, + }, + )) + }) +} + +fn parse_kvn_numeric_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnValue), KvnNumberLineParserErr<&'a str>> { + parse_kvn_string_line(key, input, with_unit) + .map_err(|e| match e { + KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, + KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), + }) + .and_then(|result| { + let value = fast_float::parse(result.1.value) + .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; Ok(( "", @@ -439,12 +463,48 @@ mod test { assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(KvnIntegerLineParserErr::InvalidFormat) + Err(KvnNumberLineParserErr::InvalidFormat) ); assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(KvnIntegerLineParserErr::EmptyValue) + Err(KvnNumberLineParserErr::EmptyValue) + ); + } + + #[test] + fn test_parse_kvn_numeric_line() { + assert_eq!( + parse_kvn_numeric_line("X", "X = 66559942 [km]", true), + Ok(( + "", + KvnValue { + value: 66559942f64, + unit: Some("km") + }, + )) + ); + + assert_eq!( + parse_kvn_numeric_line("X", "X = 6655.9942 [km]", true), + Ok(( + "", + KvnValue { + value: 6655.9942, + unit: Some("km") + }, + )) + ); + + assert_eq!( + parse_kvn_numeric_line("CX_X", "CX_X = 5.801003223606e-05", true), + Ok(( + "", + KvnValue { + value: 5.801003223606e-05, + unit: None + }, + )) ); } @@ -482,6 +542,8 @@ mod test { )) ); + // @TODO add support for ddd format + assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), Err(KvnDateTimeParserErr::InvalidDateFormat) From 4af142980352b860efcc4b88ed2b9d3b1a6b5f30 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Apr 2024 23:00:49 +0200 Subject: [PATCH 047/150] Add copyright header --- crates/lox-utils/src/ndm/kvn/opm.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 82bf0c20..7a2cb579 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + // KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf use nom::bytes::complete as nb; From 3918cf61bc8f38531c4b3f8c0a6d2d5de9679d5c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Apr 2024 23:21:37 +0200 Subject: [PATCH 048/150] Implement deserializer proc macro --- Cargo.toml | 1 + crates/lox-utils/Cargo.toml | 1 + crates/lox-utils/src/ndm/kvn/opm.rs | 355 +++++++++++++++++++++++----- crates/lox_derive/Cargo.toml | 11 + crates/lox_derive/src/lib.rs | 108 +++++++++ 5 files changed, 411 insertions(+), 65 deletions(-) create mode 100644 crates/lox_derive/Cargo.toml create mode 100644 crates/lox_derive/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 8c1e292c..0a3eb2fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ lox-io = { path = "crates/lox-io" } lox-space = { path = "crates/lox-space" } lox-time = { path = "crates/lox-time" } lox-utils = { path = "crates/lox-utils" } +lox_derive = { path = "./crates/lox_derive" } csv = "1.3.0" divan = "0.1.14" diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 6c76b8b5..08fdcd7b 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -15,6 +15,7 @@ error = "0.1.9" serde-aux = "4.5.0" regex = "1.10.4" fast-float = "0.2.0" +lox_derive.workspace = true [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 7a2cb579..dcc71d4e 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -8,11 +8,61 @@ // KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf +use lox_derive::KvnDeserialize; use nom::bytes::complete as nb; use nom::character::complete as nc; use nom::sequence as ns; use regex::Regex; +type KvnStringValue = KvnValue; +type KvnIntegerValue = KvnValue; +type KvnNumericValue = KvnValue; + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct Opm { + //@TODO the unit is always fixed and the same + ccsds_opm_vers: KvnStringValue, + comment: KvnStringValue, + creation_date: KvnDateTimeValue, + originator: KvnStringValue, + object_name: KvnStringValue, + object_id: KvnStringValue, + center_name: KvnStringValue, + ref_frame: KvnStringValue, + // ref_frame_epoch: KvnDateTimeValue, + time_system: KvnStringValue, + // comment: KvnStringValue, + epoch: KvnDateTimeValue, + x: KvnNumericValue, + y: KvnNumericValue, + z: KvnNumericValue, + x_dot: KvnNumericValue, + y_dot: KvnNumericValue, + z_dot: KvnNumericValue, + // comment: KvnStringValue, + semi_major_axis: KvnNumericValue, + eccentricity: KvnNumericValue, //@TODO no unit + inclination: KvnNumericValue, + ra_of_asc_node: KvnNumericValue, + arg_of_pericenter: KvnNumericValue, + true_anomaly: KvnNumericValue, + gm: KvnNumericValue, + // comment: KvnStringValue, + mass: KvnNumericValue, + solar_rad_area: KvnNumericValue, + solar_rad_coeff: KvnNumericValue, + drag_area: KvnNumericValue, + drag_coeff: KvnNumericValue, //@TODO no unit + // comment: KvnStringValue, + man_epoch_ignition: KvnDateTimeValue, + man_duration: KvnNumericValue, + man_delta_mass: KvnNumericValue, + man_ref_frame: KvnStringValue, + man_dv_1: KvnNumericValue, + man_dv_2: KvnNumericValue, + man_dv_3: KvnNumericValue, +} + #[derive(PartialEq, Debug)] pub enum KvnStringLineParserErr { ParseError(nom::Err>), @@ -34,12 +84,20 @@ pub enum KvnDateTimeParserErr { } #[derive(PartialEq, Debug)] +pub enum KvnDeserializerErr { + String(KvnStringLineParserErr), + DateTime(KvnDateTimeParserErr), + Number(KvnNumberLineParserErr), + UnexpectedEndOfInput, +} + +#[derive(PartialEq, Debug, Default)] pub struct KvnValue { pub value: V, pub unit: Option, } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Debug, Default)] pub struct KvnDateTimeValue { year: u16, month: u8, @@ -50,6 +108,12 @@ pub struct KvnDateTimeValue { fractional_second: f64, } +pub trait KvnDeserializer { + fn deserialize<'a>( + lines: &mut dyn Iterator, + ) -> Result>; +} + fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { let (input, _) = nc::space0(input)?; @@ -76,7 +140,7 @@ fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue<&'a str, &'a str>), KvnStringLineParserErr<&'a str>> { +) -> Result<(&'a str, KvnStringValue), KvnStringLineParserErr<&'a str>> { if key == "COMMENT" { let (_, comment) = comment_line(input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; @@ -84,7 +148,7 @@ fn parse_kvn_string_line<'a>( return Ok(( "", KvnValue { - value: comment, + value: comment.to_owned(), unit: None, }, )); @@ -119,8 +183,8 @@ fn parse_kvn_string_line<'a>( Ok(( remaining, KvnValue { - value: parsed_value, - unit: parsed_unit, + value: parsed_value.to_owned(), + unit: parsed_unit.map(|x| x.to_owned()), }, )) } @@ -129,7 +193,7 @@ fn parse_kvn_integer_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue), KvnNumberLineParserErr<&'a str>> { +) -> Result<(&'a str, KvnIntegerValue), KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, @@ -156,7 +220,7 @@ fn parse_kvn_numeric_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnValue), KvnNumberLineParserErr<&'a str>> { +) -> Result<(&'a str, KvnNumericValue), KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, @@ -268,7 +332,7 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", + value: "ASDFG".to_string(), unit: None } )) @@ -278,7 +342,7 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", + value: "ASDFG".to_string(), unit: None } )) @@ -288,7 +352,7 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", + value: "ASDFG".to_string(), unit: None } )) @@ -312,7 +376,7 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", + value: "ASDFG".to_string(), unit: None } )) @@ -325,8 +389,8 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", - unit: Some("km") + value: "ASDFG".to_string(), + unit: Some("km".to_string()) } )) ); @@ -335,8 +399,8 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", - unit: Some("km") + value: "ASDFG".to_string(), + unit: Some("km".to_string()) } )) ); @@ -371,7 +435,7 @@ mod test { Ok(( "", KvnValue { - value: "ASDFG", + value: "ASDFG".to_string(), unit: None } )) @@ -385,7 +449,7 @@ mod test { Ok(( "", KvnValue { - value: "asd a asd a ads as ", + value: "asd a asd a ads as ".to_string(), unit: None } )) @@ -396,7 +460,7 @@ mod test { Ok(( "", KvnValue { - value: "", + value: "".to_string(), unit: None } )) @@ -419,7 +483,7 @@ mod test { "", KvnValue { value: 28800, - unit: Some("s") + unit: Some("s".to_string()) }, )) ); @@ -434,7 +498,7 @@ mod test { "", KvnValue { value: 28800, - unit: Some("s") + unit: Some("s".to_string()) }, )) ); @@ -449,7 +513,7 @@ mod test { "", KvnValue { value: -28800, - unit: Some("s") + unit: Some("s".to_string()) }, )) ); @@ -488,7 +552,7 @@ mod test { "", KvnValue { value: 66559942f64, - unit: Some("km") + unit: Some("km".to_string()) }, )) ); @@ -499,7 +563,7 @@ mod test { "", KvnValue { value: 6655.9942, - unit: Some("km") + unit: Some("km".to_string()) }, )) ); @@ -570,9 +634,64 @@ mod test { #[test] fn test_parse_json() { + /* + This is the original file with multi-line comments: + + CCSDS_OPM_VERS = 3.0 + COMMENT Generated by GSOC, R. Kiehling + COMMENT Current intermediate orbit IO2 and maneuver planning data + CREATION_DATE = 2021-06-03T05:33:00.123 + ORIGINATOR = GSOC + OBJECT_NAME = EUTELSAT W4 + OBJECT_ID = 2021-028A + CENTER_NAME = EARTH + REF_FRAME = TOD + TIME_SYSTEM = UTC + COMMENT State Vector + EPOCH = 2021-06-03T00:00:00.000 + X = 6655.9942 [km] + Y = -40218.5751 [km] + Z = -82.9177 [km] + X_DOT = 3.11548208 [km/s] + Y_DOT = 0.47042605 [km/s] + Z_DOT = -0.00101495 [km/s] + COMMENT Keplerian elements + SEMI_MAJOR_AXIS = 41399.5123 [km] + ECCENTRICITY = 0.020842611 + INCLINATION = 0.117746 [deg] + RA_OF_ASC_NODE = 17.604721 [deg] + ARG_OF_PERICENTER = 218.242943 [deg] + TRUE_ANOMALY = 41.922339 [deg] + GM = 398600.4415 [km**3/s**2] + COMMENT Spacecraft parameters + MASS = 1913.000 [kg] + SOLAR_RAD_AREA = 10.000 [m**2] + SOLAR_RAD_COEFF = 1.300 + DRAG_AREA = 10.000 [m**2] + DRAG_COEFF = 2.300 + COMMENT 2 planned maneuvers + COMMENT First maneuver: AMF-3 + COMMENT Non-impulsive, thrust direction fixed in inertial frame + MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 + MAN_DURATION = 132.60 [s] + MAN_DELTA_MASS = -18.418 [kg] + MAN_REF_FRAME = EME2000 + MAN_DV_1 = -0.02325700 [km/s] + MAN_DV_2 = 0.01683160 [km/s] + MAN_DV_3 = -0.00893444 [km/s] + COMMENT Second maneuver: first station acquisition maneuver + COMMENT impulsive, thrust direction fixed in RTN frame + MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 + MAN_DURATION = 0.00 [s] + MAN_DELTA_MASS = -1.469 [kg] + MAN_REF_FRAME = RTN + MAN_DV_1 = 0.00101500 [km/s] + MAN_DV_2 = -0.00187300 [km/s] + MAN_DV_3 = 0.00000000 [km/s] + */ + let kvn = r#"CCSDS_OPM_VERS = 3.0 COMMENT Generated by GSOC, R. Kiehling -COMMENT Current intermediate orbit IO2 and maneuver planning data CREATION_DATE = 2021-06-03T05:33:00.123 ORIGINATOR = GSOC OBJECT_NAME = EUTELSAT W4 @@ -580,7 +699,6 @@ OBJECT_ID = 2021-028A CENTER_NAME = EARTH REF_FRAME = TOD TIME_SYSTEM = UTC -COMMENT State Vector EPOCH = 2021-06-03T00:00:00.000 X = 6655.9942 [km] Y = -40218.5751 [km] @@ -588,7 +706,6 @@ Z = -82.9177 [km] X_DOT = 3.11548208 [km/s] Y_DOT = 0.47042605 [km/s] Z_DOT = -0.00101495 [km/s] -COMMENT Keplerian elements SEMI_MAJOR_AXIS = 41399.5123 [km] ECCENTRICITY = 0.020842611 INCLINATION = 0.117746 [deg] @@ -596,15 +713,11 @@ RA_OF_ASC_NODE = 17.604721 [deg] ARG_OF_PERICENTER = 218.242943 [deg] TRUE_ANOMALY = 41.922339 [deg] GM = 398600.4415 [km**3/s**2] -COMMENT Spacecraft parameters MASS = 1913.000 [kg] SOLAR_RAD_AREA = 10.000 [m**2] SOLAR_RAD_COEFF = 1.300 DRAG_AREA = 10.000 [m**2] DRAG_COEFF = 2.300 -COMMENT 2 planned maneuvers -COMMENT First maneuver: AMF-3 -COMMENT Non-impulsive, thrust direction fixed in inertial frame MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 MAN_DURATION = 132.60 [s] MAN_DELTA_MASS = -18.418 [kg] @@ -612,8 +725,6 @@ MAN_REF_FRAME = EME2000 MAN_DV_1 = -0.02325700 [km/s] MAN_DV_2 = 0.01683160 [km/s] MAN_DV_3 = -0.00893444 [km/s] -COMMENT Second maneuver: first station acquisition maneuver -COMMENT impulsive, thrust direction fixed in RTN frame MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 MAN_DURATION = 0.00 [s] MAN_DELTA_MASS = -1.469 [kg] @@ -624,44 +735,20 @@ MAN_DV_3 = 0.00000000 [km/s]"#; let mut lines = kvn.lines(); - assert_eq!( - parse_kvn_string_line("CCSDS_OPM_VERS", lines.next().unwrap(), false), - Ok(( - "", - KvnValue { - value: "3.0", - unit: None, - }, - ),) - ); + let opm = Opm::deserialize(&mut lines); assert_eq!( - parse_kvn_string_line("COMMENT", lines.next().unwrap(), false), - Ok(( - "", - KvnValue { - value: "Generated by GSOC, R. Kiehling", + opm, + Ok(Opm { + ccsds_opm_vers: KvnValue { + value: "3.0".to_string(), unit: None, }, - ),) - ); - - assert_eq!( - parse_kvn_string_line("COMMENT", lines.next().unwrap(), false), - Ok(( - "", - KvnValue { - value: "Current intermediate orbit IO2 and maneuver planning data", + comment: KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), unit: None, }, - ),) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", lines.next().unwrap()), - Ok(( - "", - KvnDateTimeValue { + creation_date: KvnDateTimeValue { year: 2021, month: 6, day: 3, @@ -670,7 +757,145 @@ MAN_DV_3 = 0.00000000 [km/s]"#; second: 0, fractional_second: 0.123, }, - )) + originator: KvnValue { + value: "GSOC".to_string(), + unit: None, + }, + object_name: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None, + }, + object_id: KvnValue { + value: "2021-028A".to_string(), + unit: None, + }, + center_name: KvnValue { + value: "EARTH".to_string(), + unit: None, + }, + ref_frame: KvnValue { + value: "TOD".to_string(), + unit: None, + }, + time_system: KvnValue { + value: "UTC".to_string(), + unit: None, + }, + epoch: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 0, + minute: 0, + second: 0, + fractional_second: 0.0, + }, + x: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + y: KvnValue { + value: -40218.5751, + unit: Some("km".to_string(),), + }, + z: KvnValue { + value: -82.9177, + unit: Some("km".to_string(),), + }, + x_dot: KvnValue { + value: 3.11548208, + unit: Some("km/s".to_string(),), + }, + y_dot: KvnValue { + value: 0.47042605, + unit: Some("km/s".to_string(),), + }, + z_dot: KvnValue { + value: -0.00101495, + unit: Some("km/s".to_string(),), + }, + semi_major_axis: KvnValue { + value: 41399.5123, + unit: Some("km".to_string(),), + }, + eccentricity: KvnValue { + value: 0.020842611, + unit: None, + }, + inclination: KvnValue { + value: 0.117746, + unit: Some("deg".to_string(),), + }, + ra_of_asc_node: KvnValue { + value: 17.604721, + unit: Some("deg".to_string(),), + }, + arg_of_pericenter: KvnValue { + value: 218.242943, + unit: Some("deg".to_string(),), + }, + true_anomaly: KvnValue { + value: 41.922339, + unit: Some("deg".to_string(),), + }, + gm: KvnValue { + value: 398600.4415, + unit: Some("km**3/s**2".to_string(),), + }, + mass: KvnValue { + value: 1913.0, + unit: Some("kg".to_string(),), + }, + solar_rad_area: KvnValue { + value: 10.0, + unit: Some("m**2".to_string(),), + }, + solar_rad_coeff: KvnValue { + value: 1.3, + unit: None, + }, + drag_area: KvnValue { + value: 10.0, + unit: Some("m**2".to_string(),), + }, + drag_coeff: KvnValue { + value: 2.3, + unit: None, + }, + man_epoch_ignition: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 9, + minute: 0, + second: 34, + fractional_second: 0.10000000000000142, + }, + man_duration: KvnValue { + value: 132.6, + unit: Some("s".to_string(),), + }, + man_delta_mass: KvnValue { + value: -18.418, + unit: Some("kg".to_string(),), + }, + man_ref_frame: KvnValue { + value: "EME2000".to_string(), + unit: None, + }, + man_dv_1: KvnValue { + value: -0.023257, + unit: Some("km/s".to_string(),), + }, + man_dv_2: KvnValue { + value: 0.0168316, + unit: Some("km/s".to_string(),), + }, + man_dv_3: KvnValue { + value: -0.00893444, + unit: Some("km/s".to_string(),), + }, + },) ); } } diff --git a/crates/lox_derive/Cargo.toml b/crates/lox_derive/Cargo.toml new file mode 100644 index 00000000..2d426b84 --- /dev/null +++ b/crates/lox_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "lox_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.20" +syn = "1.0.98" \ No newline at end of file diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs new file mode 100644 index 00000000..fe2a8437 --- /dev/null +++ b/crates/lox_derive/src/lib.rs @@ -0,0 +1,108 @@ +use quote::quote; +use syn::spanned::Spanned; + +#[proc_macro_derive(KvnDeserialize)] +pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let item = syn::parse_macro_input!(item as syn::DeriveInput); + let name = &item.ident; + + let syn::Data::Struct(strukt) = item.data else { + return syn::Error::new_spanned( + &item, + "only structs are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into(); + }; + + let fields = match strukt.fields { + syn::Fields::Named(syn::FieldsNamed { named, .. }) => named, + _ => { + return syn::Error::new_spanned( + &strukt.fields, + "only named fields are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into() + } + }; + + let field_initializers: Result, _> = fields + .iter() + .enumerate() + .map(|(_, field)| { + let field_name = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = field.ty.span().source_text().unwrap(); + + let (parser_function, parser_error_type, parser_unit_parameter) = + match field_type.as_str() { + "KvnDateTimeValue" => ( + quote! { parse_kvn_datetime_line }, + quote! { KvnDeserializerErr::DateTime}, + quote! {}, + ), + "KvnStringValue" => ( + quote! { parse_kvn_string_line }, + quote! { KvnDeserializerErr::String }, + //@TODO make unit dynamic according to the definition + quote! { ,true }, + ), + "KvnNumericValue" => ( + quote! { parse_kvn_numeric_line }, + quote! { KvnDeserializerErr::Number }, + //@TODO make unit dynamic according to the definition + quote! { ,true }, + ), + "KvnIntegerValue" => ( + quote! { parse_kvn_integer_line }, + quote! { KvnDeserializerErr::Number }, + //@TODO make unit dynamic according to the definition + quote! { ,true }, + ), + _ => { + return Err(syn::Error::new_spanned( + &field, + "unsupported field type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()); + } + }; + + Ok(quote! { + #field_name: #parser_function( + #expected_kvn_name, + lines.next().ok_or(KvnDeserializerErr::UnexpectedEndOfInput)? + #parser_unit_parameter + ).map_err(|x| #parser_error_type(x))?.1, + }) + }) + .collect(); + + if let Err(e) = field_initializers { + return e; + } + + let field_initializers = field_initializers.unwrap(); + + let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); + + let deserializer = quote! { + impl #impl_generics KvnDeserializer<#name> for #name #type_generics + #where_clause + { + fn deserialize<'a>(lines: &mut dyn Iterator) -> Result<#name, KvnDeserializerErr<&'a str>> { + Ok(#name { + #(#field_initializers)* + }) + } + } + }; + + deserializer.into() +} From 874ec8a4fa02f23eabc9f932c3da80214ee0e51a Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Apr 2024 23:36:44 +0200 Subject: [PATCH 049/150] Move KVN parser to separate file --- crates/lox-utils/src/ndm/kvn.rs | 1 + crates/lox-utils/src/ndm/kvn/opm.rs | 578 +----------------------- crates/lox-utils/src/ndm/kvn/parser.rs | 588 +++++++++++++++++++++++++ crates/lox_derive/src/lib.rs | 3 + 4 files changed, 595 insertions(+), 575 deletions(-) create mode 100644 crates/lox-utils/src/ndm/kvn/parser.rs diff --git a/crates/lox-utils/src/ndm/kvn.rs b/crates/lox-utils/src/ndm/kvn.rs index 887a48d8..dbd9a0e6 100644 --- a/crates/lox-utils/src/ndm/kvn.rs +++ b/crates/lox-utils/src/ndm/kvn.rs @@ -1 +1,2 @@ pub mod opm; +pub mod parser; diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index dcc71d4e..3e2bd465 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -6,17 +6,9 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ -// KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf - use lox_derive::KvnDeserialize; -use nom::bytes::complete as nb; -use nom::character::complete as nc; -use nom::sequence as ns; -use regex::Regex; -type KvnStringValue = KvnValue; -type KvnIntegerValue = KvnValue; -type KvnNumericValue = KvnValue; +use super::parser::{KvnDateTimeValue, KvnNumericValue, KvnStringValue}; #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct Opm { @@ -63,574 +55,10 @@ pub struct Opm { man_dv_3: KvnNumericValue, } -#[derive(PartialEq, Debug)] -pub enum KvnStringLineParserErr { - ParseError(nom::Err>), - EmptyValue, -} - -#[derive(PartialEq, Debug)] -pub enum KvnNumberLineParserErr { - ParseError(nom::Err>), - EmptyValue, - InvalidFormat, -} - -#[derive(PartialEq, Debug)] -pub enum KvnDateTimeParserErr { - ParseError(nom::Err>), - InvalidDateFormat, - EmptyValue, -} - -#[derive(PartialEq, Debug)] -pub enum KvnDeserializerErr { - String(KvnStringLineParserErr), - DateTime(KvnDateTimeParserErr), - Number(KvnNumberLineParserErr), - UnexpectedEndOfInput, -} - -#[derive(PartialEq, Debug, Default)] -pub struct KvnValue { - pub value: V, - pub unit: Option, -} - -#[derive(PartialEq, Debug, Default)] -pub struct KvnDateTimeValue { - year: u16, - month: u8, - day: u8, - hour: u8, - minute: u8, - second: u8, - fractional_second: f64, -} - -pub trait KvnDeserializer { - fn deserialize<'a>( - lines: &mut dyn Iterator, - ) -> Result>; -} - -fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { - let (input, _) = nc::space0(input)?; - - let (remaining, _) = nb::tag("COMMENT ")(input)?; - - Ok(("", remaining)) -} - -fn kvn_line<'a>(key: &'a str, input: &'a str) -> nom::IResult<&'a str, (&'a str, &'a str)> { - let equals = ns::tuple(( - nc::space0::<_, nom::error::Error<_>>, - nc::char('='), - nc::space0, - )); - - let value = nc::not_line_ending; - - let kvn = ns::separated_pair(nb::tag(key), equals, value); - - ns::delimited(nc::space0, kvn, nc::space0)(input) -} - -fn parse_kvn_string_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> Result<(&'a str, KvnStringValue), KvnStringLineParserErr<&'a str>> { - if key == "COMMENT" { - let (_, comment) = - comment_line(input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; - - return Ok(( - "", - KvnValue { - value: comment.to_owned(), - unit: None, - }, - )); - } - - let (remaining, result) = - kvn_line(key, input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; - - let parsed_right_hand_side = result.1; - - let (parsed_value, parsed_unit) = if with_unit { - // This unwrap is okay here because this regex never changes after testing - let re = Regex::new(r"(.*?)(\[(.*)\])?$").unwrap(); - - // This unwrap is okay because .* will always match - let captures = re.captures(parsed_right_hand_side).unwrap(); - - ( - captures.get(1).unwrap().as_str(), - captures.get(3).map(|f| f.as_str()), - ) - } else { - (parsed_right_hand_side, None) - }; - - if parsed_value.len() == 0 { - return Err(KvnStringLineParserErr::EmptyValue); - } - - let parsed_value = parsed_value.trim_end(); - - Ok(( - remaining, - KvnValue { - value: parsed_value.to_owned(), - unit: parsed_unit.map(|x| x.to_owned()), - }, - )) -} - -fn parse_kvn_integer_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> Result<(&'a str, KvnIntegerValue), KvnNumberLineParserErr<&'a str>> { - parse_kvn_string_line(key, input, with_unit) - .map_err(|e| match e { - KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, - KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), - }) - .and_then(|result| { - let value = result - .1 - .value - .parse::() - .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; - - Ok(( - "", - KvnValue { - value, - unit: result.1.unit, - }, - )) - }) -} - -fn parse_kvn_numeric_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> Result<(&'a str, KvnNumericValue), KvnNumberLineParserErr<&'a str>> { - parse_kvn_string_line(key, input, with_unit) - .map_err(|e| match e { - KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, - KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), - }) - .and_then(|result| { - let value = fast_float::parse(result.1.value) - .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; - - Ok(( - "", - KvnValue { - value, - unit: result.1.unit, - }, - )) - }) -} - -fn parse_kvn_datetime_line<'a>( - key: &'a str, - input: &'a str, -) -> Result<(&'a str, KvnDateTimeValue), KvnDateTimeParserErr<&'a str>> { - let (_, result) = kvn_line(key, input).map_err(|e| KvnDateTimeParserErr::ParseError(e))?; - - let parsed_value = result.1; - - if parsed_value.len() == 0 { - return Err(KvnDateTimeParserErr::EmptyValue); - } - - let parsed_value = parsed_value.trim_end(); - - // Taken from CCSDS 502.0-B-3 Figure F-5: Regex Pattern for CCSDS Timecode - // This unwrap is okay here because this regex never changes after testing - let re = Regex::new( - r"^(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))$", - ) - .unwrap(); - - let captures = re - .captures(parsed_value) - .ok_or(KvnDateTimeParserErr::InvalidDateFormat)?; - - // yr is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let year = captures - .name("yr") - .unwrap() - .as_str() - .parse::() - .unwrap(); - - // We don't do full validation of the date values. We only care if they - // have the expected number of digits - - // mo is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let month = captures.name("mo").unwrap().as_str().parse::().unwrap(); - - // day is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let day = captures.name("dy").unwrap().as_str().parse::().unwrap(); - - // hr is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let hour = captures.name("hr").unwrap().as_str().parse::().unwrap(); - - // mn is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let minute = captures.name("mn").unwrap().as_str().parse::().unwrap(); - - // sc is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let full_second = captures - .name("sc") - .unwrap() - .as_str() - .parse::() - .unwrap(); - - let second = full_second.floor() as u8; - - let fractional_second = full_second.fract(); - - Ok(( - "", - KvnDateTimeValue { - year, - month, - day, - hour, - minute, - second, - fractional_second, - }, - )) -} - mod test { - use super::*; - - #[test] - fn test_parse_kvn_string_line() { - // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values - // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnStringLineParserErr::EmptyValue) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnStringLineParserErr::EmptyValue) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD =", true), - Err(KvnStringLineParserErr::EmptyValue) - ); - - // 7.4.7 Any white space immediately preceding the end of line shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG ", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - - // a) there must be at least one blank character between the value and the units text; - // b) the units must be enclosed within square brackets (e.g., ‘[m]’); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: Some("km".to_string()) - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: Some("km".to_string()) - } - )) - ); - - assert_eq!( - parse_kvn_string_line("ASD", "ASD = [km]", true), - Err(KvnStringLineParserErr::EmptyValue) - ); - - assert_eq!( - parse_kvn_string_line("ASD", "ASD [km]", true), - Err(KvnStringLineParserErr::ParseError(nom::Err::Error( - nom::error::Error { - input: "[km]", - code: nom::error::ErrorKind::Char - } - ))) - ); - assert_eq!( - parse_kvn_string_line("ASD", " = [km]", true), - Err(KvnStringLineParserErr::ParseError(nom::Err::Error( - nom::error::Error { - input: "= [km]", - code: nom::error::ErrorKind::Tag - } - ))) - ); - - // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", " ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - - // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. - // [...] White space shall be retained (shall be significant) in comment values. - - assert_eq!( - parse_kvn_string_line("COMMENT", " COMMENT asd a asd a ads as ", true), - Ok(( - "", - KvnValue { - value: "asd a asd a ads as ".to_string(), - unit: None - } - )) - ); - - assert_eq!( - parse_kvn_string_line("COMMENT", " COMMENT ", true), - Ok(( - "", - KvnValue { - value: "".to_string(), - unit: None - } - )) - ); - - // 7.4.4 Keywords must be uppercase and must not contain blanks - //@TODO parse dates and floats and integers - //@TODO return error code when the key doesn't exist - } - - #[test] - fn test_parse_kvn_integer_line() { - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = 28800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: 28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = 00028800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: 28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = -28800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: -28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = -28800", - true - ), - Ok(( - "", - KvnValue { - value: -28800, - unit: None - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(KvnNumberLineParserErr::InvalidFormat) - ); - - assert_eq!( - parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(KvnNumberLineParserErr::EmptyValue) - ); - } - - #[test] - fn test_parse_kvn_numeric_line() { - assert_eq!( - parse_kvn_numeric_line("X", "X = 66559942 [km]", true), - Ok(( - "", - KvnValue { - value: 66559942f64, - unit: Some("km".to_string()) - }, - )) - ); + use crate::ndm::kvn::parser::KvnValue; - assert_eq!( - parse_kvn_numeric_line("X", "X = 6655.9942 [km]", true), - Ok(( - "", - KvnValue { - value: 6655.9942, - unit: Some("km".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_numeric_line("CX_X", "CX_X = 5.801003223606e-05", true), - Ok(( - "", - KvnValue { - value: 5.801003223606e-05, - unit: None - }, - )) - ); - } - - #[test] - fn test_parse_kvn_datetime_line() { - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:00.123"), - Ok(( - "", - KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - )) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:01"), - Ok(( - "", - KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 1, - fractional_second: 0.0, - }, - )) - ); - - // @TODO add support for ddd format - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), - Err(KvnDateTimeParserErr::InvalidDateFormat) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), - Err(KvnDateTimeParserErr::InvalidDateFormat) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), - Err(KvnDateTimeParserErr::EmptyValue) - ); - } + use super::*; #[test] fn test_parse_json() { diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs new file mode 100644 index 00000000..a37a3747 --- /dev/null +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -0,0 +1,588 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +// KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf + +use nom::bytes::complete as nb; +use nom::character::complete as nc; +use nom::sequence as ns; +use regex::Regex; + +pub type KvnStringValue = KvnValue; +pub type KvnIntegerValue = KvnValue; +pub type KvnNumericValue = KvnValue; + +#[derive(PartialEq, Debug)] +pub enum KvnStringLineParserErr { + ParseError(nom::Err>), + EmptyValue, +} + +#[derive(PartialEq, Debug)] +pub enum KvnNumberLineParserErr { + ParseError(nom::Err>), + EmptyValue, + InvalidFormat, +} + +#[derive(PartialEq, Debug)] +pub enum KvnDateTimeParserErr { + ParseError(nom::Err>), + InvalidDateFormat, + EmptyValue, +} + +#[derive(PartialEq, Debug)] +pub enum KvnDeserializerErr { + String(KvnStringLineParserErr), + DateTime(KvnDateTimeParserErr), + Number(KvnNumberLineParserErr), + UnexpectedEndOfInput, +} + +#[derive(PartialEq, Debug, Default)] +pub struct KvnValue { + pub value: V, + pub unit: Option, +} + +#[derive(PartialEq, Debug, Default)] +pub struct KvnDateTimeValue { + pub year: u16, + pub month: u8, + pub day: u8, + pub hour: u8, + pub minute: u8, + pub second: u8, + pub fractional_second: f64, +} + +pub trait KvnDeserializer { + fn deserialize<'a>( + lines: &mut dyn Iterator, + ) -> Result>; +} + +fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { + let (input, _) = nc::space0(input)?; + + let (remaining, _) = nb::tag("COMMENT ")(input)?; + + Ok(("", remaining)) +} + +fn kvn_line<'a>(key: &'a str, input: &'a str) -> nom::IResult<&'a str, (&'a str, &'a str)> { + let equals = ns::tuple(( + nc::space0::<_, nom::error::Error<_>>, + nc::char('='), + nc::space0, + )); + + let value = nc::not_line_ending; + + let kvn = ns::separated_pair(nb::tag(key), equals, value); + + ns::delimited(nc::space0, kvn, nc::space0)(input) +} + +pub fn parse_kvn_string_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnStringValue), KvnStringLineParserErr<&'a str>> { + if key == "COMMENT" { + let (_, comment) = + comment_line(input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; + + return Ok(( + "", + KvnValue { + value: comment.to_owned(), + unit: None, + }, + )); + } + + let (remaining, result) = + kvn_line(key, input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; + + let parsed_right_hand_side = result.1; + + let (parsed_value, parsed_unit) = if with_unit { + // This unwrap is okay here because this regex never changes after testing + let re = Regex::new(r"(.*?)(\[(.*)\])?$").unwrap(); + + // This unwrap is okay because .* will always match + let captures = re.captures(parsed_right_hand_side).unwrap(); + + ( + captures.get(1).unwrap().as_str(), + captures.get(3).map(|f| f.as_str()), + ) + } else { + (parsed_right_hand_side, None) + }; + + if parsed_value.len() == 0 { + return Err(KvnStringLineParserErr::EmptyValue); + } + + let parsed_value = parsed_value.trim_end(); + + Ok(( + remaining, + KvnValue { + value: parsed_value.to_owned(), + unit: parsed_unit.map(|x| x.to_owned()), + }, + )) +} + +pub fn parse_kvn_integer_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnIntegerValue), KvnNumberLineParserErr<&'a str>> { + parse_kvn_string_line(key, input, with_unit) + .map_err(|e| match e { + KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, + KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), + }) + .and_then(|result| { + let value = result + .1 + .value + .parse::() + .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; + + Ok(( + "", + KvnValue { + value, + unit: result.1.unit, + }, + )) + }) +} + +pub fn parse_kvn_numeric_line<'a>( + key: &'a str, + input: &'a str, + with_unit: bool, +) -> Result<(&'a str, KvnNumericValue), KvnNumberLineParserErr<&'a str>> { + parse_kvn_string_line(key, input, with_unit) + .map_err(|e| match e { + KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, + KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), + }) + .and_then(|result| { + let value = fast_float::parse(result.1.value) + .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; + + Ok(( + "", + KvnValue { + value, + unit: result.1.unit, + }, + )) + }) +} + +pub fn parse_kvn_datetime_line<'a>( + key: &'a str, + input: &'a str, +) -> Result<(&'a str, KvnDateTimeValue), KvnDateTimeParserErr<&'a str>> { + let (_, result) = kvn_line(key, input).map_err(|e| KvnDateTimeParserErr::ParseError(e))?; + + let parsed_value = result.1; + + if parsed_value.len() == 0 { + return Err(KvnDateTimeParserErr::EmptyValue); + } + + let parsed_value = parsed_value.trim_end(); + + // Taken from CCSDS 502.0-B-3 Figure F-5: Regex Pattern for CCSDS Timecode + // This unwrap is okay here because this regex never changes after testing + let re = Regex::new( + r"^(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))$", + ) + .unwrap(); + + let captures = re + .captures(parsed_value) + .ok_or(KvnDateTimeParserErr::InvalidDateFormat)?; + + // yr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let year = captures + .name("yr") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + // We don't do full validation of the date values. We only care if they + // have the expected number of digits + + // mo is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let month = captures.name("mo").unwrap().as_str().parse::().unwrap(); + + // day is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let day = captures.name("dy").unwrap().as_str().parse::().unwrap(); + + // hr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let hour = captures.name("hr").unwrap().as_str().parse::().unwrap(); + + // mn is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let minute = captures.name("mn").unwrap().as_str().parse::().unwrap(); + + // sc is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let full_second = captures + .name("sc") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + let second = full_second.floor() as u8; + + let fractional_second = full_second.fract(); + + Ok(( + "", + KvnDateTimeValue { + year, + month, + day, + hour, + minute, + second, + fractional_second, + }, + )) +} + +mod test { + use super::*; + + #[test] + fn test_parse_kvn_string_line() { + // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values + // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ", true), + Err(KvnStringLineParserErr::EmptyValue) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ", true), + Err(KvnStringLineParserErr::EmptyValue) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD =", true), + Err(KvnStringLineParserErr::EmptyValue) + ); + + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG ", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + + // a) there must be at least one blank character between the value and the units text; + // b) the units must be enclosed within square brackets (e.g., ‘[m]’); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: Some("km".to_string()) + } + )) + ); + assert_eq!( + parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: Some("km".to_string()) + } + )) + ); + + assert_eq!( + parse_kvn_string_line("ASD", "ASD = [km]", true), + Err(KvnStringLineParserErr::EmptyValue) + ); + + assert_eq!( + parse_kvn_string_line("ASD", "ASD [km]", true), + Err(KvnStringLineParserErr::ParseError(nom::Err::Error( + nom::error::Error { + input: "[km]", + code: nom::error::ErrorKind::Char + } + ))) + ); + assert_eq!( + parse_kvn_string_line("ASD", " = [km]", true), + Err(KvnStringLineParserErr::ParseError(nom::Err::Error( + nom::error::Error { + input: "= [km]", + code: nom::error::ErrorKind::Tag + } + ))) + ); + + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + assert_eq!( + parse_kvn_string_line("ASD", " ASD = ASDFG", true), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + + // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. + // [...] White space shall be retained (shall be significant) in comment values. + + assert_eq!( + parse_kvn_string_line("COMMENT", " COMMENT asd a asd a ads as ", true), + Ok(( + "", + KvnValue { + value: "asd a asd a ads as ".to_string(), + unit: None + } + )) + ); + + assert_eq!( + parse_kvn_string_line("COMMENT", " COMMENT ", true), + Ok(( + "", + KvnValue { + value: "".to_string(), + unit: None + } + )) + ); + + // 7.4.4 Keywords must be uppercase and must not contain blanks + //@TODO parse dates and floats and integers + //@TODO return error code when the key doesn't exist + } + + #[test] + fn test_parse_kvn_integer_line() { + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = 28800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = 00028800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = -28800 [s]", + true + ), + Ok(( + "", + KvnValue { + value: -28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line( + "SCLK_OFFSET_AT_EPOCH", + "SCLK_OFFSET_AT_EPOCH = -28800", + true + ), + Ok(( + "", + KvnValue { + value: -28800, + unit: None + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), + Err(KvnNumberLineParserErr::InvalidFormat) + ); + + assert_eq!( + parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), + Err(KvnNumberLineParserErr::EmptyValue) + ); + } + + #[test] + fn test_parse_kvn_numeric_line() { + assert_eq!( + parse_kvn_numeric_line("X", "X = 66559942 [km]", true), + Ok(( + "", + KvnValue { + value: 66559942f64, + unit: Some("km".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_numeric_line("X", "X = 6655.9942 [km]", true), + Ok(( + "", + KvnValue { + value: 6655.9942, + unit: Some("km".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_numeric_line("CX_X", "CX_X = 5.801003223606e-05", true), + Ok(( + "", + KvnValue { + value: 5.801003223606e-05, + unit: None + }, + )) + ); + } + + #[test] + fn test_parse_kvn_datetime_line() { + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:00.123"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + )) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:01"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 1, + fractional_second: 0.0, + }, + )) + ); + + // @TODO add support for ddd format + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), + Err(KvnDateTimeParserErr::InvalidDateFormat) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), + Err(KvnDateTimeParserErr::InvalidDateFormat) + ); + + assert_eq!( + parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), + Err(KvnDateTimeParserErr::EmptyValue) + ); + } +} diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index fe2a8437..c279fa8a 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -93,6 +93,9 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); let deserializer = quote! { + use crate::ndm::kvn::parser::{KvnDeserializer, KvnDeserializerErr}; + use crate::ndm::kvn::parser::{parse_kvn_string_line, parse_kvn_datetime_line, parse_kvn_numeric_line, parse_kvn_integer_line}; + impl #impl_generics KvnDeserializer<#name> for #name #type_generics #where_clause { From 7fb1d7e4746f5cc52b09e5be7a82e028d37867b0 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 29 Apr 2024 23:39:14 +0200 Subject: [PATCH 050/150] Add missing copyright header --- crates/lox_derive/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index c279fa8a..47d4f163 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + use quote::quote; use syn::spanned::Spanned; From 31527341fed0a2b814cd81d3560578d84fb651a9 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 2 May 2024 22:40:51 +0200 Subject: [PATCH 051/150] Implement option type --- crates/lox-utils/src/ndm/kvn/opm.rs | 5 +- crates/lox-utils/src/ndm/kvn/parser.rs | 365 +++++++++++++++++++++---- crates/lox_derive/Cargo.toml | 3 +- crates/lox_derive/src/lib.rs | 171 +++++++++--- 4 files changed, 443 insertions(+), 101 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 3e2bd465..bda47028 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -21,7 +21,6 @@ pub struct Opm { object_id: KvnStringValue, center_name: KvnStringValue, ref_frame: KvnStringValue, - // ref_frame_epoch: KvnDateTimeValue, time_system: KvnStringValue, // comment: KvnStringValue, epoch: KvnDateTimeValue, @@ -161,9 +160,7 @@ MAN_DV_1 = 0.00101500 [km/s] MAN_DV_2 = -0.00187300 [km/s] MAN_DV_3 = 0.00000000 [km/s]"#; - let mut lines = kvn.lines(); - - let opm = Opm::deserialize(&mut lines); + let opm = Opm::deserialize(&mut kvn.lines().peekable()); assert_eq!( opm, diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index a37a3747..2e8fa8d2 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -10,6 +10,7 @@ use nom::bytes::complete as nb; use nom::character::complete as nc; +use nom::error::{ErrorKind, ParseError}; use nom::sequence as ns; use regex::Regex; @@ -17,32 +18,114 @@ pub type KvnStringValue = KvnValue; pub type KvnIntegerValue = KvnValue; pub type KvnNumericValue = KvnValue; -#[derive(PartialEq, Debug)] -pub enum KvnStringLineParserErr { - ParseError(nom::Err>), +#[derive(Debug, PartialEq)] +pub enum KvnParserErr { + KeywordNotFound, EmptyValue, + ParserError(I, ErrorKind), } #[derive(PartialEq, Debug)] pub enum KvnNumberLineParserErr { - ParseError(nom::Err>), + ParserError(I, ErrorKind), + KeywordNotFound, EmptyValue, InvalidFormat, } #[derive(PartialEq, Debug)] pub enum KvnDateTimeParserErr { - ParseError(nom::Err>), - InvalidDateFormat, + ParserError(I, ErrorKind), + KeywordNotFound, EmptyValue, + InvalidFormat, } #[derive(PartialEq, Debug)] pub enum KvnDeserializerErr { - String(KvnStringLineParserErr), - DateTime(KvnDateTimeParserErr), - Number(KvnNumberLineParserErr), + InvalidDateTimeFormat, + InvalidNumberFormat, + KeywordNotFound, + EmptyValue, UnexpectedEndOfInput, + GeneralParserError(I, ErrorKind), +} + +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { + match value { + nom::Err::Error(KvnParserErr::EmptyValue) + | nom::Err::Failure(KvnParserErr::EmptyValue) => KvnDeserializerErr::EmptyValue, + nom::Err::Error(KvnParserErr::KeywordNotFound) + | nom::Err::Failure(KvnParserErr::KeywordNotFound) => { + KvnDeserializerErr::KeywordNotFound + } + nom::Err::Error(KvnParserErr::ParserError(i, k)) + | nom::Err::Failure(KvnParserErr::ParserError(i, k)) => { + KvnDeserializerErr::GeneralParserError(i, k) + } + // We don't use streaming deserialization + nom::Err::Incomplete(_) => unimplemented!(), + } + } +} + +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { + match value { + nom::Err::Error(KvnDateTimeParserErr::EmptyValue) + | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue) => KvnDeserializerErr::EmptyValue, + nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound) + | nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound) => { + KvnDeserializerErr::KeywordNotFound + } + nom::Err::Error(KvnDateTimeParserErr::InvalidFormat) + | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat) => { + KvnDeserializerErr::InvalidDateTimeFormat + } + nom::Err::Error(KvnDateTimeParserErr::ParserError(i, k)) + | nom::Err::Failure(KvnDateTimeParserErr::ParserError(i, k)) => { + KvnDeserializerErr::GeneralParserError(i, k) + } + // We don't use streaming deserialization + nom::Err::Incomplete(_) => unimplemented!(), + } + } +} + +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { + match value { + nom::Err::Error(KvnNumberLineParserErr::EmptyValue) + | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) => { + KvnDeserializerErr::EmptyValue + } + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) + | nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) => { + KvnDeserializerErr::KeywordNotFound + } + nom::Err::Error(KvnNumberLineParserErr::InvalidFormat) + | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat) => { + KvnDeserializerErr::InvalidNumberFormat + } + nom::Err::Error(KvnNumberLineParserErr::ParserError(i, k)) + | nom::Err::Failure(KvnNumberLineParserErr::ParserError(i, k)) => { + KvnDeserializerErr::GeneralParserError(i, k) + } + // We don't use streaming deserialization + nom::Err::Incomplete(_) => unimplemented!(), + } + } +} + +impl ParseError for KvnParserErr { + fn from_error_kind(input: I, kind: ErrorKind) -> Self { + KvnParserErr::ParserError(input, kind) + } + + fn append(_: I, _: ErrorKind, other: Self) -> Self { + other + } } #[derive(PartialEq, Debug, Default)] @@ -64,11 +147,11 @@ pub struct KvnDateTimeValue { pub trait KvnDeserializer { fn deserialize<'a>( - lines: &mut dyn Iterator, + lines: &mut std::iter::Peekable>, ) -> Result>; } -fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { +fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str, KvnParserErr<&'a str>> { let (input, _) = nc::space0(input)?; let (remaining, _) = nb::tag("COMMENT ")(input)?; @@ -76,12 +159,28 @@ fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str> { Ok(("", remaining)) } -fn kvn_line<'a>(key: &'a str, input: &'a str) -> nom::IResult<&'a str, (&'a str, &'a str)> { - let equals = ns::tuple(( - nc::space0::<_, nom::error::Error<_>>, - nc::char('='), - nc::space0, - )); +pub fn kvn_line_matches_key<'a>(key: &'a str, input: &'a str) -> bool { + let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); + + // This function should return true in the case of malformed lines which + // are missing the keyword + if equals(input).is_ok() { + return true; + } + + ns::delimited(nc::space0, nb::tag(key), equals)(input).is_ok() +} + +fn kvn_line<'a>( + key: &'a str, + input: &'a str, +) -> nom::IResult<&'a str, (&'a str, &'a str), KvnParserErr<&'a str>> { + let mut equals = ns::tuple((nc::space0::<_, KvnParserErr<_>>, nc::char('='), nc::space0)); + + match equals(input) { + Ok(_) => return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound)), + Err(_) => (), + } let value = nc::not_line_ending; @@ -94,10 +193,9 @@ pub fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnStringValue), KvnStringLineParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { if key == "COMMENT" { - let (_, comment) = - comment_line(input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; + let (_, comment) = comment_line(input)?; return Ok(( "", @@ -108,8 +206,7 @@ pub fn parse_kvn_string_line<'a>( )); } - let (remaining, result) = - kvn_line(key, input).map_err(|e| KvnStringLineParserErr::ParseError(e))?; + let (remaining, result) = kvn_line(key, input)?; let parsed_right_hand_side = result.1; @@ -129,7 +226,7 @@ pub fn parse_kvn_string_line<'a>( }; if parsed_value.len() == 0 { - return Err(KvnStringLineParserErr::EmptyValue); + return Err(nom::Err::Failure(KvnParserErr::EmptyValue)); } let parsed_value = parsed_value.trim_end(); @@ -147,18 +244,35 @@ pub fn parse_kvn_integer_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnIntegerValue), KvnNumberLineParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnIntegerValue, KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { - KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, - KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), + nom::Err::Failure(KvnParserErr::EmptyValue) => { + nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) + } + nom::Err::Error(KvnParserErr::EmptyValue) => { + nom::Err::Error(KvnNumberLineParserErr::EmptyValue) + } + nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { + nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) + } + nom::Err::Error(KvnParserErr::ParserError(input, code)) => { + nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) + } + nom::Err::Failure(KvnParserErr::KeywordNotFound) => { + nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) + } + nom::Err::Error(KvnParserErr::KeywordNotFound) => { + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) + } + nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), }) .and_then(|result| { let value = result .1 .value .parse::() - .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; + .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat))?; Ok(( "", @@ -174,15 +288,32 @@ pub fn parse_kvn_numeric_line<'a>( key: &'a str, input: &'a str, with_unit: bool, -) -> Result<(&'a str, KvnNumericValue), KvnNumberLineParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { - KvnStringLineParserErr::EmptyValue => KvnNumberLineParserErr::EmptyValue, - KvnStringLineParserErr::ParseError(e) => KvnNumberLineParserErr::ParseError(e), + nom::Err::Failure(KvnParserErr::EmptyValue) => { + nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) + } + nom::Err::Error(KvnParserErr::EmptyValue) => { + nom::Err::Error(KvnNumberLineParserErr::EmptyValue) + } + nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { + nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) + } + nom::Err::Error(KvnParserErr::ParserError(input, code)) => { + nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) + } + nom::Err::Failure(KvnParserErr::KeywordNotFound) => { + nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) + } + nom::Err::Error(KvnParserErr::KeywordNotFound) => { + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) + } + nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), }) .and_then(|result| { let value = fast_float::parse(result.1.value) - .map_err(|_| KvnNumberLineParserErr::InvalidFormat)?; + .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat))?; Ok(( "", @@ -197,13 +328,33 @@ pub fn parse_kvn_numeric_line<'a>( pub fn parse_kvn_datetime_line<'a>( key: &'a str, input: &'a str, -) -> Result<(&'a str, KvnDateTimeValue), KvnDateTimeParserErr<&'a str>> { - let (_, result) = kvn_line(key, input).map_err(|e| KvnDateTimeParserErr::ParseError(e))?; +) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { + let (_, result) = kvn_line(key, input).map_err(|e| match e { + nom::Err::Failure(KvnParserErr::EmptyValue) => { + nom::Err::Failure(KvnDateTimeParserErr::EmptyValue) + } + nom::Err::Error(KvnParserErr::EmptyValue) => { + nom::Err::Error(KvnDateTimeParserErr::EmptyValue) + } + nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { + nom::Err::Failure(KvnDateTimeParserErr::ParserError(input, code)) + } + nom::Err::Error(KvnParserErr::ParserError(input, code)) => { + nom::Err::Error(KvnDateTimeParserErr::ParserError(input, code)) + } + nom::Err::Failure(KvnParserErr::KeywordNotFound) => { + nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound) + } + nom::Err::Error(KvnParserErr::KeywordNotFound) => { + nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound) + } + nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), + })?; let parsed_value = result.1; if parsed_value.len() == 0 { - return Err(KvnDateTimeParserErr::EmptyValue); + return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue)); } let parsed_value = parsed_value.trim_end(); @@ -217,7 +368,7 @@ pub fn parse_kvn_datetime_line<'a>( let captures = re .captures(parsed_value) - .ok_or(KvnDateTimeParserErr::InvalidDateFormat)?; + .ok_or(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat))?; // yr is a mandatory decimal in the regex so we expect the capture to be // always there and unwrap is fine @@ -275,8 +426,18 @@ pub fn parse_kvn_datetime_line<'a>( } mod test { + use lox_derive::KvnDeserialize; + use super::*; + #[test] + fn test_kvn_line_matches_key() { + assert!(!kvn_line_matches_key("ASD", "AAAAAD123 = ASDFG")); + assert!(kvn_line_matches_key("ASD", "ASD = ASDFG")); + assert!(!kvn_line_matches_key("ASD", "ASD ASD = ASDFG")); + assert!(kvn_line_matches_key("ASD", "= ASDFG")); + } + #[test] fn test_parse_kvn_string_line() { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values @@ -313,15 +474,15 @@ mod test { ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnStringLineParserErr::EmptyValue) + Err(nom::Err::Failure(KvnParserErr::EmptyValue)) ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(KvnStringLineParserErr::EmptyValue) + Err(nom::Err::Failure(KvnParserErr::EmptyValue)) ); assert_eq!( parse_kvn_string_line("ASD", "ASD =", true), - Err(KvnStringLineParserErr::EmptyValue) + Err(nom::Err::Failure(KvnParserErr::EmptyValue)) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. @@ -361,26 +522,19 @@ mod test { assert_eq!( parse_kvn_string_line("ASD", "ASD = [km]", true), - Err(KvnStringLineParserErr::EmptyValue) + Err(nom::Err::Failure(KvnParserErr::EmptyValue)) ); assert_eq!( parse_kvn_string_line("ASD", "ASD [km]", true), - Err(KvnStringLineParserErr::ParseError(nom::Err::Error( - nom::error::Error { - input: "[km]", - code: nom::error::ErrorKind::Char - } + Err(nom::Err::Error(KvnParserErr::ParserError( + "[km]", + nom::error::ErrorKind::Char ))) ); assert_eq!( parse_kvn_string_line("ASD", " = [km]", true), - Err(KvnStringLineParserErr::ParseError(nom::Err::Error( - nom::error::Error { - input: "= [km]", - code: nom::error::ErrorKind::Tag - } - ))) + Err(nom::Err::Failure(KvnParserErr::KeywordNotFound)) ); // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. @@ -489,12 +643,12 @@ mod test { assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(KvnNumberLineParserErr::InvalidFormat) + Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat)) ); assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(KvnNumberLineParserErr::EmptyValue) + Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue)) ); } @@ -572,17 +726,118 @@ mod test { assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), - Err(KvnDateTimeParserErr::InvalidDateFormat) + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat)) ); assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), - Err(KvnDateTimeParserErr::InvalidDateFormat) + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat)) ); assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), - Err(KvnDateTimeParserErr::EmptyValue) + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue)) + ); + } + + #[derive(KvnDeserialize, Default, Debug, PartialEq)] + pub struct KvnStruct { + comment: KvnStringValue, + string_value: KvnStringValue, + date_value: KvnDateTimeValue, + numeric_value: KvnNumericValue, + option_numeric_value: Option, + integer_value: KvnIntegerValue, + option_date_value: Option, + } + + #[test] + fn test_parse_whole_struct() { + let kvn = r#"COMMENT Generated by GSOC, R. Kiehling +STRING_VALUE = EUTELSAT W4 +DATE_VALUE = 2021-06-03T05:33:00.123 +NUMERIC_VALUE = 6655.9942 [km] +INTEGER_VALUE = 123 [km] +OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; + + assert_eq!( + KvnStruct::deserialize(&mut kvn.lines().peekable()), + Ok(KvnStruct { + comment: KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None + }, + string_value: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None + }, + date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123 + }, + numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string()) + }, + option_numeric_value: None, + integer_value: KvnValue { + value: 123, + unit: Some("km".to_string()) + }, + option_date_value: Some(KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123 + }) + }) + ); + + let kvn = r#"COMMENT Generated by GSOC, R. Kiehling +STRING_VALUE = EUTELSAT W4 +DATE_VALUE = 2021-06-03T05:33:00.123 +NUMERIC_VALUE = 6655.9942 [km] +INTEGER_VALUE = 123 [km]"#; + + assert_eq!( + KvnStruct::deserialize(&mut kvn.lines().peekable()), + Ok(KvnStruct { + comment: KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None + }, + string_value: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None + }, + date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123 + }, + numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string()) + }, + option_numeric_value: None, + integer_value: KvnValue { + value: 123, + unit: Some("km".to_string()) + }, + option_date_value: None + }) ); } } diff --git a/crates/lox_derive/Cargo.toml b/crates/lox_derive/Cargo.toml index 2d426b84..2b68007f 100644 --- a/crates/lox_derive/Cargo.toml +++ b/crates/lox_derive/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" proc-macro = true [dependencies] +proc-macro2 = "1.0.81" quote = "1.0.20" -syn = "1.0.98" \ No newline at end of file +syn = "1.0.98" diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 47d4f163..2d49d50e 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -7,7 +7,96 @@ */ use quote::quote; -use syn::spanned::Spanned; +use syn::{spanned::Spanned, Field}; + +fn generate_call_to_deserializer_for_kvn_type( + type_name: &str, + expected_kvn_name: &str, + field: &Field, +) -> Result { + match type_name { + "KvnDateTimeValue" => Ok(quote! { + parse_kvn_datetime_line( + #expected_kvn_name, + line, + ).map_err(|x| KvnDeserializerErr::from(x)) + .map(|x| x.1) + }), + "KvnStringValue" => Ok(quote! { + parse_kvn_string_line( + #expected_kvn_name, + line, + true + ).map_err(|x| KvnDeserializerErr::from(x)) + .map(|x| x.1) + }), + "KvnNumericValue" => Ok(quote! { + parse_kvn_numeric_line( + #expected_kvn_name, + line, + true + ).map_err(|x| KvnDeserializerErr::from(x)) + .map(|x| x.1) + }), + "KvnIntegerValue" => Ok(quote! { + parse_kvn_integer_line( + #expected_kvn_name, + line, + true + ).map_err(|x| KvnDeserializerErr::from(x)) + .map(|x| x.1) + }), + _ => Err(syn::Error::new_spanned( + &field, + "unsupported field type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()), + } +} + +fn generate_call_to_deserializer_for_option_type( + expected_kvn_name: &str, + field: &Field, +) -> Result { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + let type_name = type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(); + + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &expected_kvn_name, + &field, + )?; + + return Ok(quote! { + lines.next_if(|line| + kvn_line_matches_key( + #expected_kvn_name, + line + ) + ).map(|line| { + #deserializer_for_kvn_type + }).transpose()? + }); + } + } + } + + return Err( + syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + .into_compile_error() + .into(), + ); +} #[proc_macro_derive(KvnDeserialize)] pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { @@ -47,47 +136,37 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke // Unwrap is okay because we expect this span to come from the source code let field_type = field.ty.span().source_text().unwrap(); - let (parser_function, parser_error_type, parser_unit_parameter) = - match field_type.as_str() { - "KvnDateTimeValue" => ( - quote! { parse_kvn_datetime_line }, - quote! { KvnDeserializerErr::DateTime}, - quote! {}, - ), - "KvnStringValue" => ( - quote! { parse_kvn_string_line }, - quote! { KvnDeserializerErr::String }, - //@TODO make unit dynamic according to the definition - quote! { ,true }, - ), - "KvnNumericValue" => ( - quote! { parse_kvn_numeric_line }, - quote! { KvnDeserializerErr::Number }, - //@TODO make unit dynamic according to the definition - quote! { ,true }, - ), - "KvnIntegerValue" => ( - quote! { parse_kvn_integer_line }, - quote! { KvnDeserializerErr::Number }, - //@TODO make unit dynamic according to the definition - quote! { ,true }, - ), - _ => { - return Err(syn::Error::new_spanned( - &field, - "unsupported field type for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into()); + let parser = match field_type.as_str() { + "KvnDateTimeValue" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &field_type, + &expected_kvn_name, + &field, + )?; + + quote! { + lines.next().map_or_else( + || Err(KvnDeserializerErr::<&str>::UnexpectedEndOfInput), + |line| { + #deserializer_for_kvn_type + })? } - }; + } + "Option" => { + generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? + } + _ => { + return Err(syn::Error::new_spanned( + &field, + "unsupported field type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()); + } + }; Ok(quote! { - #field_name: #parser_function( - #expected_kvn_name, - lines.next().ok_or(KvnDeserializerErr::UnexpectedEndOfInput)? - #parser_unit_parameter - ).map_err(|x| #parser_error_type(x))?.1, + #field_name: #parser, }) }) .collect(); @@ -101,13 +180,23 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); let deserializer = quote! { + use std::iter::Peekable; + use crate::ndm::kvn::parser::{KvnDeserializer, KvnDeserializerErr}; - use crate::ndm::kvn::parser::{parse_kvn_string_line, parse_kvn_datetime_line, parse_kvn_numeric_line, parse_kvn_integer_line}; + use crate::ndm::kvn::parser::{ + kvn_line_matches_key, + parse_kvn_string_line, + parse_kvn_datetime_line, + parse_kvn_numeric_line, + parse_kvn_integer_line + }; impl #impl_generics KvnDeserializer<#name> for #name #type_generics #where_clause { - fn deserialize<'a>(lines: &mut dyn Iterator) -> Result<#name, KvnDeserializerErr<&'a str>> { + fn deserialize<'a>(lines: &mut std::iter::Peekable>) + -> Result<#name, KvnDeserializerErr<&'a str>> { + Ok(#name { #(#field_initializers)* }) From 8ee3512e3978fd78f3f778bb9e277a3903e69e72 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 18:43:52 +0200 Subject: [PATCH 052/150] Implement vec type deserializer --- crates/lox-utils/src/ndm/kvn/parser.rs | 174 ++++++++++++++++---- crates/lox_derive/src/lib.rs | 213 +++++++++++++++++-------- 2 files changed, 288 insertions(+), 99 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 2e8fa8d2..3c6abcf3 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -46,6 +46,7 @@ pub enum KvnDeserializerErr { InvalidDateTimeFormat, InvalidNumberFormat, KeywordNotFound, + UnexpectedKeyword, EmptyValue, UnexpectedEndOfInput, GeneralParserError(I, ErrorKind), @@ -145,10 +146,12 @@ pub struct KvnDateTimeValue { pub fractional_second: f64, } -pub trait KvnDeserializer { +pub trait KvnDeserializer { fn deserialize<'a>( lines: &mut std::iter::Peekable>, - ) -> Result>; + ) -> Result> + where + Self: Sized; } fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str, KvnParserErr<&'a str>> { @@ -160,15 +163,19 @@ fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str, KvnParserE } pub fn kvn_line_matches_key<'a>(key: &'a str, input: &'a str) -> bool { - let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); + if key == "COMMENT" { + ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input).is_ok() + } else { + let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); - // This function should return true in the case of malformed lines which - // are missing the keyword - if equals(input).is_ok() { - return true; - } + // This function should return true in the case of malformed lines which + // are missing the keyword + if equals(input).is_ok() { + return true; + } - ns::delimited(nc::space0, nb::tag(key), equals)(input).is_ok() + ns::delimited(nc::space0, nb::tag(key), equals)(input).is_ok() + } } fn kvn_line<'a>( @@ -740,36 +747,54 @@ mod test { ); } + #[derive(KvnDeserialize, Default, Debug, PartialEq)] + pub struct KvnChildStruct { + child_date_value: KvnDateTimeValue, + child_numeric_value: KvnNumericValue, + } + #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct KvnStruct { - comment: KvnStringValue, + comment: Vec, string_value: KvnStringValue, date_value: KvnDateTimeValue, numeric_value: KvnNumericValue, option_numeric_value: Option, integer_value: KvnIntegerValue, option_date_value: Option, + vec_child_struct: Vec, } #[test] fn test_parse_whole_struct() { let kvn = r#"COMMENT Generated by GSOC, R. Kiehling +COMMENT asdsda a1 adsd STRING_VALUE = EUTELSAT W4 DATE_VALUE = 2021-06-03T05:33:00.123 NUMERIC_VALUE = 6655.9942 [km] INTEGER_VALUE = 123 [km] -OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; +OPTION_DATE_VALUE = 2021-06-03T05:33:00.123 +CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 +CHILD_NUMERIC_VALUE = 6655.9942 [km] +CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 +CHILD_NUMERIC_VALUE = 6655.9942 [km]"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), Ok(KvnStruct { - comment: KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None - }, + comment: vec![ + KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None, + }, + KvnValue { + value: "asdsda a1 adsd".to_string(), + unit: None, + }, + ], string_value: KvnValue { value: "EUTELSAT W4".to_string(), - unit: None + unit: None, }, date_value: KvnDateTimeValue { year: 2021, @@ -778,16 +803,16 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; hour: 5, minute: 33, second: 0, - fractional_second: 0.123 + fractional_second: 0.123, }, numeric_value: KvnValue { value: 6655.9942, - unit: Some("km".to_string()) + unit: Some("km".to_string(),), }, option_numeric_value: None, integer_value: KvnValue { value: 123, - unit: Some("km".to_string()) + unit: Some("km".to_string(),), }, option_date_value: Some(KvnDateTimeValue { year: 2021, @@ -796,27 +821,111 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; hour: 5, minute: 33, second: 0, - fractional_second: 0.123 - }) - }) + fractional_second: 0.123, + },), + vec_child_struct: vec![ + KvnChildStruct { + child_date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + child_numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + }, + KvnChildStruct { + child_date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + child_numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + }, + ], + },) ); let kvn = r#"COMMENT Generated by GSOC, R. Kiehling +COMMENT asdsda a1 adsd STRING_VALUE = EUTELSAT W4 DATE_VALUE = 2021-06-03T05:33:00.123 NUMERIC_VALUE = 6655.9942 [km] -INTEGER_VALUE = 123 [km]"#; +INTEGER_VALUE = 123 [km] +OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), Ok(KvnStruct { - comment: KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None + comment: vec![ + KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None, + }, + KvnValue { + value: "asdsda a1 adsd".to_string(), + unit: None, + }, + ], + string_value: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None, }, + date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + option_numeric_value: None, + integer_value: KvnValue { + value: 123, + unit: Some("km".to_string(),), + }, + option_date_value: Some(KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + },), + vec_child_struct: vec![], + },) + ); + + let kvn = r#"STRING_VALUE = EUTELSAT W4 +DATE_VALUE = 2021-06-03T05:33:00.123 +NUMERIC_VALUE = 6655.9942 [km] +INTEGER_VALUE = 123 [km]"#; + + assert_eq!( + KvnStruct::deserialize(&mut kvn.lines().peekable()), + Ok(KvnStruct { + comment: vec![], string_value: KvnValue { value: "EUTELSAT W4".to_string(), - unit: None + unit: None, }, date_value: KvnDateTimeValue { year: 2021, @@ -825,19 +934,20 @@ INTEGER_VALUE = 123 [km]"#; hour: 5, minute: 33, second: 0, - fractional_second: 0.123 + fractional_second: 0.123, }, numeric_value: KvnValue { value: 6655.9942, - unit: Some("km".to_string()) + unit: Some("km".to_string(),), }, option_numeric_value: None, integer_value: KvnValue { value: 123, - unit: Some("km".to_string()) + unit: Some("km".to_string(),), }, - option_date_value: None - }) + option_date_value: None, + vec_child_struct: vec![], + },) ); } } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 2d49d50e..1152a244 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -6,52 +6,92 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +use proc_macro2::Span; use quote::quote; use syn::{spanned::Spanned, Field}; fn generate_call_to_deserializer_for_kvn_type( type_name: &str, expected_kvn_name: &str, - field: &Field, ) -> Result { match type_name { - "KvnDateTimeValue" => Ok(quote! { - parse_kvn_datetime_line( - #expected_kvn_name, - line, - ).map_err(|x| KvnDeserializerErr::from(x)) - .map(|x| x.1) - }), - "KvnStringValue" => Ok(quote! { - parse_kvn_string_line( - #expected_kvn_name, - line, - true - ).map_err(|x| KvnDeserializerErr::from(x)) - .map(|x| x.1) - }), - "KvnNumericValue" => Ok(quote! { - parse_kvn_numeric_line( - #expected_kvn_name, - line, - true - ).map_err(|x| KvnDeserializerErr::from(x)) - .map(|x| x.1) - }), - "KvnIntegerValue" => Ok(quote! { - parse_kvn_integer_line( - #expected_kvn_name, - line, - true - ).map_err(|x| KvnDeserializerErr::from(x)) - .map(|x| x.1) - }), - _ => Err(syn::Error::new_spanned( - &field, - "unsupported field type for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into()), + "KvnDateTimeValue" | "KvnNumericValue" | "KvnStringValue" | "KvnIntegerValue" => { + let parser = match type_name { + "KvnDateTimeValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_datetime_line( + #expected_kvn_name, + next_line, + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnStringValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnNumericValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnIntegerValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput), + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key( + #expected_kvn_name, + next_line, + ); + + let result = if line_matches { + let next_line = lines.next().unwrap(); + + Ok(#parser) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword) + }; + + result + } + } + }) + } + + type_value => { + let type_ident = syn::Ident::new(&type_value, Span::call_site()); + + Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_ident::deserialize(lines) + } else { + break; + }; + + result + } + }) + } } } @@ -74,18 +114,72 @@ fn generate_call_to_deserializer_for_option_type( let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( &type_name.as_ref(), &expected_kvn_name, - &field, )?; return Ok(quote! { - lines.next_if(|line| - kvn_line_matches_key( - #expected_kvn_name, - line - ) - ).map(|line| { - #deserializer_for_kvn_type - }).transpose()? + { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => Some(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) => None, + Err(e) => Err(e)?, + } + } + }); + } + } + } + + return Err( + syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + .into_compile_error() + .into(), + ); +} + +fn generate_call_to_deserializer_for_vec_type( + expected_kvn_name: &str, + field: &Field, +) -> Result { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + let type_name = type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(); + + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &expected_kvn_name, + )?; + + let type_ident = syn::Ident::new(&type_name, Span::call_site()); + + return Ok(quote! { + { + let mut items: Vec<#type_ident> = Vec::new(); + + loop { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => items.push(item), + Err( + crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword, + ) => break, + Err(e) => Err(e)?, + } + } + + items + } }); } } @@ -141,20 +235,16 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( &field_type, &expected_kvn_name, - &field, )?; quote! { - lines.next().map_or_else( - || Err(KvnDeserializerErr::<&str>::UnexpectedEndOfInput), - |line| { - #deserializer_for_kvn_type - })? + #deserializer_for_kvn_type? } } "Option" => { generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? } + "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, _ => { return Err(syn::Error::new_spanned( &field, @@ -180,22 +270,11 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); let deserializer = quote! { - use std::iter::Peekable; - - use crate::ndm::kvn::parser::{KvnDeserializer, KvnDeserializerErr}; - use crate::ndm::kvn::parser::{ - kvn_line_matches_key, - parse_kvn_string_line, - parse_kvn_datetime_line, - parse_kvn_numeric_line, - parse_kvn_integer_line - }; - - impl #impl_generics KvnDeserializer<#name> for #name #type_generics + impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #name #type_generics #where_clause { - fn deserialize<'a>(lines: &mut std::iter::Peekable>) - -> Result<#name, KvnDeserializerErr<&'a str>> { + fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) + -> Result<#name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { Ok(#name { #(#field_initializers)* From 87f304baaa9f8135cec8fcb73b4567ea71b64325 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 18:44:11 +0200 Subject: [PATCH 053/150] Use vec for OPM comment field --- crates/lox-utils/src/ndm/kvn/opm.rs | 96 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index bda47028..ce224b60 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -14,7 +14,7 @@ use super::parser::{KvnDateTimeValue, KvnNumericValue, KvnStringValue}; pub struct Opm { //@TODO the unit is always fixed and the same ccsds_opm_vers: KvnStringValue, - comment: KvnStringValue, + comment: Vec, creation_date: KvnDateTimeValue, originator: KvnStringValue, object_name: KvnStringValue, @@ -55,7 +55,7 @@ pub struct Opm { } mod test { - use crate::ndm::kvn::parser::KvnValue; + use crate::ndm::kvn::parser::{KvnDeserializer, KvnValue}; use super::*; @@ -117,8 +117,9 @@ mod test { MAN_DV_3 = 0.00000000 [km/s] */ - let kvn = r#"CCSDS_OPM_VERS = 3.0 + let kvn = r#" CCSDS_OPM_VERS = 3.0 COMMENT Generated by GSOC, R. Kiehling +COMMENT Current intermediate orbit IO2 and maneuver planning data CREATION_DATE = 2021-06-03T05:33:00.123 ORIGINATOR = GSOC OBJECT_NAME = EUTELSAT W4 @@ -167,12 +168,19 @@ MAN_DV_3 = 0.00000000 [km/s]"#; Ok(Opm { ccsds_opm_vers: KvnValue { value: "3.0".to_string(), - unit: None, - }, - comment: KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None, - }, + unit: None + }, + comment: vec![ + KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None + }, + KvnValue { + value: "Current intermediate orbit IO2 and maneuver planning data" + .to_string(), + unit: None + }, + ], creation_date: KvnDateTimeValue { year: 2021, month: 6, @@ -180,31 +188,31 @@ MAN_DV_3 = 0.00000000 [km/s]"#; hour: 5, minute: 33, second: 0, - fractional_second: 0.123, + fractional_second: 0.123 }, originator: KvnValue { value: "GSOC".to_string(), - unit: None, + unit: None }, object_name: KvnValue { value: "EUTELSAT W4".to_string(), - unit: None, + unit: None }, object_id: KvnValue { value: "2021-028A".to_string(), - unit: None, + unit: None }, center_name: KvnValue { value: "EARTH".to_string(), - unit: None, + unit: None }, ref_frame: KvnValue { value: "TOD".to_string(), - unit: None, + unit: None }, time_system: KvnValue { value: "UTC".to_string(), - unit: None, + unit: None }, epoch: KvnDateTimeValue { year: 2021, @@ -213,79 +221,79 @@ MAN_DV_3 = 0.00000000 [km/s]"#; hour: 0, minute: 0, second: 0, - fractional_second: 0.0, + fractional_second: 0.0 }, x: KvnValue { value: 6655.9942, - unit: Some("km".to_string(),), + unit: Some("km".to_string()) }, y: KvnValue { value: -40218.5751, - unit: Some("km".to_string(),), + unit: Some("km".to_string()) }, z: KvnValue { value: -82.9177, - unit: Some("km".to_string(),), + unit: Some("km".to_string()) }, x_dot: KvnValue { value: 3.11548208, - unit: Some("km/s".to_string(),), + unit: Some("km/s".to_string()) }, y_dot: KvnValue { value: 0.47042605, - unit: Some("km/s".to_string(),), + unit: Some("km/s".to_string()) }, z_dot: KvnValue { value: -0.00101495, - unit: Some("km/s".to_string(),), + unit: Some("km/s".to_string()) }, semi_major_axis: KvnValue { value: 41399.5123, - unit: Some("km".to_string(),), + unit: Some("km".to_string()) }, eccentricity: KvnValue { value: 0.020842611, - unit: None, + unit: None }, inclination: KvnValue { value: 0.117746, - unit: Some("deg".to_string(),), + unit: Some("deg".to_string()) }, ra_of_asc_node: KvnValue { value: 17.604721, - unit: Some("deg".to_string(),), + unit: Some("deg".to_string()) }, arg_of_pericenter: KvnValue { value: 218.242943, - unit: Some("deg".to_string(),), + unit: Some("deg".to_string()) }, true_anomaly: KvnValue { value: 41.922339, - unit: Some("deg".to_string(),), + unit: Some("deg".to_string()) }, gm: KvnValue { value: 398600.4415, - unit: Some("km**3/s**2".to_string(),), + unit: Some("km**3/s**2".to_string()) }, mass: KvnValue { value: 1913.0, - unit: Some("kg".to_string(),), + unit: Some("kg".to_string()) }, solar_rad_area: KvnValue { value: 10.0, - unit: Some("m**2".to_string(),), + unit: Some("m**2".to_string()) }, solar_rad_coeff: KvnValue { value: 1.3, - unit: None, + unit: None }, drag_area: KvnValue { value: 10.0, - unit: Some("m**2".to_string(),), + unit: Some("m**2".to_string()) }, drag_coeff: KvnValue { value: 2.3, - unit: None, + unit: None }, man_epoch_ignition: KvnDateTimeValue { year: 2021, @@ -294,33 +302,33 @@ MAN_DV_3 = 0.00000000 [km/s]"#; hour: 9, minute: 0, second: 34, - fractional_second: 0.10000000000000142, + fractional_second: 0.10000000000000142 }, man_duration: KvnValue { value: 132.6, - unit: Some("s".to_string(),), + unit: Some("s".to_string()) }, man_delta_mass: KvnValue { value: -18.418, - unit: Some("kg".to_string(),), + unit: Some("kg".to_string()) }, man_ref_frame: KvnValue { value: "EME2000".to_string(), - unit: None, + unit: None }, man_dv_1: KvnValue { value: -0.023257, - unit: Some("km/s".to_string(),), + unit: Some("km/s".to_string()) }, man_dv_2: KvnValue { value: 0.0168316, - unit: Some("km/s".to_string(),), + unit: Some("km/s".to_string()) }, man_dv_3: KvnValue { value: -0.00893444, - unit: Some("km/s".to_string(),), - }, - },) + unit: Some("km/s".to_string()) + } + }) ); } } From 36c4a3948ac6da8f5b5c00d99ff31630d9f7c884 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 21:51:58 +0200 Subject: [PATCH 054/150] Reorganize the tests a little bit --- crates/lox-utils/src/ndm/kvn/parser.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 3c6abcf3..ed45f53a 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -776,8 +776,8 @@ INTEGER_VALUE = 123 [km] OPTION_DATE_VALUE = 2021-06-03T05:33:00.123 CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 CHILD_NUMERIC_VALUE = 6655.9942 [km] -CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 -CHILD_NUMERIC_VALUE = 6655.9942 [km]"#; +CHILD_DATE_VALUE = 2021-02-03T05:33:00.123 +CHILD_NUMERIC_VALUE = 1122.9942 [km]"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), @@ -842,7 +842,7 @@ CHILD_NUMERIC_VALUE = 6655.9942 [km]"#; KvnChildStruct { child_date_value: KvnDateTimeValue { year: 2021, - month: 6, + month: 2, day: 3, hour: 5, minute: 33, @@ -850,7 +850,7 @@ CHILD_NUMERIC_VALUE = 6655.9942 [km]"#; fractional_second: 0.123, }, child_numeric_value: KvnValue { - value: 6655.9942, + value: 1122.9942, unit: Some("km".to_string(),), }, }, @@ -913,11 +913,14 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; vec_child_struct: vec![], },) ); + } + #[test] + fn test_parse_whole_struct_with_empty_vec_and_option() { let kvn = r#"STRING_VALUE = EUTELSAT W4 -DATE_VALUE = 2021-06-03T05:33:00.123 -NUMERIC_VALUE = 6655.9942 [km] -INTEGER_VALUE = 123 [km]"#; + DATE_VALUE = 2021-06-03T05:33:00.123 + NUMERIC_VALUE = 6655.9942 [km] + INTEGER_VALUE = 123 [km]"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), From 603c163caf3a24a855e5e98f0d485d7156770dfe Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 23:22:51 +0200 Subject: [PATCH 055/150] Add support for structs in options --- crates/lox-utils/src/ndm/kvn/parser.rs | 26 ++++++++++++++++++++++++++ crates/lox_derive/src/lib.rs | 5 ++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index ed45f53a..4f037e1d 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -753,11 +753,18 @@ mod test { child_numeric_value: KvnNumericValue, } + #[derive(KvnDeserialize, Default, Debug, PartialEq)] + pub struct KvnOptionChildStruct { + option_child_date_value: KvnDateTimeValue, + option_child_numeric_value: KvnNumericValue, + } + #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct KvnStruct { comment: Vec, string_value: KvnStringValue, date_value: KvnDateTimeValue, + option_child_struct: Option, numeric_value: KvnNumericValue, option_numeric_value: Option, integer_value: KvnIntegerValue, @@ -771,6 +778,8 @@ mod test { COMMENT asdsda a1 adsd STRING_VALUE = EUTELSAT W4 DATE_VALUE = 2021-06-03T05:33:00.123 +OPTION_CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 +OPTION_CHILD_NUMERIC_VALUE = 6655.9942 [km] NUMERIC_VALUE = 6655.9942 [km] INTEGER_VALUE = 123 [km] OPTION_DATE_VALUE = 2021-06-03T05:33:00.123 @@ -805,6 +814,21 @@ CHILD_NUMERIC_VALUE = 1122.9942 [km]"#; second: 0, fractional_second: 0.123, }, + option_child_struct: Some(KvnOptionChildStruct { + option_child_date_value: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + option_child_numeric_value: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + }), numeric_value: KvnValue { value: 6655.9942, unit: Some("km".to_string(),), @@ -892,6 +916,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; second: 0, fractional_second: 0.123, }, + option_child_struct: None, numeric_value: KvnValue { value: 6655.9942, unit: Some("km".to_string(),), @@ -939,6 +964,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; second: 0, fractional_second: 0.123, }, + option_child_struct: None, numeric_value: KvnValue { value: 6655.9942, unit: Some("km".to_string(),), diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 1152a244..95b0628a 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -171,9 +171,8 @@ fn generate_call_to_deserializer_for_vec_type( match result { Ok(item) => items.push(item), - Err( - crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword, - ) => break, + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) => break, Err(e) => Err(e)?, } } From a8c68123d4c9f3d33b2d4783b6835c6ddc3fbc5b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 23:53:50 +0200 Subject: [PATCH 056/150] Fix non-nested structs --- crates/lox_derive/src/lib.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 95b0628a..3f51e446 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -85,7 +85,7 @@ fn generate_call_to_deserializer_for_kvn_type( let result = if has_next_line { #type_ident::deserialize(lines) } else { - break; + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) }; result @@ -229,6 +229,8 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke // Unwrap is okay because we expect this span to come from the source code let field_type = field.ty.span().source_text().unwrap(); + let type_ident = syn::Ident::new(&field_type, Span::call_site()); + let parser = match field_type.as_str() { "KvnDateTimeValue" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" => { let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( @@ -245,12 +247,9 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke } "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, _ => { - return Err(syn::Error::new_spanned( - &field, - "unsupported field type for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into()); + quote! { + #type_ident::deserialize(lines)? + } } }; From 99d6316e7ec038b76590bf042720de393c2062aa Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 9 May 2024 23:54:14 +0200 Subject: [PATCH 057/150] Parse a complete OPM message --- crates/lox-utils/src/ndm/kvn/opm.rs | 520 ++++++++++++++-------------- 1 file changed, 259 insertions(+), 261 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index ce224b60..547091d4 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -11,47 +11,134 @@ use lox_derive::KvnDeserialize; use super::parser::{KvnDateTimeValue, KvnNumericValue, KvnStringValue}; #[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct Opm { - //@TODO the unit is always fixed and the same - ccsds_opm_vers: KvnStringValue, - comment: Vec, - creation_date: KvnDateTimeValue, - originator: KvnStringValue, - object_name: KvnStringValue, - object_id: KvnStringValue, - center_name: KvnStringValue, - ref_frame: KvnStringValue, - time_system: KvnStringValue, - // comment: KvnStringValue, - epoch: KvnDateTimeValue, - x: KvnNumericValue, - y: KvnNumericValue, - z: KvnNumericValue, - x_dot: KvnNumericValue, - y_dot: KvnNumericValue, - z_dot: KvnNumericValue, - // comment: KvnStringValue, - semi_major_axis: KvnNumericValue, - eccentricity: KvnNumericValue, //@TODO no unit - inclination: KvnNumericValue, - ra_of_asc_node: KvnNumericValue, - arg_of_pericenter: KvnNumericValue, - true_anomaly: KvnNumericValue, - gm: KvnNumericValue, - // comment: KvnStringValue, - mass: KvnNumericValue, - solar_rad_area: KvnNumericValue, - solar_rad_coeff: KvnNumericValue, - drag_area: KvnNumericValue, - drag_coeff: KvnNumericValue, //@TODO no unit - // comment: KvnStringValue, - man_epoch_ignition: KvnDateTimeValue, - man_duration: KvnNumericValue, - man_delta_mass: KvnNumericValue, - man_ref_frame: KvnStringValue, - man_dv_1: KvnNumericValue, - man_dv_2: KvnNumericValue, - man_dv_3: KvnNumericValue, +pub struct OdmHeader { + pub ccsds_opm_vers: KvnStringValue, + pub comment: Vec, + pub classification: Vec, + pub creation_date: KvnDateTimeValue, + pub originator: KvnStringValue, + pub message_id: Option, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmType { + pub header: OdmHeader, + pub body: OpmBody, + // pub id: KvnStringValue, Unexpected end of input? + // pub version: KvnStringValue, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmBody { + pub segment: OpmSegment, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmSegment { + pub metadata: OpmMetadata, + pub data: OpmData, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmMetadata { + pub comment_list: Vec, + pub object_name: KvnStringValue, + pub object_id: KvnStringValue, + pub center_name: KvnStringValue, + pub ref_frame: KvnStringValue, + pub ref_frame_epoch: Option, + pub time_system: KvnStringValue, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct StateVectorType { + pub comment_list: Vec, + pub epoch: KvnDateTimeValue, + pub x: KvnNumericValue, + pub y: KvnNumericValue, + pub z: KvnNumericValue, + pub x_dot: KvnNumericValue, + pub y_dot: KvnNumericValue, + pub z_dot: KvnNumericValue, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct SpacecraftParametersType { + pub comment_list: Vec, + pub mass: Option, + pub solar_rad_area: Option, + pub solar_rad_coeff: Option, //@TODO no unit + pub drag_area: Option, + pub drag_coeff: Option, //@TODO no unit +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmCovarianceMatrixType { + pub comment_list: Vec, + pub cov_ref_frame: Option, + pub cx_x: KvnNumericValue, + pub cy_x: KvnNumericValue, + pub cy_y: KvnNumericValue, + pub cz_x: KvnNumericValue, + pub cz_y: KvnNumericValue, + pub cz_z: KvnNumericValue, + pub cx_dot_x: KvnNumericValue, + pub cx_dot_y: KvnNumericValue, + pub cx_dot_z: KvnNumericValue, + pub cx_dot_x_dot: KvnNumericValue, + pub cy_dot_x: KvnNumericValue, + pub cy_dot_y: KvnNumericValue, + pub cy_dot_z: KvnNumericValue, + pub cy_dot_x_dot: KvnNumericValue, + pub cy_dot_y_dot: KvnNumericValue, + pub cz_dot_x: KvnNumericValue, + pub cz_dot_y: KvnNumericValue, + pub cz_dot_z: KvnNumericValue, + pub cz_dot_x_dot: KvnNumericValue, + pub cz_dot_y_dot: KvnNumericValue, + pub cz_dot_z_dot: KvnNumericValue, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct UserDefinedType { + pub comment: Vec, + pub user_defined: Vec, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct OpmData { + pub comment: Vec, + pub state_vector: StateVectorType, + pub keplerian_elements: Option, + pub spacecraft_parameters: Option, + pub covariance_matrix: Option, + pub maneuver_parameters_list: Vec, + pub user_defined_parameters: Option, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct KeplerianElementsType { + pub comment_list: Vec, + pub semi_major_axis: KvnNumericValue, + pub eccentricity: KvnNumericValue, // no unit + pub inclination: KvnNumericValue, + pub ra_of_asc_node: KvnNumericValue, + pub arg_of_pericenter: KvnNumericValue, + pub true_anomaly: Option, + pub mean_anomaly: Option, + pub gm: KvnNumericValue, +} + +#[derive(KvnDeserialize, Default, Debug, PartialEq)] +pub struct ManeuverParametersType { + pub comment_list: Vec, + pub man_epoch_ignition: KvnDateTimeValue, + pub man_duration: KvnNumericValue, + pub man_delta_mass: KvnNumericValue, + pub man_ref_frame: KvnStringValue, + pub man_dv_1: KvnNumericValue, + pub man_dv_2: KvnNumericValue, + pub man_dv_3: KvnNumericValue, } mod test { @@ -60,64 +147,8 @@ mod test { use super::*; #[test] - fn test_parse_json() { - /* - This is the original file with multi-line comments: - - CCSDS_OPM_VERS = 3.0 - COMMENT Generated by GSOC, R. Kiehling - COMMENT Current intermediate orbit IO2 and maneuver planning data - CREATION_DATE = 2021-06-03T05:33:00.123 - ORIGINATOR = GSOC - OBJECT_NAME = EUTELSAT W4 - OBJECT_ID = 2021-028A - CENTER_NAME = EARTH - REF_FRAME = TOD - TIME_SYSTEM = UTC - COMMENT State Vector - EPOCH = 2021-06-03T00:00:00.000 - X = 6655.9942 [km] - Y = -40218.5751 [km] - Z = -82.9177 [km] - X_DOT = 3.11548208 [km/s] - Y_DOT = 0.47042605 [km/s] - Z_DOT = -0.00101495 [km/s] - COMMENT Keplerian elements - SEMI_MAJOR_AXIS = 41399.5123 [km] - ECCENTRICITY = 0.020842611 - INCLINATION = 0.117746 [deg] - RA_OF_ASC_NODE = 17.604721 [deg] - ARG_OF_PERICENTER = 218.242943 [deg] - TRUE_ANOMALY = 41.922339 [deg] - GM = 398600.4415 [km**3/s**2] - COMMENT Spacecraft parameters - MASS = 1913.000 [kg] - SOLAR_RAD_AREA = 10.000 [m**2] - SOLAR_RAD_COEFF = 1.300 - DRAG_AREA = 10.000 [m**2] - DRAG_COEFF = 2.300 - COMMENT 2 planned maneuvers - COMMENT First maneuver: AMF-3 - COMMENT Non-impulsive, thrust direction fixed in inertial frame - MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 - MAN_DURATION = 132.60 [s] - MAN_DELTA_MASS = -18.418 [kg] - MAN_REF_FRAME = EME2000 - MAN_DV_1 = -0.02325700 [km/s] - MAN_DV_2 = 0.01683160 [km/s] - MAN_DV_3 = -0.00893444 [km/s] - COMMENT Second maneuver: first station acquisition maneuver - COMMENT impulsive, thrust direction fixed in RTN frame - MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 - MAN_DURATION = 0.00 [s] - MAN_DELTA_MASS = -1.469 [kg] - MAN_REF_FRAME = RTN - MAN_DV_1 = 0.00101500 [km/s] - MAN_DV_2 = -0.00187300 [km/s] - MAN_DV_3 = 0.00000000 [km/s] - */ - - let kvn = r#" CCSDS_OPM_VERS = 3.0 + fn test_parse_kvn() { + let kvn = r#"CCSDS_OPM_VERS = 3.0 COMMENT Generated by GSOC, R. Kiehling COMMENT Current intermediate orbit IO2 and maneuver planning data CREATION_DATE = 2021-06-03T05:33:00.123 @@ -127,6 +158,7 @@ OBJECT_ID = 2021-028A CENTER_NAME = EARTH REF_FRAME = TOD TIME_SYSTEM = UTC +COMMENT State Vector EPOCH = 2021-06-03T00:00:00.000 X = 6655.9942 [km] Y = -40218.5751 [km] @@ -134,6 +166,7 @@ Z = -82.9177 [km] X_DOT = 3.11548208 [km/s] Y_DOT = 0.47042605 [km/s] Z_DOT = -0.00101495 [km/s] +COMMENT Keplerian elements SEMI_MAJOR_AXIS = 41399.5123 [km] ECCENTRICITY = 0.020842611 INCLINATION = 0.117746 [deg] @@ -141,11 +174,15 @@ RA_OF_ASC_NODE = 17.604721 [deg] ARG_OF_PERICENTER = 218.242943 [deg] TRUE_ANOMALY = 41.922339 [deg] GM = 398600.4415 [km**3/s**2] +COMMENT Spacecraft parameters MASS = 1913.000 [kg] SOLAR_RAD_AREA = 10.000 [m**2] SOLAR_RAD_COEFF = 1.300 DRAG_AREA = 10.000 [m**2] DRAG_COEFF = 2.300 +COMMENT 2 planned maneuvers +COMMENT First maneuver: AMF-3 +COMMENT Non-impulsive, thrust direction fixed in inertial frame MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 MAN_DURATION = 132.60 [s] MAN_DELTA_MASS = -18.418 [kg] @@ -153,6 +190,8 @@ MAN_REF_FRAME = EME2000 MAN_DV_1 = -0.02325700 [km/s] MAN_DV_2 = 0.01683160 [km/s] MAN_DV_3 = -0.00893444 [km/s] +COMMENT Second maneuver: first station acquisition maneuver +COMMENT impulsive, thrust direction fixed in RTN frame MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 MAN_DURATION = 0.00 [s] MAN_DELTA_MASS = -1.469 [kg] @@ -161,174 +200,133 @@ MAN_DV_1 = 0.00101500 [km/s] MAN_DV_2 = -0.00187300 [km/s] MAN_DV_3 = 0.00000000 [km/s]"#; - let opm = Opm::deserialize(&mut kvn.lines().peekable()); + let opm = OpmType::deserialize(&mut kvn.lines().peekable()); + println!("{:#?}", opm); assert_eq!( opm, - Ok(Opm { - ccsds_opm_vers: KvnValue { - value: "3.0".to_string(), - unit: None - }, - comment: vec![ - KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None + Ok(OpmType { + header: OdmHeader { + ccsds_opm_vers: KvnValue { + value: "3.0".to_string(), + unit: None, }, - KvnValue { - value: "Current intermediate orbit IO2 and maneuver planning data" - .to_string(), - unit: None + comment: vec![ + KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), + unit: None, + }, + KvnValue { + value: "Current intermediate orbit IO2 and maneuver planning data" + .to_string(), + unit: None, + }, + ], + classification: vec![], + creation_date: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + originator: KvnValue { + value: "GSOC".to_string(), + unit: None, + }, + message_id: None, + }, + body: OpmBody { + segment: OpmSegment { + metadata: OpmMetadata { + comment_list: vec![], + object_name: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None, + }, + object_id: KvnValue { + value: "2021-028A".to_string(), + unit: None, + }, + center_name: KvnValue { + value: "EARTH".to_string(), + unit: None, + }, + ref_frame: KvnValue { + value: "TOD".to_string(), + unit: None, + }, + ref_frame_epoch: None, + time_system: KvnValue { + value: "UTC".to_string(), + unit: None, + }, + }, + data: OpmData { + comment: vec![KvnValue { + value: "State Vector".to_string(), + unit: None, + },], + state_vector: StateVectorType { + comment_list: vec![], + epoch: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 0, + minute: 0, + second: 0, + fractional_second: 0.0, + }, + x: KvnValue { + value: 6655.9942, + unit: Some("km".to_string(),), + }, + y: KvnValue { + value: -40218.5751, + unit: Some("km".to_string(),), + }, + z: KvnValue { + value: -82.9177, + unit: Some("km".to_string(),), + }, + x_dot: KvnValue { + value: 3.11548208, + unit: Some("km/s".to_string(),), + }, + y_dot: KvnValue { + value: 0.47042605, + unit: Some("km/s".to_string(),), + }, + z_dot: KvnValue { + value: -0.00101495, + unit: Some("km/s".to_string(),), + }, + }, + keplerian_elements: None, + spacecraft_parameters: Some(SpacecraftParametersType { + comment_list: vec![], + mass: None, + solar_rad_area: None, + solar_rad_coeff: None, + drag_area: None, + drag_coeff: None, + },), + covariance_matrix: None, + maneuver_parameters_list: vec![], + user_defined_parameters: Some(UserDefinedType { + comment: vec![KvnValue { + value: "Keplerian elements".to_string(), + unit: None, + },], + user_defined: vec![], + },), + }, }, - ], - creation_date: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123 - }, - originator: KvnValue { - value: "GSOC".to_string(), - unit: None - }, - object_name: KvnValue { - value: "EUTELSAT W4".to_string(), - unit: None - }, - object_id: KvnValue { - value: "2021-028A".to_string(), - unit: None - }, - center_name: KvnValue { - value: "EARTH".to_string(), - unit: None - }, - ref_frame: KvnValue { - value: "TOD".to_string(), - unit: None - }, - time_system: KvnValue { - value: "UTC".to_string(), - unit: None - }, - epoch: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 0, - minute: 0, - second: 0, - fractional_second: 0.0 - }, - x: KvnValue { - value: 6655.9942, - unit: Some("km".to_string()) - }, - y: KvnValue { - value: -40218.5751, - unit: Some("km".to_string()) - }, - z: KvnValue { - value: -82.9177, - unit: Some("km".to_string()) - }, - x_dot: KvnValue { - value: 3.11548208, - unit: Some("km/s".to_string()) - }, - y_dot: KvnValue { - value: 0.47042605, - unit: Some("km/s".to_string()) - }, - z_dot: KvnValue { - value: -0.00101495, - unit: Some("km/s".to_string()) - }, - semi_major_axis: KvnValue { - value: 41399.5123, - unit: Some("km".to_string()) - }, - eccentricity: KvnValue { - value: 0.020842611, - unit: None - }, - inclination: KvnValue { - value: 0.117746, - unit: Some("deg".to_string()) - }, - ra_of_asc_node: KvnValue { - value: 17.604721, - unit: Some("deg".to_string()) - }, - arg_of_pericenter: KvnValue { - value: 218.242943, - unit: Some("deg".to_string()) - }, - true_anomaly: KvnValue { - value: 41.922339, - unit: Some("deg".to_string()) - }, - gm: KvnValue { - value: 398600.4415, - unit: Some("km**3/s**2".to_string()) - }, - mass: KvnValue { - value: 1913.0, - unit: Some("kg".to_string()) - }, - solar_rad_area: KvnValue { - value: 10.0, - unit: Some("m**2".to_string()) - }, - solar_rad_coeff: KvnValue { - value: 1.3, - unit: None - }, - drag_area: KvnValue { - value: 10.0, - unit: Some("m**2".to_string()) - }, - drag_coeff: KvnValue { - value: 2.3, - unit: None - }, - man_epoch_ignition: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 9, - minute: 0, - second: 34, - fractional_second: 0.10000000000000142 - }, - man_duration: KvnValue { - value: 132.6, - unit: Some("s".to_string()) - }, - man_delta_mass: KvnValue { - value: -18.418, - unit: Some("kg".to_string()) - }, - man_ref_frame: KvnValue { - value: "EME2000".to_string(), - unit: None - }, - man_dv_1: KvnValue { - value: -0.023257, - unit: Some("km/s".to_string()) - }, - man_dv_2: KvnValue { - value: 0.0168316, - unit: Some("km/s".to_string()) }, - man_dv_3: KvnValue { - value: -0.00893444, - unit: Some("km/s".to_string()) - } - }) + },) ); } } From da9924a73770d5bb07f9dec646b47db8c0624b9c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 11 May 2024 15:52:21 +0200 Subject: [PATCH 058/150] Add support for _list suffix for vecs --- crates/lox-utils/src/ndm/kvn/parser.rs | 16 ++++++++-------- crates/lox_derive/src/lib.rs | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 4f037e1d..c84122a1 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -761,7 +761,7 @@ mod test { #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct KvnStruct { - comment: Vec, + comment_list: Vec, string_value: KvnStringValue, date_value: KvnDateTimeValue, option_child_struct: Option, @@ -769,7 +769,7 @@ mod test { option_numeric_value: Option, integer_value: KvnIntegerValue, option_date_value: Option, - vec_child_struct: Vec, + vec_child_struct_list: Vec, } #[test] @@ -791,7 +791,7 @@ CHILD_NUMERIC_VALUE = 1122.9942 [km]"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), Ok(KvnStruct { - comment: vec![ + comment_list: vec![ KvnValue { value: "Generated by GSOC, R. Kiehling".to_string(), unit: None, @@ -847,7 +847,7 @@ CHILD_NUMERIC_VALUE = 1122.9942 [km]"#; second: 0, fractional_second: 0.123, },), - vec_child_struct: vec![ + vec_child_struct_list: vec![ KvnChildStruct { child_date_value: KvnDateTimeValue { year: 2021, @@ -893,7 +893,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), Ok(KvnStruct { - comment: vec![ + comment_list: vec![ KvnValue { value: "Generated by GSOC, R. Kiehling".to_string(), unit: None, @@ -935,7 +935,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; second: 0, fractional_second: 0.123, },), - vec_child_struct: vec![], + vec_child_struct_list: vec![], },) ); } @@ -950,7 +950,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; assert_eq!( KvnStruct::deserialize(&mut kvn.lines().peekable()), Ok(KvnStruct { - comment: vec![], + comment_list: vec![], string_value: KvnValue { value: "EUTELSAT W4".to_string(), unit: None, @@ -975,7 +975,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; unit: Some("km".to_string(),), }, option_date_value: None, - vec_child_struct: vec![], + vec_child_struct_list: vec![], },) ); } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 3f51e446..77c05f6b 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -155,6 +155,8 @@ fn generate_call_to_deserializer_for_vec_type( .source_text() .unwrap(); + let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( &type_name.as_ref(), &expected_kvn_name, From b75c64a21ca758166a4eb4cc342b6e0e42e422d8 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 11 May 2024 15:52:55 +0200 Subject: [PATCH 059/150] Add _list suffix to opm vecs --- crates/lox-utils/src/ndm/kvn/opm.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index 547091d4..f2953750 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -13,8 +13,8 @@ use super::parser::{KvnDateTimeValue, KvnNumericValue, KvnStringValue}; #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct OdmHeader { pub ccsds_opm_vers: KvnStringValue, - pub comment: Vec, - pub classification: Vec, + pub comment_list: Vec, + pub classification_list: Vec, pub creation_date: KvnDateTimeValue, pub originator: KvnStringValue, pub message_id: Option, @@ -101,13 +101,13 @@ pub struct OpmCovarianceMatrixType { #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct UserDefinedType { - pub comment: Vec, - pub user_defined: Vec, + pub comment_list: Vec, + pub user_defined_list: Vec, } #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct OpmData { - pub comment: Vec, + pub comment_list: Vec, pub state_vector: StateVectorType, pub keplerian_elements: Option, pub spacecraft_parameters: Option, From 7b61b2c93c3ad395b870b740246aace7a3c38be5 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 11 May 2024 15:53:16 +0200 Subject: [PATCH 060/150] Update test expectation --- crates/lox-utils/src/ndm/kvn/opm.rs | 410 +++++++++++++++++++++------- 1 file changed, 305 insertions(+), 105 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs index f2953750..1677eda0 100644 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ b/crates/lox-utils/src/ndm/kvn/opm.rs @@ -202,131 +202,331 @@ MAN_DV_3 = 0.00000000 [km/s]"#; let opm = OpmType::deserialize(&mut kvn.lines().peekable()); - println!("{:#?}", opm); assert_eq!( opm, - Ok(OpmType { - header: OdmHeader { - ccsds_opm_vers: KvnValue { - value: "3.0".to_string(), - unit: None, - }, - comment: vec![ - KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None, - }, - KvnValue { - value: "Current intermediate orbit IO2 and maneuver planning data" - .to_string(), + Ok( + OpmType { + header: OdmHeader { + ccsds_opm_vers: KvnValue { + value: "3.0".to_string(), unit: None, }, - ], - classification: vec![], - creation_date: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - originator: KvnValue { - value: "GSOC".to_string(), - unit: None, - }, - message_id: None, - }, - body: OpmBody { - segment: OpmSegment { - metadata: OpmMetadata { - comment_list: vec![], - object_name: KvnValue { - value: "EUTELSAT W4".to_string(), + comment_list: vec![ + KvnValue { + value: "Generated by GSOC, R. Kiehling".to_string(), unit: None, }, - object_id: KvnValue { - value: "2021-028A".to_string(), - unit: None, - }, - center_name: KvnValue { - value: "EARTH".to_string(), - unit: None, - }, - ref_frame: KvnValue { - value: "TOD".to_string(), - unit: None, - }, - ref_frame_epoch: None, - time_system: KvnValue { - value: "UTC".to_string(), + KvnValue { + value: "Current intermediate orbit IO2 and maneuver planning data".to_string(), unit: None, }, + ], + classification_list: vec![], + creation_date: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, }, - data: OpmData { - comment: vec![KvnValue { - value: "State Vector".to_string(), - unit: None, - },], - state_vector: StateVectorType { + originator: KvnValue { + value: "GSOC".to_string(), + unit: None, + }, + message_id: None, + }, + body: OpmBody { + segment: OpmSegment { + metadata: OpmMetadata { comment_list: vec![], - epoch: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 0, - minute: 0, - second: 0, - fractional_second: 0.0, - }, - x: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), + object_name: KvnValue { + value: "EUTELSAT W4".to_string(), + unit: None, }, - y: KvnValue { - value: -40218.5751, - unit: Some("km".to_string(),), + object_id: KvnValue { + value: "2021-028A".to_string(), + unit: None, }, - z: KvnValue { - value: -82.9177, - unit: Some("km".to_string(),), + center_name: KvnValue { + value: "EARTH".to_string(), + unit: None, }, - x_dot: KvnValue { - value: 3.11548208, - unit: Some("km/s".to_string(),), + ref_frame: KvnValue { + value: "TOD".to_string(), + unit: None, }, - y_dot: KvnValue { - value: 0.47042605, - unit: Some("km/s".to_string(),), + ref_frame_epoch: None, + time_system: KvnValue { + value: "UTC".to_string(), + unit: None, }, - z_dot: KvnValue { - value: -0.00101495, - unit: Some("km/s".to_string(),), + }, + data: OpmData { + comment_list: vec![ + KvnValue { + value: "State Vector".to_string(), + unit: None, + }, + ], + state_vector: StateVectorType { + comment_list: vec![], + epoch: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 0, + minute: 0, + second: 0, + fractional_second: 0.0, + }, + x: KvnValue { + value: 6655.9942, + unit: Some( + "km".to_string(), + ), + }, + y: KvnValue { + value: -40218.5751, + unit: Some( + "km".to_string(), + ), + }, + z: KvnValue { + value: -82.9177, + unit: Some( + "km".to_string(), + ), + }, + x_dot: KvnValue { + value: 3.11548208, + unit: Some( + "km/s".to_string(), + ), + }, + y_dot: KvnValue { + value: 0.47042605, + unit: Some( + "km/s".to_string(), + ), + }, + z_dot: KvnValue { + value: -0.00101495, + unit: Some( + "km/s".to_string(), + ), + }, }, + keplerian_elements: Some( + KeplerianElementsType { + comment_list: vec![ + KvnValue { + value: "Keplerian elements".to_string(), + unit: None, + }, + ], + semi_major_axis: KvnValue { + value: 41399.5123, + unit: Some( + "km".to_string(), + ), + }, + eccentricity: KvnValue { + value: 0.020842611, + unit: None, + }, + inclination: KvnValue { + value: 0.117746, + unit: Some( + "deg".to_string(), + ), + }, + ra_of_asc_node: KvnValue { + value: 17.604721, + unit: Some( + "deg".to_string(), + ), + }, + arg_of_pericenter: KvnValue { + value: 218.242943, + unit: Some( + "deg".to_string(), + ), + }, + true_anomaly: Some( + KvnValue { + value: 41.922339, + unit: Some( + "deg".to_string(), + ), + }, + ), + mean_anomaly: None, + gm: KvnValue { + value: 398600.4415, + unit: Some( + "km**3/s**2".to_string(), + ), + }, + }, + ), + spacecraft_parameters: Some( + SpacecraftParametersType { + comment_list: vec![ + KvnValue { + value: "Spacecraft parameters".to_string(), + unit: None, + }, + ], + mass: Some( + KvnValue { + value: 1913.0, + unit: Some( + "kg".to_string(), + ), + }, + ), + solar_rad_area: Some( + KvnValue { + value: 10.0, + unit: Some( + "m**2".to_string(), + ), + }, + ), + solar_rad_coeff: Some( + KvnValue { + value: 1.3, + unit: None, + }, + ), + drag_area: Some( + KvnValue { + value: 10.0, + unit: Some( + "m**2".to_string(), + ), + }, + ), + drag_coeff: Some( + KvnValue { + value: 2.3, + unit: None, + }, + ), + }, + ), + covariance_matrix: None, + maneuver_parameters_list: vec![ + ManeuverParametersType { + comment_list: vec![], + man_epoch_ignition: KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 9, + minute: 0, + second: 34, + fractional_second: 0.10000000000000142, + }, + man_duration: KvnValue { + value: 132.6, + unit: Some( + "s".to_string(), + ), + }, + man_delta_mass: KvnValue { + value: -18.418, + unit: Some( + "kg".to_string(), + ), + }, + man_ref_frame: KvnValue { + value: "EME2000".to_string(), + unit: None, + }, + man_dv_1: KvnValue { + value: -0.023257, + unit: Some( + "km/s".to_string(), + ), + }, + man_dv_2: KvnValue { + value: 0.0168316, + unit: Some( + "km/s".to_string(), + ), + }, + man_dv_3: KvnValue { + value: -0.00893444, + unit: Some( + "km/s".to_string(), + ), + }, + }, + ManeuverParametersType { + comment_list: vec![ + KvnValue { + value: "Second maneuver: first station acquisition maneuver".to_string(), + unit: None, + }, + KvnValue { + value: "impulsive, thrust direction fixed in RTN frame".to_string(), + unit: None, + }, + ], + man_epoch_ignition: KvnDateTimeValue { + year: 2021, + month: 6, + day: 5, + hour: 18, + minute: 59, + second: 21, + fractional_second: 0.0, + }, + man_duration: KvnValue { + value: 0.0, + unit: Some( + "s".to_string(), + ), + }, + man_delta_mass: KvnValue { + value: -1.469, + unit: Some( + "kg".to_string(), + ), + }, + man_ref_frame: KvnValue { + value: "RTN".to_string(), + unit: None, + }, + man_dv_1: KvnValue { + value: 0.001015, + unit: Some( + "km/s".to_string(), + ), + }, + man_dv_2: KvnValue { + value: -0.001873, + unit: Some( + "km/s".to_string(), + ), + }, + man_dv_3: KvnValue { + value: 0.0, + unit: Some( + "km/s".to_string(), + ), + }, + }, + ], + user_defined_parameters: None, }, - keplerian_elements: None, - spacecraft_parameters: Some(SpacecraftParametersType { - comment_list: vec![], - mass: None, - solar_rad_area: None, - solar_rad_coeff: None, - drag_area: None, - drag_coeff: None, - },), - covariance_matrix: None, - maneuver_parameters_list: vec![], - user_defined_parameters: Some(UserDefinedType { - comment: vec![KvnValue { - value: "Keplerian elements".to_string(), - unit: None, - },], - user_defined: vec![], - },), }, }, }, - },) + ) ); } } From c7ed371a62db59ced044c862bd66eced996b2604 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Sat, 11 May 2024 15:53:43 +0200 Subject: [PATCH 061/150] Make error types more descriptive --- crates/lox-utils/src/ndm/kvn/parser.rs | 195 ++++++++++++++----------- crates/lox_derive/src/lib.rs | 21 ++- 2 files changed, 126 insertions(+), 90 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index c84122a1..68f84557 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -20,46 +20,48 @@ pub type KvnNumericValue = KvnValue; #[derive(Debug, PartialEq)] pub enum KvnParserErr { - KeywordNotFound, - EmptyValue, + KeywordNotFound { expected: I }, + EmptyValue { keyword: I }, ParserError(I, ErrorKind), } #[derive(PartialEq, Debug)] pub enum KvnNumberLineParserErr { ParserError(I, ErrorKind), - KeywordNotFound, - EmptyValue, - InvalidFormat, + KeywordNotFound { expected: I }, + EmptyValue { keyword: I }, + InvalidFormat { keyword: I }, } #[derive(PartialEq, Debug)] pub enum KvnDateTimeParserErr { ParserError(I, ErrorKind), - KeywordNotFound, - EmptyValue, - InvalidFormat, + KeywordNotFound { expected: I }, + EmptyValue { keyword: I }, + InvalidFormat { keyword: I }, } #[derive(PartialEq, Debug)] pub enum KvnDeserializerErr { - InvalidDateTimeFormat, - InvalidNumberFormat, - KeywordNotFound, - UnexpectedKeyword, - EmptyValue, - UnexpectedEndOfInput, + InvalidDateTimeFormat { keyword: I }, + InvalidNumberFormat { keyword: I }, + KeywordNotFound { expected: I }, + UnexpectedKeyword { found: I, expected: I }, + EmptyValue { keyword: I }, + UnexpectedEndOfInput { keyword: I }, GeneralParserError(I, ErrorKind), } impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnParserErr::EmptyValue) - | nom::Err::Failure(KvnParserErr::EmptyValue) => KvnDeserializerErr::EmptyValue, - nom::Err::Error(KvnParserErr::KeywordNotFound) - | nom::Err::Failure(KvnParserErr::KeywordNotFound) => { - KvnDeserializerErr::KeywordNotFound + nom::Err::Error(KvnParserErr::EmptyValue { keyword }) + | nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { + KvnDeserializerErr::EmptyValue { keyword } + } + nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) + | nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { + KvnDeserializerErr::KeywordNotFound { expected } } nom::Err::Error(KvnParserErr::ParserError(i, k)) | nom::Err::Failure(KvnParserErr::ParserError(i, k)) => { @@ -74,15 +76,17 @@ impl From>> for KvnDeserializerErr { impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnDateTimeParserErr::EmptyValue) - | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue) => KvnDeserializerErr::EmptyValue, - nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound) - | nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound) => { - KvnDeserializerErr::KeywordNotFound + nom::Err::Error(KvnDateTimeParserErr::EmptyValue { keyword }) + | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { keyword }) => { + KvnDeserializerErr::EmptyValue { keyword } + } + nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound { expected }) + | nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound { expected }) => { + KvnDeserializerErr::KeywordNotFound { expected } } - nom::Err::Error(KvnDateTimeParserErr::InvalidFormat) - | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat) => { - KvnDeserializerErr::InvalidDateTimeFormat + nom::Err::Error(KvnDateTimeParserErr::InvalidFormat { keyword }) + | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { keyword }) => { + KvnDeserializerErr::InvalidDateTimeFormat { keyword } } nom::Err::Error(KvnDateTimeParserErr::ParserError(i, k)) | nom::Err::Failure(KvnDateTimeParserErr::ParserError(i, k)) => { @@ -97,17 +101,17 @@ impl From>> for KvnDeserializerErr { impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue) - | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) => { - KvnDeserializerErr::EmptyValue + nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) + | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) => { + KvnDeserializerErr::EmptyValue { keyword } } - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) - | nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) => { - KvnDeserializerErr::KeywordNotFound + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) + | nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) => { + KvnDeserializerErr::KeywordNotFound { expected } } - nom::Err::Error(KvnNumberLineParserErr::InvalidFormat) - | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat) => { - KvnDeserializerErr::InvalidNumberFormat + nom::Err::Error(KvnNumberLineParserErr::InvalidFormat { keyword }) + | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword }) => { + KvnDeserializerErr::InvalidDateTimeFormat { keyword } } nom::Err::Error(KvnNumberLineParserErr::ParserError(i, k)) | nom::Err::Failure(KvnNumberLineParserErr::ParserError(i, k)) => { @@ -185,7 +189,11 @@ fn kvn_line<'a>( let mut equals = ns::tuple((nc::space0::<_, KvnParserErr<_>>, nc::char('='), nc::space0)); match equals(input) { - Ok(_) => return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound)), + Ok(_) => { + return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { + expected: key, + })) + } Err(_) => (), } @@ -233,7 +241,7 @@ pub fn parse_kvn_string_line<'a>( }; if parsed_value.len() == 0 { - return Err(nom::Err::Failure(KvnParserErr::EmptyValue)); + return Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: key })); } let parsed_value = parsed_value.trim_end(); @@ -254,11 +262,11 @@ pub fn parse_kvn_integer_line<'a>( ) -> nom::IResult<&'a str, KvnIntegerValue, KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue) => { - nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) + nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) } - nom::Err::Error(KvnParserErr::EmptyValue) => { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue) + nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) } nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) @@ -266,20 +274,18 @@ pub fn parse_kvn_integer_line<'a>( nom::Err::Error(KvnParserErr::ParserError(input, code)) => { nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) } - nom::Err::Failure(KvnParserErr::KeywordNotFound) => { - nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) + nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) } - nom::Err::Error(KvnParserErr::KeywordNotFound) => { - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) + nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) } nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), }) .and_then(|result| { - let value = result - .1 - .value - .parse::() - .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat))?; + let value = result.1.value.parse::().map_err(|_| { + nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: key }) + })?; Ok(( "", @@ -298,11 +304,11 @@ pub fn parse_kvn_numeric_line<'a>( ) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { parse_kvn_string_line(key, input, with_unit) .map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue) => { - nom::Err::Failure(KvnNumberLineParserErr::EmptyValue) + nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) } - nom::Err::Error(KvnParserErr::EmptyValue) => { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue) + nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) } nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) @@ -310,17 +316,18 @@ pub fn parse_kvn_numeric_line<'a>( nom::Err::Error(KvnParserErr::ParserError(input, code)) => { nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) } - nom::Err::Failure(KvnParserErr::KeywordNotFound) => { - nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound) + nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) } - nom::Err::Error(KvnParserErr::KeywordNotFound) => { - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound) + nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) } nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), }) .and_then(|result| { - let value = fast_float::parse(result.1.value) - .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat))?; + let value = fast_float::parse(result.1.value).map_err(|_| { + nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: key }) + })?; Ok(( "", @@ -337,11 +344,11 @@ pub fn parse_kvn_datetime_line<'a>( input: &'a str, ) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { let (_, result) = kvn_line(key, input).map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue) => { - nom::Err::Failure(KvnDateTimeParserErr::EmptyValue) + nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { keyword }) } - nom::Err::Error(KvnParserErr::EmptyValue) => { - nom::Err::Error(KvnDateTimeParserErr::EmptyValue) + nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { + nom::Err::Error(KvnDateTimeParserErr::EmptyValue { keyword }) } nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { nom::Err::Failure(KvnDateTimeParserErr::ParserError(input, code)) @@ -349,11 +356,11 @@ pub fn parse_kvn_datetime_line<'a>( nom::Err::Error(KvnParserErr::ParserError(input, code)) => { nom::Err::Error(KvnDateTimeParserErr::ParserError(input, code)) } - nom::Err::Failure(KvnParserErr::KeywordNotFound) => { - nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound) + nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound { expected }) } - nom::Err::Error(KvnParserErr::KeywordNotFound) => { - nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound) + nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { + nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound { expected }) } nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), })?; @@ -361,7 +368,9 @@ pub fn parse_kvn_datetime_line<'a>( let parsed_value = result.1; if parsed_value.len() == 0 { - return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue)); + return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + keyword: key, + })); } let parsed_value = parsed_value.trim_end(); @@ -373,9 +382,9 @@ pub fn parse_kvn_datetime_line<'a>( ) .unwrap(); - let captures = re - .captures(parsed_value) - .ok_or(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat))?; + let captures = re.captures(parsed_value).ok_or(nom::Err::Failure( + KvnDateTimeParserErr::InvalidFormat { keyword: key }, + ))?; // yr is a mandatory decimal in the regex so we expect the capture to be // always there and unwrap is fine @@ -481,15 +490,21 @@ mod test { ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) ); assert_eq!( parse_kvn_string_line("ASD", "ASD = ", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) ); assert_eq!( parse_kvn_string_line("ASD", "ASD =", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) ); // 7.4.7 Any white space immediately preceding the end of line shall not be significant. @@ -529,7 +544,9 @@ mod test { assert_eq!( parse_kvn_string_line("ASD", "ASD = [km]", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) ); assert_eq!( @@ -541,7 +558,9 @@ mod test { ); assert_eq!( parse_kvn_string_line("ASD", " = [km]", true), - Err(nom::Err::Failure(KvnParserErr::KeywordNotFound)) + Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { + expected: "ASD" + })) ); // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. @@ -650,12 +669,16 @@ mod test { assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat)) + Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + keyword: "SCLK_OFFSET_AT_EPOCH" + })) ); assert_eq!( parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { + keyword: "SCLK_OFFSET_AT_EPOCH" + })) ); } @@ -733,17 +756,23 @@ mod test { assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), - Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat)) + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + keyword: "CREATION_DATE" + })) ); assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), - Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat)) + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + keyword: "CREATION_DATE" + })) ); assert_eq!( parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), - Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue)) + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + keyword: "CREATION_DATE" + })) ); } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 77c05f6b..4a59971e 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -54,7 +54,9 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(quote! { match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput), + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }), Some(next_line) => { let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key( #expected_kvn_name, @@ -66,7 +68,10 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(#parser) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword) + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }) }; result @@ -85,7 +90,9 @@ fn generate_call_to_deserializer_for_kvn_type( let result = if has_next_line { #type_ident::deserialize(lines) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }) }; result @@ -122,8 +129,8 @@ fn generate_call_to_deserializer_for_option_type( match result { Ok(item) => Some(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) => None, + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, Err(e) => Err(e)?, } } @@ -173,8 +180,8 @@ fn generate_call_to_deserializer_for_vec_type( match result { Ok(item) => items.push(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput) => break, + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, Err(e) => Err(e)?, } } From 075e6731541146ff3635d8adff75cff9b5e8969d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 13 May 2024 23:50:11 +0200 Subject: [PATCH 062/150] Update syn crate --- crates/lox_derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox_derive/Cargo.toml b/crates/lox_derive/Cargo.toml index 2b68007f..e3caed5f 100644 --- a/crates/lox_derive/Cargo.toml +++ b/crates/lox_derive/Cargo.toml @@ -9,4 +9,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.81" quote = "1.0.20" -syn = "1.0.98" +syn = "2.0.63" From 1c97923fe24867d28684efaebddbee5331b34e18 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 21 May 2024 23:33:43 +0200 Subject: [PATCH 063/150] Implement struct deserialization --- crates/lox-utils/src/ndm/kvn/parser.rs | 569 ++++++++++++++++++++++++- crates/lox_derive/src/lib.rs | 277 ++++++++++-- 2 files changed, 802 insertions(+), 44 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 68f84557..4e63ae7f 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -25,6 +25,11 @@ pub enum KvnParserErr { ParserError(I, ErrorKind), } +#[derive(Debug, PartialEq)] +pub enum KvnKeyMatchErr { + KeywordNotFound { expected: I }, +} + #[derive(PartialEq, Debug)] pub enum KvnNumberLineParserErr { ParserError(I, ErrorKind), @@ -123,6 +128,16 @@ impl From>> for KvnDeserializerErr { } } +impl From> for KvnDeserializerErr { + fn from(value: KvnKeyMatchErr) -> Self { + match value { + KvnKeyMatchErr::KeywordNotFound { expected } => { + KvnDeserializerErr::KeywordNotFound { expected } + } + } + } +} + impl ParseError for KvnParserErr { fn from_error_kind(input: I, kind: ErrorKind) -> Self { KvnParserErr::ParserError(input, kind) @@ -182,6 +197,27 @@ pub fn kvn_line_matches_key<'a>(key: &'a str, input: &'a str) -> bool { } } +pub fn kvn_line_matches_key_new<'a>( + key: &'a str, + input: &'a str, +) -> Result> { + if key == "COMMENT" { + ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input) + .and_then(|_| Ok(true)) + .or_else(|_| Ok(false)) + } else { + let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); + + if equals(input).is_ok() { + return Err(KvnKeyMatchErr::KeywordNotFound { expected: key }); + } + + ns::delimited(nc::space0, nb::tag(key), equals)(input) + .and_then(|_| Ok(true)) + .or_else(|_| Ok(false)) + } +} + fn kvn_line<'a>( key: &'a str, input: &'a str, @@ -204,6 +240,28 @@ fn kvn_line<'a>( ns::delimited(nc::space0, kvn, nc::space0)(input) } +// fn kvn_line_new<'a>( +// input: &'a str, +// ) -> nom::IResult<&'a str, (&'a str, &'a str), KvnParserErr<&'a str>> { +// let mut equals = ns::tuple((nc::space0::<_, KvnParserErr<_>>, nc::char('='), nc::space0)); + +// match equals(input) { +// Ok(_) => { +// return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { +// //@TODO +// expected: "blalalal", +// })) +// } +// Err(_) => (), +// } + +// let value = nc::not_line_ending; + +// let kvn = ns::separated_pair(nb::tag(key), equals, value); + +// ns::delimited(nc::space0, kvn, nc::space0)(input) +// } + pub fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, @@ -255,6 +313,45 @@ pub fn parse_kvn_string_line<'a>( )) } +pub fn parse_kvn_string_line_new<'a>( + input: &'a str, +) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { + // if key == "COMMENT" { + // let (_, comment) = comment_line(input)?; + + // return Ok(( + // "", + // KvnValue { + // value: comment.to_owned(), + // unit: None, + // }, + // )); + // } + + // Figure F-8: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:[0-9A-Z_\.\- ]*)|(?:[0-9a-z_\.\- ]*)))(?:\s*)$").unwrap(); + + // @TODO unwrap + let captures = re.captures(input).unwrap(); + + // @TODO unwrap + let value = captures + .name("value") + .unwrap() + .as_str() + .trim_end() + .to_owned(); + + if value.len() == 0 { + //@TODO + return Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD", + })); + } + + Ok(("", KvnValue { value, unit: None })) +} + pub fn parse_kvn_integer_line<'a>( key: &'a str, input: &'a str, @@ -297,6 +394,52 @@ pub fn parse_kvn_integer_line<'a>( }) } +pub fn parse_kvn_integer_line_new<'a>( + input: &'a str, + with_unit: bool, +) -> nom::IResult<&'a str, KvnIntegerValue, KvnNumberLineParserErr<&'a str>> { + if is_empty_value(input) { + Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { + //@TODO + keyword: "SCLK_OFFSET_AT_EPOCH", + }))? + }; + + // Modified from Figure F-9: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$") + .unwrap(); + + // @TODO unwrap + let captures = + re.captures(input) + .ok_or(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + //@TODO + keyword: "SCLK_OFFSET_AT_EPOCH", + }))?; + + // @TODO unwrap + let value = captures.name("value").unwrap().as_str(); + let unit = captures.name("unit").map(|x| x.as_str().to_owned()); + + let value = value.parse::().map_err(|_| { + nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + //@TODO + keyword: "SCLK_OFFSET_AT_EPOCH", + }) + })?; + + Ok(("", KvnValue { value, unit })) +} + +fn is_empty_value(input: &str) -> bool { + let re = Regex::new( + r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?)?$", + ) + .unwrap(); + + re.is_match(input) +} + pub fn parse_kvn_numeric_line<'a>( key: &'a str, input: &'a str, @@ -339,6 +482,35 @@ pub fn parse_kvn_numeric_line<'a>( }) } +pub fn parse_kvn_numeric_line_new<'a>( + input: &'a str, + with_unit: bool, +) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { + if is_empty_value(input) { + Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { + //@TODO + keyword: "SCLK_OFFSET_AT_EPOCH", + }))? + }; + + // Figure F-9: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?(?:[eE][+-]?(?:\d+))?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$").unwrap(); + + // @TODO unwrap + let captures = re.captures(input).unwrap(); + + // @TODO unwrap + let value = captures.name("value").unwrap().as_str(); + let unit = captures.name("unit").map(|x| x.as_str().to_owned()); + + let value = fast_float::parse(value).map_err(|_| { + //@TODO + nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: "blalala" }) + })?; + + Ok(("", KvnValue { value, unit })) +} + pub fn parse_kvn_datetime_line<'a>( key: &'a str, input: &'a str, @@ -441,6 +613,81 @@ pub fn parse_kvn_datetime_line<'a>( )) } +pub fn parse_kvn_datetime_line_new<'a>( + input: &'a str, +) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { + if is_empty_value(input) { + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + //@TODO + keyword: "CREATION_DATE", + }))? + }; + + // Figure F-5: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)?(?[0-9A-Z_]*)(?:\s*)?=(?:\s*)?(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))(?:\s*)?$").unwrap(); + + let captures = + re.captures(input) + .ok_or(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + //@TODO + keyword: "CREATION_DATE", + }))?; + + // yr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let year = captures + .name("yr") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + // We don't do full validation of the date values. We only care if they + // have the expected number of digits + + // mo is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let month = captures.name("mo").unwrap().as_str().parse::().unwrap(); + + // day is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let day = captures.name("dy").unwrap().as_str().parse::().unwrap(); + + // hr is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let hour = captures.name("hr").unwrap().as_str().parse::().unwrap(); + + // mn is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let minute = captures.name("mn").unwrap().as_str().parse::().unwrap(); + + // sc is a mandatory decimal in the regex so we expect the capture to be + // always there and unwrap is fine + let full_second = captures + .name("sc") + .unwrap() + .as_str() + .parse::() + .unwrap(); + + let second = full_second.floor() as u8; + + let fractional_second = full_second.fract(); + + Ok(( + "", + KvnDateTimeValue { + year, + month, + day, + hour, + minute, + second, + fractional_second, + }, + )) +} + mod test { use lox_derive::KvnDeserialize; @@ -454,6 +701,26 @@ mod test { assert!(kvn_line_matches_key("ASD", "= ASDFG")); } + #[test] + fn test_kvn_line_matches_key_new() { + assert_eq!( + kvn_line_matches_key_new("ASD", "AAAAAD123 = ASDFG"), + Ok(false) + ); + assert_eq!(kvn_line_matches_key_new("ASD", "ASD = ASDFG"), Ok(true)); + + // 7.4.4 Keywords must be uppercase and must not contain blanks + // @TODO + assert_eq!( + kvn_line_matches_key_new("ASD", "ASD ASD = ASDFG"), + Ok(false) + ); + assert_eq!( + kvn_line_matches_key_new("ASD", "= ASDFG"), + Err(KvnKeyMatchErr::KeywordNotFound { expected: "ASD" }) + ); + } + #[test] fn test_parse_kvn_string_line() { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values @@ -599,10 +866,155 @@ mod test { } )) ); + } - // 7.4.4 Keywords must be uppercase and must not contain blanks - //@TODO parse dates and floats and integers - //@TODO return error code when the key doesn't exist + #[test] + fn test_parse_kvn_string_line_new() { + // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values + // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. + assert_eq!( + parse_kvn_string_line_new("ASD = ASDFG"), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line_new("ASD = ASDFG"), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line_new("ASD = ASDFG"), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + assert_eq!( + parse_kvn_string_line_new("ASD = "), + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) + ); + assert_eq!( + parse_kvn_string_line_new("ASD = "), + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) + ); + assert_eq!( + parse_kvn_string_line_new("ASD ="), + Err(nom::Err::Failure(KvnParserErr::EmptyValue { + keyword: "ASD" + })) + ); + + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + assert_eq!( + parse_kvn_string_line_new("ASD = ASDFG "), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + + //@TODO move to numeric test + // a) there must be at least one blank character between the value and the units text; + // b) the units must be enclosed within square brackets (e.g., ‘[m]’); + // assert_eq!( + // parse_kvn_string_line_new("ASD = ASDFG [km]"), + // Ok(( + // "", + // KvnValue { + // value: "ASDFG".to_string(), + // unit: Some("km".to_string()) + // } + // )) + // ); + // assert_eq!( + // parse_kvn_string_line_new("ASD = ASDFG [km]"), + // Ok(( + // "", + // KvnValue { + // value: "ASDFG".to_string(), + // unit: Some("km".to_string()) + // } + // )) + // ); + + // assert_eq!( + // parse_kvn_string_line_new("ASD = [km]"), + // Err(nom::Err::Failure(KvnParserErr::EmptyValue { + // keyword: "ASD" + // })) + // ); + + // assert_eq!( + // parse_kvn_string_line_new("ASD [km]"), + // Err(nom::Err::Error(KvnParserErr::ParserError( + // "[km]", + // nom::error::ErrorKind::Char + // ))) + // ); + // assert_eq!( + // parse_kvn_string_line_new(" = [km]"), + // Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { + // expected: "ASD" + // })) + // ); + + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + assert_eq!( + parse_kvn_string_line_new(" ASD = ASDFG"), + Ok(( + "", + KvnValue { + value: "ASDFG".to_string(), + unit: None + } + )) + ); + + //@TODO implement COMMENT + // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. + // [...] White space shall be retained (shall be significant) in comment values. + + // assert_eq!( + // parse_kvn_string_line_new(" COMMENT asd a asd a ads as "), + // Ok(( + // "", + // KvnValue { + // value: "asd a asd a ads as ".to_string(), + // unit: None + // } + // )) + // ); + + // assert_eq!( + // parse_kvn_string_line_new(" COMMENT "), + // Ok(( + // "", + // KvnValue { + // value: "".to_string(), + // unit: None + // } + // )) + // ); } #[test] @@ -682,6 +1094,67 @@ mod test { ); } + #[test] + fn test_parse_kvn_integer_line_new() { + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", true), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 00028800 [s]", true), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = -28800 [s]", true), + Ok(( + "", + KvnValue { + value: -28800, + unit: Some("s".to_string()) + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = -28800", true), + Ok(( + "", + KvnValue { + value: -28800, + unit: None + }, + )) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = -asd", true), + Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + keyword: "SCLK_OFFSET_AT_EPOCH" + })) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = [s]", true), + Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { + keyword: "SCLK_OFFSET_AT_EPOCH" + })) + ); + } + #[test] fn test_parse_kvn_numeric_line() { assert_eq!( @@ -776,6 +1249,64 @@ mod test { ); } + #[test] + fn test_parse_kvn_datetime_line_new() { + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = 2021-06-03T05:33:00.123"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 0, + fractional_second: 0.123, + }, + )) + ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = 2021-06-03T05:33:01"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 1, + fractional_second: 0.0, + }, + )) + ); + + // @TODO add support for ddd format + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = 2021,06,03Q05!33!00-123"), + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + keyword: "CREATION_DATE" + })) + ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = asdffggg"), + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + keyword: "CREATION_DATE" + })) + ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = "), + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + keyword: "CREATION_DATE" + })) + ); + } + #[derive(KvnDeserialize, Default, Debug, PartialEq)] pub struct KvnChildStruct { child_date_value: KvnDateTimeValue, @@ -1008,4 +1539,36 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; },) ); } + + //@TODO + // #[derive(KvnDeserialize, Default, Debug, PartialEq)] + // pub struct PositionUnits(pub std::string::String); + + #[derive(KvnDeserialize, Default, Debug, PartialEq)] + #[kvn(value_unit_struct)] + pub struct DistanceType { + pub base: f64, + // @TODO pub units: Option, + pub units: Option, + } + + #[derive(KvnDeserialize, Default, Debug, PartialEq)] + struct KvnWithUnitStruct { + semi_major_axis: DistanceType, + } + + #[test] + fn test_parse_with_unit_struct() { + let kvn = r#"SEMI_MAJOR_AXIS = 41399.5123 [km]"#; + + assert_eq!( + KvnWithUnitStruct::deserialize(&mut kvn.lines().peekable()), + Ok(KvnWithUnitStruct { + semi_major_axis: DistanceType { + base: 41399.5123, + units: Some("km".to_string(),), + }, + },) + ) + } } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 4a59971e..e4f56e43 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -8,7 +8,7 @@ use proc_macro2::Span; use quote::quote; -use syn::{spanned::Spanned, Field}; +use syn::{spanned::Spanned, DeriveInput, Field}; fn generate_call_to_deserializer_for_kvn_type( type_name: &str, @@ -102,6 +102,67 @@ fn generate_call_to_deserializer_for_kvn_type( } } +fn generate_call_to_deserializer_for_kvn_type_new( + type_name: &str, +) -> Result { + match type_name { + "KvnDateTimeValue" | "f64" | "String" | "i32" => { + let parser = match type_name { + "KvnDateTimeValue" => quote! { //@TODO + crate::ndm::kvn::parser::parse_kvn_datetime_line_new( + lines.next().unwrap(), + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "String" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "f64" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "i32" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(parser) + }, + type_value => { + let type_ident = syn::Ident::new(&type_value, Span::call_site()); + + Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_ident::deserialize(lines) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: "Blala" //@TODO + }) + }; + + result + } + }) + } + } +} + fn generate_call_to_deserializer_for_option_type( expected_kvn_name: &str, field: &Field, @@ -200,10 +261,33 @@ fn generate_call_to_deserializer_for_vec_type( ); } -#[proc_macro_derive(KvnDeserialize)] +fn is_value_unit_struct(item: &DeriveInput) -> bool { + for attr in item.attrs.iter() { + if attr.path().is_ident("kvn") { + if attr + .parse_nested_meta(|meta| { + if meta.path.is_ident("value_unit_struct") { + Ok(()) + } else { + Err(meta.error("unsupported attribute")) + } + }) + .is_ok() + { + return true; + } + } + } + + + false +} + +#[proc_macro_derive(KvnDeserialize, attributes(kvn))] pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { let item = syn::parse_macro_input!(item as syn::DeriveInput); let name = &item.ident; + let is_value_unit_struct = is_value_unit_struct(&item); let syn::Data::Struct(strukt) = item.data else { return syn::Error::new_spanned( @@ -226,53 +310,166 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke } }; - let field_initializers: Result, _> = fields - .iter() - .enumerate() - .map(|(_, field)| { - let field_name = field.ident.as_ref().unwrap(); + let deserializer = if is_value_unit_struct { + let mut deserializer = None; - // Unwrap is okay because we only support named structs - let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); + for (index, field) in fields.iter().enumerate() { + let field_name_ident = field.ident.as_ref().unwrap(); - // Unwrap is okay because we expect this span to come from the source code - let field_type = field.ty.span().source_text().unwrap(); + // Unwrap is okay because we only support named structs + let field_name = field_name_ident.span().source_text().unwrap(); + + match index { + 0 => { + if field_name.as_str() != "base" { + return syn::Error::new_spanned( + &field, + "The first field in a value unit struct should be called \"base\"", + ) + .into_compile_error() + .into() + } - let type_ident = syn::Ident::new(&field_type, Span::call_site()); + // Unwrap is okay because we expect this span to come from the source code + let field_type = field.ty.span().source_text().unwrap(); - let parser = match field_type.as_str() { - "KvnDateTimeValue" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" => { - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &field_type, - &expected_kvn_name, - )?; + + match field_type.as_str() { + "KvnDateTimeValue" | "String" | "f64" | "i32" => { + match generate_call_to_deserializer_for_kvn_type_new(&field_type) { + Ok(deserializer_for_kvn_type) => deserializer = Some(deserializer_for_kvn_type), + Err(e) => return e, + } + }, + + _ => return syn::Error::new_spanned( + &field, + "Unsupported field type for deserializer", + ) + .into_compile_error() + .into() + } + }, + 1 => if field_name.as_str() != "units" { + return syn::Error::new_spanned( + &field, + "The second field in a value unit struct should be called \"units\"", + ) + .into_compile_error() + .into() + }, + _ => return syn::Error::new_spanned( + &field, + "Only two fields \"base\" and \"units\" are called", + ) + .into_compile_error() + .into() + } - quote! { - #deserializer_for_kvn_type? + + } + + match deserializer { + None => return syn::Error::new_spanned( + &fields, + "Unable to create deserializer for struct", + ) + .into_compile_error() + .into(), + Some(deserializer) => quote! { + let kvn_value = #deserializer; + Ok(#name { + base: kvn_value.value, + units: kvn_value.unit, + }) + } + } + } else { + let field_initializers: Result, _> = fields + .iter() + .enumerate() + .map(|(_, field)| { + let field_name = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = field.ty.span().source_text().unwrap(); + + let type_ident = syn::Ident::new(&field_type, Span::call_site()); + + let parser = match field_type.as_str() { + "KvnDateTimeValue" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &field_type, + &expected_kvn_name, + )?; + + quote! { + #deserializer_for_kvn_type? + } } - } - "Option" => { - generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? - } - "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, - _ => { - quote! { - #type_ident::deserialize(lines)? + "Option" => { + generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? } - } - }; + "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, + _ => { + quote! { + { + match lines.peek() { + None => Err( + crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name, + }, + )?, + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + ); + + match line_matches { + Ok(true) => #type_ident::deserialize(lines), + Ok(false) => Err( + crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }, + ), + Err(crate::ndm::kvn::parser::KvnKeyMatchErr::KeywordNotFound { expected }) => Err( + crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::KeywordNotFound { + expected, + }, + ), + }? + } + } + } + } + } + }; - Ok(quote! { - #field_name: #parser, + Ok(quote! { + #field_name: #parser, + }) + }) + .collect(); + + if let Err(e) = field_initializers { + return e; + } + + let field_initializers = field_initializers.unwrap(); + + quote! { + Ok(#name { + #(#field_initializers)* }) - }) - .collect(); + } + }; - if let Err(e) = field_initializers { - return e; - } - let field_initializers = field_initializers.unwrap(); let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); @@ -283,9 +480,7 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) -> Result<#name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { - Ok(#name { - #(#field_initializers)* - }) + #deserializer } } }; From a9ca33be85aea8cb22795d4921fc205fc4ae08bb Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 21 May 2024 23:55:20 +0200 Subject: [PATCH 064/150] Implement support for tuple struct --- crates/lox-utils/src/ndm/kvn/parser.rs | 10 ++- crates/lox_derive/src/lib.rs | 94 +++++++++++++++----------- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 4e63ae7f..7e2d6ff5 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -1540,16 +1540,14 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; ); } - //@TODO - // #[derive(KvnDeserialize, Default, Debug, PartialEq)] - // pub struct PositionUnits(pub std::string::String); + #[derive(Default, Debug, PartialEq)] + pub struct PositionUnits(pub std::string::String); #[derive(KvnDeserialize, Default, Debug, PartialEq)] #[kvn(value_unit_struct)] pub struct DistanceType { pub base: f64, - // @TODO pub units: Option, - pub units: Option, + pub units: Option, } #[derive(KvnDeserialize, Default, Debug, PartialEq)] @@ -1566,7 +1564,7 @@ OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; Ok(KvnWithUnitStruct { semi_major_axis: DistanceType { base: 41399.5123, - units: Some("km".to_string(),), + units: Some(PositionUnits("km".to_string(),)), }, },) ) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index e4f56e43..67f878c5 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -163,48 +163,58 @@ fn generate_call_to_deserializer_for_kvn_type_new( } } -fn generate_call_to_deserializer_for_option_type( - expected_kvn_name: &str, - field: &Field, -) -> Result { +fn get_generic_type_argument(field: &Field) -> Option { if let syn::Type::Path(type_path) = &field.ty { let path_part = type_path.path.segments.first(); if let Some(path_part) = path_part { if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - let type_name = type_argument + return Some(type_argument .args .first() .unwrap() .span() .source_text() - .unwrap(); + .unwrap()); + } + } + } - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &expected_kvn_name, - )?; + None +} - return Ok(quote! { - { - let result = #deserializer_for_kvn_type; +fn generate_call_to_deserializer_for_option_type( + expected_kvn_name: &str, + field: &Field, +) -> Result { + let type_name = get_generic_type_argument(field); - match result { - Ok(item) => Some(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, - Err(e) => Err(e)?, - } + match type_name { + None => return Err( + syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + .into_compile_error() + .into(), + ), + + Some(type_name) => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &expected_kvn_name, + )?; + + return Ok(quote! { + { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => Some(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, + Err(e) => Err(e)?, } - }); - } + } + }); } } - - return Err( - syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") - .into_compile_error() - .into(), - ); } fn generate_call_to_deserializer_for_vec_type( @@ -312,6 +322,7 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let deserializer = if is_value_unit_struct { let mut deserializer = None; + let mut unit_type: Option = None; for (index, field) in fields.iter().enumerate() { let field_name_ident = field.ident.as_ref().unwrap(); @@ -350,13 +361,17 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke .into() } }, - 1 => if field_name.as_str() != "units" { - return syn::Error::new_spanned( - &field, - "The second field in a value unit struct should be called \"units\"", - ) - .into_compile_error() - .into() + 1 => { + if field_name.as_str() != "units" { + return syn::Error::new_spanned( + &field, + "The second field in a value unit struct should be called \"units\"", + ) + .into_compile_error() + .into() + } + + unit_type = get_generic_type_argument(field); }, _ => return syn::Error::new_spanned( &field, @@ -364,10 +379,13 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke ) .into_compile_error() .into() - } - - + } } + + // This unwrap is okay because we know the field exists. If it didn't exist we would've thrown an error. + let unit_type = unit_type.unwrap(); + + let unit_type_ident = syn::Ident::new(&unit_type, Span::call_site()); match deserializer { None => return syn::Error::new_spanned( @@ -380,7 +398,7 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let kvn_value = #deserializer; Ok(#name { base: kvn_value.value, - units: kvn_value.unit, + units: kvn_value.unit.map(|unit| #unit_type_ident (unit)), }) } } From 73a97c849490c511a72739c2dd5bf52d05fd95ec Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:01:26 +0200 Subject: [PATCH 065/150] Clean-up string type Parsing multi-segment type paths with syn in proc macros is annoying. So this simplifies everything a little bit --- crates/lox-utils/src/ndm/common.rs | 116 ++++++++++++++--------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/crates/lox-utils/src/ndm/common.rs b/crates/lox-utils/src/ndm/common.rs index 3aa1997b..69b41adc 100644 --- a/crates/lox-utils/src/ndm/common.rs +++ b/crates/lox-utils/src/ndm/common.rs @@ -10,11 +10,11 @@ use serde; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AccUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AccUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -22,11 +22,11 @@ pub struct AngleRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngMomentumUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngMomentumUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -34,19 +34,19 @@ pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AreaUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AreaUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DayIntervalUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct FrequencyUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GmUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct GmUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -54,47 +54,47 @@ pub struct InclinationRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LengthUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct LengthUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MassUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct MassUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MomentUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct MomentUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct WkgUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct WkgUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub std::string::String); +pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Ms2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Ms2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2sUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2sUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2s2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2s2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct VelocityUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq)] pub struct VecDouble { @@ -115,15 +115,15 @@ pub struct Vec9Double(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct EpochType(#[serde(rename = "$text")] pub std::string::String); +pub struct EpochType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct TimeUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeSystemType(#[serde(rename = "$text")] pub std::string::String); +pub struct TimeSystemType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -135,11 +135,11 @@ pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NonPositiveDouble(#[serde(rename = "$text")] pub std::string::String); +pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentType(#[serde(rename = "$text")] pub std::string::String); +pub struct PercentType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -147,139 +147,139 @@ pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Range100Type(#[serde(rename = "$text")] pub std::string::String); +pub struct Range100Type(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ProbabilityType(#[serde(rename = "$text")] pub std::string::String); +pub struct ProbabilityType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentageUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PercentageUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct YesNoType(#[serde(rename = "$text")] pub std::string::String); +pub struct YesNoType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TrajBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct TrajBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RevNumBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct RevNumBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct CovBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct ManBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManDcType(#[serde(rename = "$text")] pub std::string::String); +pub struct ManDcType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NumPerYearUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct NumPerYearUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ThrustUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct ThrustUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovOrderType(#[serde(rename = "$text")] pub std::string::String); +pub struct CovOrderType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GeomagUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct GeomagUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct SolarFluxUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct SolarFluxUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub std::string::String); +pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatRange(#[serde(rename = "$text")] pub std::string::String); +pub struct LatRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AltRange(#[serde(rename = "$text")] pub std::string::String); +pub struct AltRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LonRange(#[serde(rename = "$text")] pub std::string::String); +pub struct LonRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatLonUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct LatLonUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ControlledType(#[serde(rename = "$text")] pub std::string::String); +pub struct ControlledType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DisintegrationType(#[serde(rename = "$text")] pub std::string::String); +pub struct DisintegrationType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub std::string::String); +pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub std::string::String); +pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionComponentType(#[serde(rename = "$text")] pub std::string::String); +pub struct QuaternionComponentType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotDirectionType(#[serde(rename = "$text")] pub std::string::String); +pub struct RotDirectionType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotseqType(#[serde(rename = "$text")] pub std::string::String); +pub struct RotseqType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleKeywordType(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleKeywordType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ApmRateFrameType(#[serde(rename = "$text")] pub std::string::String); +pub struct ApmRateFrameType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TorqueUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct TorqueUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] From 31e98011645f6aa271466614401ed1f3d7dfd5d2 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:05:53 +0200 Subject: [PATCH 066/150] Simplify the wrapped types It complicates the kvn value unit struct deserialization uncessesarily. --- crates/lox-utils/src/ndm/common.rs | 8 --- crates/lox-utils/src/ndm/ndm.rs | 48 +++++++++--------- crates/lox-utils/src/ndm/omm.rs | 81 ++++++++---------------------- crates/lox-utils/src/ndm/opm.rs | 8 +-- 4 files changed, 49 insertions(+), 96 deletions(-) diff --git a/crates/lox-utils/src/ndm/common.rs b/crates/lox-utils/src/ndm/common.rs index 69b41adc..c5964782 100644 --- a/crates/lox-utils/src/ndm/common.rs +++ b/crates/lox-utils/src/ndm/common.rs @@ -16,10 +16,6 @@ pub struct AccUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct AngleUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleRange(#[serde(rename = "$text")] pub f64); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); @@ -48,10 +44,6 @@ pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct GmUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct InclinationRange(#[serde(rename = "$text")] pub f64); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct LengthUnits(#[serde(rename = "$text")] pub String); diff --git a/crates/lox-utils/src/ndm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs index d92dfa43..af02052c 100644 --- a/crates/lox-utils/src/ndm/ndm.rs +++ b/crates/lox-utils/src/ndm/ndm.rs @@ -403,19 +403,19 @@ mod test { mean_motion: None, eccentricity: common::NonNegativeDouble(0.0), inclination: common::InclinationType { - base: common::InclinationRange(0.0), + base: 0.0, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, gm: None, @@ -464,19 +464,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.001178), inclination: common::InclinationType { - base: common::InclinationRange(97.409), + base: 97.409, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(71.7453), + base: 71.7453, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(193.9419), + base: 193.9419, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(272.1492), + base: 272.1492, units: None, }, gm: None, @@ -571,19 +571,19 @@ mod test { }, eccentricity: common::NonNegativeDouble(0.0,), inclination: common::InclinationType { - base: common::InclinationRange(45.0,), + base: 45.0, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(0.0,), + base: 0.0, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(15.0,), + base: 15.0, units: Some(common::AngleUnits("deg".to_string(),),), }, true_anomaly: Some(common::AngleType { - base: common::AngleRange(15.0,), + base: 15.0, units: Some(common::AngleUnits("deg".to_string(),),), },), mean_anomaly: None, @@ -928,19 +928,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009574), inclination: common::InclinationType { - base: common::InclinationRange(97.2663), + base: 97.2663, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.2167), + base: 51.2167, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(149.8567), + base: 149.8567, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(322.5146), + base: 322.5146, units: None, }, gm: None, @@ -1012,19 +1012,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009674), inclination: common::InclinationType { - base: common::InclinationRange(97.2671), + base: 97.2671, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.3486), + base: 51.3486, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(160.8608), + base: 160.8608, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(302.2789), + base: 302.2789, units: None, }, gm: None, @@ -1096,19 +1096,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009024), inclination: common::InclinationType { - base: common::InclinationRange(97.2666), + base: 97.2666, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.2301), + base: 51.2301, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(167.2057), + base: 167.2057, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(304.5569), + base: 304.5569, units: None, }, gm: None, diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs index 39201ac2..e5fbd1c1 100644 --- a/crates/lox-utils/src/ndm/omm.rs +++ b/crates/lox-utils/src/ndm/omm.rs @@ -326,27 +326,19 @@ mod test { 0.0005013, ), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), + base: 3.0539, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), + base: 81.7939, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), + base: 249.2363, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), + base: 150.1602, units: None, }, gm: Some( @@ -540,27 +532,20 @@ mod test { 0.0205751, ), inclination: common::InclinationType { - base: common::InclinationRange( - 49.8237, - ), + base: 49.8237, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 93.8140, - ), + base: 93.8140, + units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 224.8348, - ), + base: 224.8348, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 133.5761, - ), + base: 133.5761, units: None, }, gm: None, @@ -735,27 +720,19 @@ mod test { 0.0005013, ), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), + base: 3.0539, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), + base: 81.7939, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), + base: 249.2363, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), + base: 150.1602, units: None, }, gm: Some( @@ -1033,9 +1010,7 @@ mod test { 0.0005013, ), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), + base: 3.0539, units: Some( common::AngleUnits( "deg".to_string(), @@ -1043,9 +1018,7 @@ mod test { ), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), + base: 81.7939, units: Some( common::AngleUnits( "deg".to_string(), @@ -1053,9 +1026,7 @@ mod test { ), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), + base: 249.2363, units: Some( common::AngleUnits( "deg".to_string(), @@ -1063,9 +1034,7 @@ mod test { ), }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), + base: 150.1602, units: Some( common::AngleUnits( "deg".to_string(), @@ -1331,9 +1300,7 @@ mod test { 0.0006703, ), inclination: common::InclinationType { - base: common::InclinationRange( - 51.6416, - ), + base: 51.6416, units: Some( common::AngleUnits( "deg".to_string(), @@ -1341,9 +1308,7 @@ mod test { ), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 247.4627, - ), + base: 247.4627, units: Some( common::AngleUnits( "deg".to_string(), @@ -1351,9 +1316,7 @@ mod test { ), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 130.536, - ), + base: 130.536, units: Some( common::AngleUnits( "deg".to_string(), @@ -1361,9 +1324,7 @@ mod test { ), }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 325.0288, - ), + base: 325.0288, units: Some( common::AngleUnits( "deg".to_string(), diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index ac217baf..5e572c49 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -289,19 +289,19 @@ mod test { }, eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { - base: common::InclinationRange(51.6416,), + base: 51.6416, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(247.463,), + base: 247.463, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(130.536,), + base: 130.536, units: Some(common::AngleUnits("deg".to_string(),),), }, true_anomaly: Some(common::AngleType { - base: common::AngleRange(324.985,), + base: 324.985, units: Some(common::AngleUnits("deg".to_string(),),), },), mean_anomaly: None, From 44a86343a96735a044be9ac29cb584bc31553e1e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:07:31 +0200 Subject: [PATCH 067/150] Make the XML metadata optional This is so we can re-use the XML types for KVN deserialization --- crates/lox-utils/src/ndm/ndm.rs | 8 ++++---- crates/lox-utils/src/ndm/opm.rs | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/lox-utils/src/ndm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs index af02052c..38fe336b 100644 --- a/crates/lox-utils/src/ndm/ndm.rs +++ b/crates/lox-utils/src/ndm/ndm.rs @@ -641,8 +641,8 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), - version: "2.0".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), + version: Some("2.0".to_string()), },), NdmChildChoice::Opm(opm::OpmType { header: common::OdmHeader { @@ -743,8 +743,8 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), - version: "2.0".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), + version: Some("2.0".to_string()), },), NdmChildChoice::Oem(oem::OemType { header: common::OdmHeader { diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index 5e572c49..3dfa0583 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -18,9 +18,11 @@ pub struct OpmType { #[serde(rename = "body")] pub body: OpmBody, #[serde(rename = "@id")] - pub id: String, + // Marked as option for the KVN deserializer + pub id: Option, #[serde(rename = "@version")] - pub version: String, + // Marked as option for the KVN deserializer + pub version: Option, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] @@ -475,8 +477,8 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), - version: "3.0".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), + version: Some("3.0".to_string()), } ); } From 5dad8104762ea12907cb2cadeaf72d91a7335b20 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:13:47 +0200 Subject: [PATCH 068/150] Remove leftover println --- crates/lox-utils/src/ndm/opm.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index 3dfa0583..e16855a1 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -228,8 +228,6 @@ mod test { let message: OpmType = from_str(xml).unwrap(); - println!("{:#?}", message); - assert_eq!( message, OpmType { From bda9175211c85d258f27b06e106a11c5268f6ec2 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:14:48 +0200 Subject: [PATCH 069/150] Remove commented out parser --- crates/lox-utils/src/ndm/kvn/parser.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 7e2d6ff5..86184b7d 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -240,28 +240,6 @@ fn kvn_line<'a>( ns::delimited(nc::space0, kvn, nc::space0)(input) } -// fn kvn_line_new<'a>( -// input: &'a str, -// ) -> nom::IResult<&'a str, (&'a str, &'a str), KvnParserErr<&'a str>> { -// let mut equals = ns::tuple((nc::space0::<_, KvnParserErr<_>>, nc::char('='), nc::space0)); - -// match equals(input) { -// Ok(_) => { -// return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { -// //@TODO -// expected: "blalalal", -// })) -// } -// Err(_) => (), -// } - -// let value = nc::not_line_ending; - -// let kvn = ns::separated_pair(nb::tag(key), equals, value); - -// ns::delimited(nc::space0, kvn, nc::space0)(input) -// } - pub fn parse_kvn_string_line<'a>( key: &'a str, input: &'a str, From 16b52be79bc45d38b5f469796c273916d0b880ff Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:18:21 +0200 Subject: [PATCH 070/150] Enable returning full string value for datetime --- crates/lox-utils/src/ndm/kvn/parser.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 86184b7d..910671a0 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -163,6 +163,7 @@ pub struct KvnDateTimeValue { pub minute: u8, pub second: u8, pub fractional_second: f64, + pub full_value: String, } pub trait KvnDeserializer { @@ -525,12 +526,9 @@ pub fn parse_kvn_datetime_line<'a>( let parsed_value = parsed_value.trim_end(); - // Taken from CCSDS 502.0-B-3 Figure F-5: Regex Pattern for CCSDS Timecode // This unwrap is okay here because this regex never changes after testing - let re = Regex::new( - r"^(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))$", - ) - .unwrap(); + // Modified from Figure F-5: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)?(?[0-9A-Z_]*)(?:\s*)?=(?:\s*)?(?(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?)))(?:\s*)?$").unwrap(); let captures = re.captures(parsed_value).ok_or(nom::Err::Failure( KvnDateTimeParserErr::InvalidFormat { keyword: key }, @@ -577,6 +575,8 @@ pub fn parse_kvn_datetime_line<'a>( let fractional_second = full_second.fract(); + let full_value = captures.name("value").unwrap().as_str().to_owned(); + Ok(( "", KvnDateTimeValue { @@ -587,6 +587,7 @@ pub fn parse_kvn_datetime_line<'a>( minute, second, fractional_second, + full_value, }, )) } @@ -601,8 +602,8 @@ pub fn parse_kvn_datetime_line_new<'a>( }))? }; - // Figure F-5: CCSDS 502.0-B-3 - let re = Regex::new(r"^(?:\s*)?(?[0-9A-Z_]*)(?:\s*)?=(?:\s*)?(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?))(?:\s*)?$").unwrap(); + // Modified from Figure F-5: CCSDS 502.0-B-3 + let re = Regex::new(r"^(?:\s*)?(?[0-9A-Z_]*)(?:\s*)?=(?:\s*)?(?(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?)))(?:\s*)?$").unwrap(); let captures = re.captures(input) @@ -652,6 +653,8 @@ pub fn parse_kvn_datetime_line_new<'a>( let fractional_second = full_second.fract(); + let full_value = captures.name("value").unwrap().as_str().to_owned(); + Ok(( "", KvnDateTimeValue { @@ -662,6 +665,7 @@ pub fn parse_kvn_datetime_line_new<'a>( minute, second, fractional_second, + full_value, }, )) } @@ -1183,6 +1187,7 @@ mod test { minute: 33, second: 0, fractional_second: 0.123, + full_value: "2021-06-03T05:33:00.123".to_string(), }, )) ); @@ -1199,6 +1204,7 @@ mod test { minute: 33, second: 1, fractional_second: 0.0, + full_value: "2021-06-03T05:33:01".to_string() }, )) ); @@ -1241,6 +1247,7 @@ mod test { minute: 33, second: 0, fractional_second: 0.123, + full_value: "2021-06-03T05:33:00.123".to_string(), }, )) ); @@ -1257,6 +1264,7 @@ mod test { minute: 33, second: 1, fractional_second: 0.0, + full_value: "2021-06-03T05:33:01".to_string(), }, )) ); From 164233d0640ccfec75bf2e96286cca78124d919d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:21:30 +0200 Subject: [PATCH 071/150] Implement relaxed parsing of strings This would allow re-use of this method for some functions like EpochType --- crates/lox-utils/src/ndm/kvn/parser.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 910671a0..312efcc9 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -294,6 +294,7 @@ pub fn parse_kvn_string_line<'a>( pub fn parse_kvn_string_line_new<'a>( input: &'a str, + relaxed: bool, ) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { // if key == "COMMENT" { // let (_, comment) = comment_line(input)?; @@ -308,7 +309,12 @@ pub fn parse_kvn_string_line_new<'a>( // } // Figure F-8: CCSDS 502.0-B-3 - let re = Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:[0-9A-Z_\.\- ]*)|(?:[0-9a-z_\.\- ]*)))(?:\s*)$").unwrap(); + let re = if relaxed { + Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:.*)))(?:\s*)$") + .unwrap() + } else { + Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:[0-9A-Z_\.\- ]*)|(?:[0-9a-z_\.\- ]*)))(?:\s*)$").unwrap() + }; // @TODO unwrap let captures = re.captures(input).unwrap(); @@ -855,7 +861,7 @@ mod test { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG"), + parse_kvn_string_line_new("ASD = ASDFG", false), Ok(( "", KvnValue { @@ -865,7 +871,7 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG"), + parse_kvn_string_line_new("ASD = ASDFG", false), Ok(( "", KvnValue { @@ -875,7 +881,7 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG"), + parse_kvn_string_line_new("ASD = ASDFG", false), Ok(( "", KvnValue { @@ -885,19 +891,19 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = "), + parse_kvn_string_line_new("ASD = ", false), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) ); assert_eq!( - parse_kvn_string_line_new("ASD = "), + parse_kvn_string_line_new("ASD = ", false), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) ); assert_eq!( - parse_kvn_string_line_new("ASD ="), + parse_kvn_string_line_new("ASD =", false), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) @@ -905,7 +911,7 @@ mod test { // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG "), + parse_kvn_string_line_new("ASD = ASDFG ", false), Ok(( "", KvnValue { @@ -962,7 +968,7 @@ mod test { // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. assert_eq!( - parse_kvn_string_line_new(" ASD = ASDFG"), + parse_kvn_string_line_new(" ASD = ASDFG", false), Ok(( "", KvnValue { From 01f3de93e45482d7b4f8ef43253331dc4955287f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:23:06 +0200 Subject: [PATCH 072/150] Remote test for old-style parsing --- crates/lox-utils/src/ndm/kvn/parser.rs | 395 ------------------------- 1 file changed, 395 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 312efcc9..e72599a2 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -496,108 +496,6 @@ pub fn parse_kvn_numeric_line_new<'a>( Ok(("", KvnValue { value, unit })) } -pub fn parse_kvn_datetime_line<'a>( - key: &'a str, - input: &'a str, -) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { - let (_, result) = kvn_line(key, input).map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { keyword }) - } - nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Error(KvnDateTimeParserErr::EmptyValue { keyword }) - } - nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { - nom::Err::Failure(KvnDateTimeParserErr::ParserError(input, code)) - } - nom::Err::Error(KvnParserErr::ParserError(input, code)) => { - nom::Err::Error(KvnDateTimeParserErr::ParserError(input, code)) - } - nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound { expected }) - } - nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound { expected }) - } - nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), - })?; - - let parsed_value = result.1; - - if parsed_value.len() == 0 { - return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { - keyword: key, - })); - } - - let parsed_value = parsed_value.trim_end(); - - // This unwrap is okay here because this regex never changes after testing - // Modified from Figure F-5: CCSDS 502.0-B-3 - let re = Regex::new(r"^(?:\s*)?(?[0-9A-Z_]*)(?:\s*)?=(?:\s*)?(?(?(?:\d{4}))-(?(?:\d{1,2}))-(?(?:\d{1,2}))T(?
(?:\d{1,2})):(?(?:\d{1,2})):(?(?:\d{0,2}(?:\.\d*)?)))(?:\s*)?$").unwrap(); - - let captures = re.captures(parsed_value).ok_or(nom::Err::Failure( - KvnDateTimeParserErr::InvalidFormat { keyword: key }, - ))?; - - // yr is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let year = captures - .name("yr") - .unwrap() - .as_str() - .parse::() - .unwrap(); - - // We don't do full validation of the date values. We only care if they - // have the expected number of digits - - // mo is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let month = captures.name("mo").unwrap().as_str().parse::().unwrap(); - - // day is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let day = captures.name("dy").unwrap().as_str().parse::().unwrap(); - - // hr is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let hour = captures.name("hr").unwrap().as_str().parse::().unwrap(); - - // mn is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let minute = captures.name("mn").unwrap().as_str().parse::().unwrap(); - - // sc is a mandatory decimal in the regex so we expect the capture to be - // always there and unwrap is fine - let full_second = captures - .name("sc") - .unwrap() - .as_str() - .parse::() - .unwrap(); - - let second = full_second.floor() as u8; - - let fractional_second = full_second.fract(); - - let full_value = captures.name("value").unwrap().as_str().to_owned(); - - Ok(( - "", - KvnDateTimeValue { - year, - month, - day, - hour, - minute, - second, - fractional_second, - full_value, - }, - )) -} - pub fn parse_kvn_datetime_line_new<'a>( input: &'a str, ) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { @@ -1179,66 +1077,6 @@ mod test { ); } - #[test] - fn test_parse_kvn_datetime_line() { - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:00.123"), - Ok(( - "", - KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - full_value: "2021-06-03T05:33:00.123".to_string(), - }, - )) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021-06-03T05:33:01"), - Ok(( - "", - KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 1, - fractional_second: 0.0, - full_value: "2021-06-03T05:33:01".to_string() - }, - )) - ); - - // @TODO add support for ddd format - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = 2021,06,03Q05!33!00-123"), - Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { - keyword: "CREATION_DATE" - })) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = asdffggg"), - Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { - keyword: "CREATION_DATE" - })) - ); - - assert_eq!( - parse_kvn_datetime_line("CREATION_DATE", "CREATION_DATE = "), - Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { - keyword: "CREATION_DATE" - })) - ); - } - #[test] fn test_parse_kvn_datetime_line_new() { assert_eq!( @@ -1299,239 +1137,6 @@ mod test { ); } - #[derive(KvnDeserialize, Default, Debug, PartialEq)] - pub struct KvnChildStruct { - child_date_value: KvnDateTimeValue, - child_numeric_value: KvnNumericValue, - } - - #[derive(KvnDeserialize, Default, Debug, PartialEq)] - pub struct KvnOptionChildStruct { - option_child_date_value: KvnDateTimeValue, - option_child_numeric_value: KvnNumericValue, - } - - #[derive(KvnDeserialize, Default, Debug, PartialEq)] - pub struct KvnStruct { - comment_list: Vec, - string_value: KvnStringValue, - date_value: KvnDateTimeValue, - option_child_struct: Option, - numeric_value: KvnNumericValue, - option_numeric_value: Option, - integer_value: KvnIntegerValue, - option_date_value: Option, - vec_child_struct_list: Vec, - } - - #[test] - fn test_parse_whole_struct() { - let kvn = r#"COMMENT Generated by GSOC, R. Kiehling -COMMENT asdsda a1 adsd -STRING_VALUE = EUTELSAT W4 -DATE_VALUE = 2021-06-03T05:33:00.123 -OPTION_CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 -OPTION_CHILD_NUMERIC_VALUE = 6655.9942 [km] -NUMERIC_VALUE = 6655.9942 [km] -INTEGER_VALUE = 123 [km] -OPTION_DATE_VALUE = 2021-06-03T05:33:00.123 -CHILD_DATE_VALUE = 2021-06-03T05:33:00.123 -CHILD_NUMERIC_VALUE = 6655.9942 [km] -CHILD_DATE_VALUE = 2021-02-03T05:33:00.123 -CHILD_NUMERIC_VALUE = 1122.9942 [km]"#; - - assert_eq!( - KvnStruct::deserialize(&mut kvn.lines().peekable()), - Ok(KvnStruct { - comment_list: vec![ - KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None, - }, - KvnValue { - value: "asdsda a1 adsd".to_string(), - unit: None, - }, - ], - string_value: KvnValue { - value: "EUTELSAT W4".to_string(), - unit: None, - }, - date_value: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - option_child_struct: Some(KvnOptionChildStruct { - option_child_date_value: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - option_child_numeric_value: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), - }, - }), - numeric_value: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), - }, - option_numeric_value: None, - integer_value: KvnValue { - value: 123, - unit: Some("km".to_string(),), - }, - option_date_value: Some(KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - },), - vec_child_struct_list: vec![ - KvnChildStruct { - child_date_value: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - child_numeric_value: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), - }, - }, - KvnChildStruct { - child_date_value: KvnDateTimeValue { - year: 2021, - month: 2, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - child_numeric_value: KvnValue { - value: 1122.9942, - unit: Some("km".to_string(),), - }, - }, - ], - },) - ); - - let kvn = r#"COMMENT Generated by GSOC, R. Kiehling -COMMENT asdsda a1 adsd -STRING_VALUE = EUTELSAT W4 -DATE_VALUE = 2021-06-03T05:33:00.123 -NUMERIC_VALUE = 6655.9942 [km] -INTEGER_VALUE = 123 [km] -OPTION_DATE_VALUE = 2021-06-03T05:33:00.123"#; - - assert_eq!( - KvnStruct::deserialize(&mut kvn.lines().peekable()), - Ok(KvnStruct { - comment_list: vec![ - KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None, - }, - KvnValue { - value: "asdsda a1 adsd".to_string(), - unit: None, - }, - ], - string_value: KvnValue { - value: "EUTELSAT W4".to_string(), - unit: None, - }, - date_value: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - option_child_struct: None, - numeric_value: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), - }, - option_numeric_value: None, - integer_value: KvnValue { - value: 123, - unit: Some("km".to_string(),), - }, - option_date_value: Some(KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - },), - vec_child_struct_list: vec![], - },) - ); - } - - #[test] - fn test_parse_whole_struct_with_empty_vec_and_option() { - let kvn = r#"STRING_VALUE = EUTELSAT W4 - DATE_VALUE = 2021-06-03T05:33:00.123 - NUMERIC_VALUE = 6655.9942 [km] - INTEGER_VALUE = 123 [km]"#; - - assert_eq!( - KvnStruct::deserialize(&mut kvn.lines().peekable()), - Ok(KvnStruct { - comment_list: vec![], - string_value: KvnValue { - value: "EUTELSAT W4".to_string(), - unit: None, - }, - date_value: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - option_child_struct: None, - numeric_value: KvnValue { - value: 6655.9942, - unit: Some("km".to_string(),), - }, - option_numeric_value: None, - integer_value: KvnValue { - value: 123, - unit: Some("km".to_string(),), - }, - option_date_value: None, - vec_child_struct_list: vec![], - },) - ); - } - #[derive(Default, Debug, PartialEq)] pub struct PositionUnits(pub std::string::String); From 612b131810c3008e91e08044c9835014cf14ff0d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:25:37 +0200 Subject: [PATCH 073/150] Enable KVN deserializer on OPM structs --- crates/lox-utils/src/ndm/common.rs | 318 ++++++++++++++++++++++++++--- crates/lox-utils/src/ndm/opm.rs | 301 ++++++++++++++++++++++++++- 2 files changed, 578 insertions(+), 41 deletions(-) diff --git a/crates/lox-utils/src/ndm/common.rs b/crates/lox-utils/src/ndm/common.rs index c5964782..7380daf8 100644 --- a/crates/lox-utils/src/ndm/common.rs +++ b/crates/lox-utils/src/ndm/common.rs @@ -105,7 +105,15 @@ pub struct Vec6Double(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct Vec9Double(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct EpochType(#[serde(rename = "$text")] pub String); @@ -121,7 +129,15 @@ pub struct TimeSystemType(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); @@ -297,7 +313,15 @@ pub struct AdmHeader { pub message_id: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OdmHeader { #[serde(rename = "COMMENT")] @@ -312,8 +336,17 @@ pub struct OdmHeader { pub message_id: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AccType { #[serde(rename = "$text")] pub base: f64, @@ -321,17 +354,35 @@ pub struct AccType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngleType { #[serde(rename = "$text")] - pub base: AngleRange, + pub base: f64, #[serde(rename = "@units")] pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngleRateType { #[serde(rename = "$text")] pub base: f64, @@ -348,8 +399,17 @@ pub struct AngMomentumType { pub units: AngMomentumUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngVelComponentType { #[serde(rename = "$text")] pub base: f64, @@ -376,7 +436,15 @@ pub struct AngVelStateType { pub angvel_z: AngVelComponentType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct AngVelType { #[serde(rename = "ANGVEL_X")] @@ -387,8 +455,17 @@ pub struct AngVelType { pub angvel_z: AngVelComponentType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AreaType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -414,8 +491,17 @@ pub struct OcmDayIntervalType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DeltamassType { #[serde(rename = "$text")] pub base: NegativeDouble, @@ -441,8 +527,17 @@ pub struct FrequencyType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct GmType { #[serde(rename = "$text")] pub base: PositiveDouble, @@ -450,11 +545,20 @@ pub struct GmType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct InclinationType { #[serde(rename = "$text")] - pub base: InclinationRange, + pub base: f64, #[serde(rename = "@units")] pub units: Option, } @@ -477,8 +581,17 @@ pub struct OcmLengthType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct MassType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -486,8 +599,17 @@ pub struct MassType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct MomentType { #[serde(rename = "$text")] pub base: f64, @@ -531,7 +653,15 @@ pub struct OdParametersType { pub weighted_rms: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SpacecraftParametersType { #[serde(rename = "COMMENT")] @@ -548,7 +678,15 @@ pub struct SpacecraftParametersType { pub drag_coeff: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct StateVectorType { #[serde(rename = "COMMENT")] @@ -603,8 +741,17 @@ pub struct Ms2Type { pub units: Ms2Units, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2Type { #[serde(rename = "$text")] pub base: f64, @@ -612,8 +759,17 @@ pub struct Km2Type { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2sType { #[serde(rename = "$text")] pub base: f64, @@ -621,8 +777,17 @@ pub struct Km2sType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2s2Type { #[serde(rename = "$text")] pub base: f64, @@ -630,8 +795,17 @@ pub struct Km2s2Type { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DistanceType { #[serde(rename = "$text")] pub base: f64, @@ -639,8 +813,17 @@ pub struct DistanceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionType { #[serde(rename = "$text")] pub base: f64, @@ -655,8 +838,17 @@ pub struct RdmPositionType { pub base: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct VelocityType { #[serde(rename = "$text")] pub base: f64, @@ -671,8 +863,17 @@ pub struct RdmVelocityType { pub base: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DurationType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -796,7 +997,15 @@ pub struct OemCovarianceMatrixType { pub cz_dot_z_dot: VelocityCovarianceType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmCovarianceMatrixType { #[serde(rename = "COMMENT")] @@ -847,8 +1056,17 @@ pub struct OpmCovarianceMatrixType { pub cz_dot_z_dot: VelocityCovarianceType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -856,8 +1074,17 @@ pub struct PositionCovarianceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct VelocityCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -865,8 +1092,17 @@ pub struct VelocityCovarianceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionVelocityCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -1027,7 +1263,15 @@ pub struct LonType { pub units: LatLonUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct UserDefinedType { #[serde(rename = "COMMENT")] @@ -1036,7 +1280,15 @@ pub struct UserDefinedType { pub user_defined_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct UserDefinedParameterType { #[serde(rename = "$text")] @@ -1081,14 +1333,14 @@ pub struct RotationAngleComponentTypeold { #[serde(rename = "@angle")] pub angle: AngleKeywordType, #[serde(rename = "@value")] - pub value: AngleRange, + pub value: f64, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct RotationAngleComponentType { #[serde(rename = "$text")] - pub base: AngleRange, + pub base: f64, #[serde(rename = "@angle")] pub angle: AngleKeywordType, #[serde(rename = "@units")] diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index e16855a1..3fb2c11c 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -10,7 +10,15 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmType { #[serde(rename = "header")] @@ -25,14 +33,30 @@ pub struct OpmType { pub version: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmBody { #[serde(rename = "segment")] pub segment: OpmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmSegment { #[serde(rename = "metadata")] @@ -41,7 +65,15 @@ pub struct OpmSegment { pub data: OpmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmMetadata { #[serde(rename = "COMMENT")] @@ -60,7 +92,15 @@ pub struct OpmMetadata { pub time_system: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmData { #[serde(rename = "COMMENT")] @@ -79,7 +119,15 @@ pub struct OpmData { pub user_defined_parameters: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct KeplerianElementsType { #[serde(rename = "COMMENT")] @@ -102,7 +150,15 @@ pub struct KeplerianElementsType { pub gm: common::GmType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManeuverParametersType { #[serde(rename = "COMMENT")] @@ -129,7 +185,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_opm_message() { + fn test_parse_opm_message_xml() { let xml = r#" Date: Tue, 28 May 2024 23:26:18 +0200 Subject: [PATCH 074/150] Remove old OPM parser --- crates/lox-utils/src/ndm/kvn.rs | 1 - crates/lox-utils/src/ndm/kvn/opm.rs | 532 ---------------------------- 2 files changed, 533 deletions(-) delete mode 100644 crates/lox-utils/src/ndm/kvn/opm.rs diff --git a/crates/lox-utils/src/ndm/kvn.rs b/crates/lox-utils/src/ndm/kvn.rs index dbd9a0e6..67c567fa 100644 --- a/crates/lox-utils/src/ndm/kvn.rs +++ b/crates/lox-utils/src/ndm/kvn.rs @@ -1,2 +1 @@ -pub mod opm; pub mod parser; diff --git a/crates/lox-utils/src/ndm/kvn/opm.rs b/crates/lox-utils/src/ndm/kvn/opm.rs deleted file mode 100644 index 1677eda0..00000000 --- a/crates/lox-utils/src/ndm/kvn/opm.rs +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use lox_derive::KvnDeserialize; - -use super::parser::{KvnDateTimeValue, KvnNumericValue, KvnStringValue}; - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OdmHeader { - pub ccsds_opm_vers: KvnStringValue, - pub comment_list: Vec, - pub classification_list: Vec, - pub creation_date: KvnDateTimeValue, - pub originator: KvnStringValue, - pub message_id: Option, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmType { - pub header: OdmHeader, - pub body: OpmBody, - // pub id: KvnStringValue, Unexpected end of input? - // pub version: KvnStringValue, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmBody { - pub segment: OpmSegment, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmSegment { - pub metadata: OpmMetadata, - pub data: OpmData, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmMetadata { - pub comment_list: Vec, - pub object_name: KvnStringValue, - pub object_id: KvnStringValue, - pub center_name: KvnStringValue, - pub ref_frame: KvnStringValue, - pub ref_frame_epoch: Option, - pub time_system: KvnStringValue, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct StateVectorType { - pub comment_list: Vec, - pub epoch: KvnDateTimeValue, - pub x: KvnNumericValue, - pub y: KvnNumericValue, - pub z: KvnNumericValue, - pub x_dot: KvnNumericValue, - pub y_dot: KvnNumericValue, - pub z_dot: KvnNumericValue, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct SpacecraftParametersType { - pub comment_list: Vec, - pub mass: Option, - pub solar_rad_area: Option, - pub solar_rad_coeff: Option, //@TODO no unit - pub drag_area: Option, - pub drag_coeff: Option, //@TODO no unit -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmCovarianceMatrixType { - pub comment_list: Vec, - pub cov_ref_frame: Option, - pub cx_x: KvnNumericValue, - pub cy_x: KvnNumericValue, - pub cy_y: KvnNumericValue, - pub cz_x: KvnNumericValue, - pub cz_y: KvnNumericValue, - pub cz_z: KvnNumericValue, - pub cx_dot_x: KvnNumericValue, - pub cx_dot_y: KvnNumericValue, - pub cx_dot_z: KvnNumericValue, - pub cx_dot_x_dot: KvnNumericValue, - pub cy_dot_x: KvnNumericValue, - pub cy_dot_y: KvnNumericValue, - pub cy_dot_z: KvnNumericValue, - pub cy_dot_x_dot: KvnNumericValue, - pub cy_dot_y_dot: KvnNumericValue, - pub cz_dot_x: KvnNumericValue, - pub cz_dot_y: KvnNumericValue, - pub cz_dot_z: KvnNumericValue, - pub cz_dot_x_dot: KvnNumericValue, - pub cz_dot_y_dot: KvnNumericValue, - pub cz_dot_z_dot: KvnNumericValue, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct UserDefinedType { - pub comment_list: Vec, - pub user_defined_list: Vec, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct OpmData { - pub comment_list: Vec, - pub state_vector: StateVectorType, - pub keplerian_elements: Option, - pub spacecraft_parameters: Option, - pub covariance_matrix: Option, - pub maneuver_parameters_list: Vec, - pub user_defined_parameters: Option, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct KeplerianElementsType { - pub comment_list: Vec, - pub semi_major_axis: KvnNumericValue, - pub eccentricity: KvnNumericValue, // no unit - pub inclination: KvnNumericValue, - pub ra_of_asc_node: KvnNumericValue, - pub arg_of_pericenter: KvnNumericValue, - pub true_anomaly: Option, - pub mean_anomaly: Option, - pub gm: KvnNumericValue, -} - -#[derive(KvnDeserialize, Default, Debug, PartialEq)] -pub struct ManeuverParametersType { - pub comment_list: Vec, - pub man_epoch_ignition: KvnDateTimeValue, - pub man_duration: KvnNumericValue, - pub man_delta_mass: KvnNumericValue, - pub man_ref_frame: KvnStringValue, - pub man_dv_1: KvnNumericValue, - pub man_dv_2: KvnNumericValue, - pub man_dv_3: KvnNumericValue, -} - -mod test { - use crate::ndm::kvn::parser::{KvnDeserializer, KvnValue}; - - use super::*; - - #[test] - fn test_parse_kvn() { - let kvn = r#"CCSDS_OPM_VERS = 3.0 -COMMENT Generated by GSOC, R. Kiehling -COMMENT Current intermediate orbit IO2 and maneuver planning data -CREATION_DATE = 2021-06-03T05:33:00.123 -ORIGINATOR = GSOC -OBJECT_NAME = EUTELSAT W4 -OBJECT_ID = 2021-028A -CENTER_NAME = EARTH -REF_FRAME = TOD -TIME_SYSTEM = UTC -COMMENT State Vector -EPOCH = 2021-06-03T00:00:00.000 -X = 6655.9942 [km] -Y = -40218.5751 [km] -Z = -82.9177 [km] -X_DOT = 3.11548208 [km/s] -Y_DOT = 0.47042605 [km/s] -Z_DOT = -0.00101495 [km/s] -COMMENT Keplerian elements -SEMI_MAJOR_AXIS = 41399.5123 [km] -ECCENTRICITY = 0.020842611 -INCLINATION = 0.117746 [deg] -RA_OF_ASC_NODE = 17.604721 [deg] -ARG_OF_PERICENTER = 218.242943 [deg] -TRUE_ANOMALY = 41.922339 [deg] -GM = 398600.4415 [km**3/s**2] -COMMENT Spacecraft parameters -MASS = 1913.000 [kg] -SOLAR_RAD_AREA = 10.000 [m**2] -SOLAR_RAD_COEFF = 1.300 -DRAG_AREA = 10.000 [m**2] -DRAG_COEFF = 2.300 -COMMENT 2 planned maneuvers -COMMENT First maneuver: AMF-3 -COMMENT Non-impulsive, thrust direction fixed in inertial frame -MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 -MAN_DURATION = 132.60 [s] -MAN_DELTA_MASS = -18.418 [kg] -MAN_REF_FRAME = EME2000 -MAN_DV_1 = -0.02325700 [km/s] -MAN_DV_2 = 0.01683160 [km/s] -MAN_DV_3 = -0.00893444 [km/s] -COMMENT Second maneuver: first station acquisition maneuver -COMMENT impulsive, thrust direction fixed in RTN frame -MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 -MAN_DURATION = 0.00 [s] -MAN_DELTA_MASS = -1.469 [kg] -MAN_REF_FRAME = RTN -MAN_DV_1 = 0.00101500 [km/s] -MAN_DV_2 = -0.00187300 [km/s] -MAN_DV_3 = 0.00000000 [km/s]"#; - - let opm = OpmType::deserialize(&mut kvn.lines().peekable()); - - assert_eq!( - opm, - Ok( - OpmType { - header: OdmHeader { - ccsds_opm_vers: KvnValue { - value: "3.0".to_string(), - unit: None, - }, - comment_list: vec![ - KvnValue { - value: "Generated by GSOC, R. Kiehling".to_string(), - unit: None, - }, - KvnValue { - value: "Current intermediate orbit IO2 and maneuver planning data".to_string(), - unit: None, - }, - ], - classification_list: vec![], - creation_date: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 5, - minute: 33, - second: 0, - fractional_second: 0.123, - }, - originator: KvnValue { - value: "GSOC".to_string(), - unit: None, - }, - message_id: None, - }, - body: OpmBody { - segment: OpmSegment { - metadata: OpmMetadata { - comment_list: vec![], - object_name: KvnValue { - value: "EUTELSAT W4".to_string(), - unit: None, - }, - object_id: KvnValue { - value: "2021-028A".to_string(), - unit: None, - }, - center_name: KvnValue { - value: "EARTH".to_string(), - unit: None, - }, - ref_frame: KvnValue { - value: "TOD".to_string(), - unit: None, - }, - ref_frame_epoch: None, - time_system: KvnValue { - value: "UTC".to_string(), - unit: None, - }, - }, - data: OpmData { - comment_list: vec![ - KvnValue { - value: "State Vector".to_string(), - unit: None, - }, - ], - state_vector: StateVectorType { - comment_list: vec![], - epoch: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 0, - minute: 0, - second: 0, - fractional_second: 0.0, - }, - x: KvnValue { - value: 6655.9942, - unit: Some( - "km".to_string(), - ), - }, - y: KvnValue { - value: -40218.5751, - unit: Some( - "km".to_string(), - ), - }, - z: KvnValue { - value: -82.9177, - unit: Some( - "km".to_string(), - ), - }, - x_dot: KvnValue { - value: 3.11548208, - unit: Some( - "km/s".to_string(), - ), - }, - y_dot: KvnValue { - value: 0.47042605, - unit: Some( - "km/s".to_string(), - ), - }, - z_dot: KvnValue { - value: -0.00101495, - unit: Some( - "km/s".to_string(), - ), - }, - }, - keplerian_elements: Some( - KeplerianElementsType { - comment_list: vec![ - KvnValue { - value: "Keplerian elements".to_string(), - unit: None, - }, - ], - semi_major_axis: KvnValue { - value: 41399.5123, - unit: Some( - "km".to_string(), - ), - }, - eccentricity: KvnValue { - value: 0.020842611, - unit: None, - }, - inclination: KvnValue { - value: 0.117746, - unit: Some( - "deg".to_string(), - ), - }, - ra_of_asc_node: KvnValue { - value: 17.604721, - unit: Some( - "deg".to_string(), - ), - }, - arg_of_pericenter: KvnValue { - value: 218.242943, - unit: Some( - "deg".to_string(), - ), - }, - true_anomaly: Some( - KvnValue { - value: 41.922339, - unit: Some( - "deg".to_string(), - ), - }, - ), - mean_anomaly: None, - gm: KvnValue { - value: 398600.4415, - unit: Some( - "km**3/s**2".to_string(), - ), - }, - }, - ), - spacecraft_parameters: Some( - SpacecraftParametersType { - comment_list: vec![ - KvnValue { - value: "Spacecraft parameters".to_string(), - unit: None, - }, - ], - mass: Some( - KvnValue { - value: 1913.0, - unit: Some( - "kg".to_string(), - ), - }, - ), - solar_rad_area: Some( - KvnValue { - value: 10.0, - unit: Some( - "m**2".to_string(), - ), - }, - ), - solar_rad_coeff: Some( - KvnValue { - value: 1.3, - unit: None, - }, - ), - drag_area: Some( - KvnValue { - value: 10.0, - unit: Some( - "m**2".to_string(), - ), - }, - ), - drag_coeff: Some( - KvnValue { - value: 2.3, - unit: None, - }, - ), - }, - ), - covariance_matrix: None, - maneuver_parameters_list: vec![ - ManeuverParametersType { - comment_list: vec![], - man_epoch_ignition: KvnDateTimeValue { - year: 2021, - month: 6, - day: 3, - hour: 9, - minute: 0, - second: 34, - fractional_second: 0.10000000000000142, - }, - man_duration: KvnValue { - value: 132.6, - unit: Some( - "s".to_string(), - ), - }, - man_delta_mass: KvnValue { - value: -18.418, - unit: Some( - "kg".to_string(), - ), - }, - man_ref_frame: KvnValue { - value: "EME2000".to_string(), - unit: None, - }, - man_dv_1: KvnValue { - value: -0.023257, - unit: Some( - "km/s".to_string(), - ), - }, - man_dv_2: KvnValue { - value: 0.0168316, - unit: Some( - "km/s".to_string(), - ), - }, - man_dv_3: KvnValue { - value: -0.00893444, - unit: Some( - "km/s".to_string(), - ), - }, - }, - ManeuverParametersType { - comment_list: vec![ - KvnValue { - value: "Second maneuver: first station acquisition maneuver".to_string(), - unit: None, - }, - KvnValue { - value: "impulsive, thrust direction fixed in RTN frame".to_string(), - unit: None, - }, - ], - man_epoch_ignition: KvnDateTimeValue { - year: 2021, - month: 6, - day: 5, - hour: 18, - minute: 59, - second: 21, - fractional_second: 0.0, - }, - man_duration: KvnValue { - value: 0.0, - unit: Some( - "s".to_string(), - ), - }, - man_delta_mass: KvnValue { - value: -1.469, - unit: Some( - "kg".to_string(), - ), - }, - man_ref_frame: KvnValue { - value: "RTN".to_string(), - unit: None, - }, - man_dv_1: KvnValue { - value: 0.001015, - unit: Some( - "km/s".to_string(), - ), - }, - man_dv_2: KvnValue { - value: -0.001873, - unit: Some( - "km/s".to_string(), - ), - }, - man_dv_3: KvnValue { - value: 0.0, - unit: Some( - "km/s".to_string(), - ), - }, - }, - ], - user_defined_parameters: None, - }, - }, - }, - }, - ) - ); - } -} From 0b5e261e6ab58dc2016dc5fee1286096edb6342d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:27:26 +0200 Subject: [PATCH 075/150] Add temp parser for comment --- crates/lox-utils/src/ndm/kvn/parser.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index e72599a2..6c9bc814 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -307,6 +307,21 @@ pub fn parse_kvn_string_line_new<'a>( // }, // )); // } + if input.trim_start().starts_with("COMMENT") { + //@TODO + + return Ok(( + "", + KvnValue { + value: input + .trim_start() + .trim_start_matches("COMMENT") + .trim_start() + .to_owned(), + unit: None, + }, + )); + } // Figure F-8: CCSDS 502.0-B-3 let re = if relaxed { From 1577021d42263a2e240c92c55344a5d4cee98949 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 28 May 2024 23:33:37 +0200 Subject: [PATCH 076/150] Remove the old style parsing functions --- crates/lox-utils/src/ndm/kvn/parser.rs | 433 +------------------------ 1 file changed, 5 insertions(+), 428 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 6c9bc814..63dda38c 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -174,30 +174,7 @@ pub trait KvnDeserializer { Self: Sized; } -fn comment_line<'a>(input: &'a str) -> nom::IResult<&'a str, &'a str, KvnParserErr<&'a str>> { - let (input, _) = nc::space0(input)?; - - let (remaining, _) = nb::tag("COMMENT ")(input)?; - - Ok(("", remaining)) -} - -pub fn kvn_line_matches_key<'a>(key: &'a str, input: &'a str) -> bool { - if key == "COMMENT" { - ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input).is_ok() - } else { - let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); - - // This function should return true in the case of malformed lines which - // are missing the keyword - if equals(input).is_ok() { - return true; - } - - ns::delimited(nc::space0, nb::tag(key), equals)(input).is_ok() - } -} - +//@TODO remove _new suffix pub fn kvn_line_matches_key_new<'a>( key: &'a str, input: &'a str, @@ -219,94 +196,10 @@ pub fn kvn_line_matches_key_new<'a>( } } -fn kvn_line<'a>( - key: &'a str, - input: &'a str, -) -> nom::IResult<&'a str, (&'a str, &'a str), KvnParserErr<&'a str>> { - let mut equals = ns::tuple((nc::space0::<_, KvnParserErr<_>>, nc::char('='), nc::space0)); - - match equals(input) { - Ok(_) => { - return Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { - expected: key, - })) - } - Err(_) => (), - } - - let value = nc::not_line_ending; - - let kvn = ns::separated_pair(nb::tag(key), equals, value); - - ns::delimited(nc::space0, kvn, nc::space0)(input) -} - -pub fn parse_kvn_string_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { - if key == "COMMENT" { - let (_, comment) = comment_line(input)?; - - return Ok(( - "", - KvnValue { - value: comment.to_owned(), - unit: None, - }, - )); - } - - let (remaining, result) = kvn_line(key, input)?; - - let parsed_right_hand_side = result.1; - - let (parsed_value, parsed_unit) = if with_unit { - // This unwrap is okay here because this regex never changes after testing - let re = Regex::new(r"(.*?)(\[(.*)\])?$").unwrap(); - - // This unwrap is okay because .* will always match - let captures = re.captures(parsed_right_hand_side).unwrap(); - - ( - captures.get(1).unwrap().as_str(), - captures.get(3).map(|f| f.as_str()), - ) - } else { - (parsed_right_hand_side, None) - }; - - if parsed_value.len() == 0 { - return Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: key })); - } - - let parsed_value = parsed_value.trim_end(); - - Ok(( - remaining, - KvnValue { - value: parsed_value.to_owned(), - unit: parsed_unit.map(|x| x.to_owned()), - }, - )) -} - pub fn parse_kvn_string_line_new<'a>( input: &'a str, relaxed: bool, ) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { - // if key == "COMMENT" { - // let (_, comment) = comment_line(input)?; - - // return Ok(( - // "", - // KvnValue { - // value: comment.to_owned(), - // unit: None, - // }, - // )); - // } if input.trim_start().starts_with("COMMENT") { //@TODO @@ -352,48 +245,6 @@ pub fn parse_kvn_string_line_new<'a>( Ok(("", KvnValue { value, unit: None })) } -pub fn parse_kvn_integer_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> nom::IResult<&'a str, KvnIntegerValue, KvnNumberLineParserErr<&'a str>> { - parse_kvn_string_line(key, input, with_unit) - .map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) - } - nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) - } - nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { - nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) - } - nom::Err::Error(KvnParserErr::ParserError(input, code)) => { - nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) - } - nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) - } - nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) - } - nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), - }) - .and_then(|result| { - let value = result.1.value.parse::().map_err(|_| { - nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: key }) - })?; - - Ok(( - "", - KvnValue { - value, - unit: result.1.unit, - }, - )) - }) -} - pub fn parse_kvn_integer_line_new<'a>( input: &'a str, with_unit: bool, @@ -440,48 +291,6 @@ fn is_empty_value(input: &str) -> bool { re.is_match(input) } -pub fn parse_kvn_numeric_line<'a>( - key: &'a str, - input: &'a str, - with_unit: bool, -) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { - parse_kvn_string_line(key, input, with_unit) - .map_err(|e| match e { - nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) - } - nom::Err::Error(KvnParserErr::EmptyValue { keyword }) => { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) - } - nom::Err::Failure(KvnParserErr::ParserError(input, code)) => { - nom::Err::Failure(KvnNumberLineParserErr::ParserError(input, code)) - } - nom::Err::Error(KvnParserErr::ParserError(input, code)) => { - nom::Err::Error(KvnNumberLineParserErr::ParserError(input, code)) - } - nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) - } - nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) => { - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) - } - nom::Err::Incomplete(needed) => nom::Err::Incomplete(needed), - }) - .and_then(|result| { - let value = fast_float::parse(result.1.value).map_err(|_| { - nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: key }) - })?; - - Ok(( - "", - KvnValue { - value, - unit: result.1.unit, - }, - )) - }) -} - pub fn parse_kvn_numeric_line_new<'a>( input: &'a str, with_unit: bool, @@ -594,14 +403,6 @@ mod test { use super::*; - #[test] - fn test_kvn_line_matches_key() { - assert!(!kvn_line_matches_key("ASD", "AAAAAD123 = ASDFG")); - assert!(kvn_line_matches_key("ASD", "ASD = ASDFG")); - assert!(!kvn_line_matches_key("ASD", "ASD ASD = ASDFG")); - assert!(kvn_line_matches_key("ASD", "= ASDFG")); - } - #[test] fn test_kvn_line_matches_key_new() { assert_eq!( @@ -622,153 +423,6 @@ mod test { ); } - #[test] - fn test_parse_kvn_string_line() { - // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values - // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" - })) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" - })) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD =", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" - })) - ); - - // 7.4.7 Any white space immediately preceding the end of line shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG ", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - - // a) there must be at least one blank character between the value and the units text; - // b) the units must be enclosed within square brackets (e.g., ‘[m]’); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: Some("km".to_string()) - } - )) - ); - assert_eq!( - parse_kvn_string_line("ASD", "ASD = ASDFG [km]", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: Some("km".to_string()) - } - )) - ); - - assert_eq!( - parse_kvn_string_line("ASD", "ASD = [km]", true), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" - })) - ); - - assert_eq!( - parse_kvn_string_line("ASD", "ASD [km]", true), - Err(nom::Err::Error(KvnParserErr::ParserError( - "[km]", - nom::error::ErrorKind::Char - ))) - ); - assert_eq!( - parse_kvn_string_line("ASD", " = [km]", true), - Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { - expected: "ASD" - })) - ); - - // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. - assert_eq!( - parse_kvn_string_line("ASD", " ASD = ASDFG", true), - Ok(( - "", - KvnValue { - value: "ASDFG".to_string(), - unit: None - } - )) - ); - - // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. - // [...] White space shall be retained (shall be significant) in comment values. - - assert_eq!( - parse_kvn_string_line("COMMENT", " COMMENT asd a asd a ads as ", true), - Ok(( - "", - KvnValue { - value: "asd a asd a ads as ".to_string(), - unit: None - } - )) - ); - - assert_eq!( - parse_kvn_string_line("COMMENT", " COMMENT ", true), - Ok(( - "", - KvnValue { - value: "".to_string(), - unit: None - } - )) - ); - } - #[test] fn test_parse_kvn_string_line_new() { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values @@ -918,83 +572,6 @@ mod test { // ); } - #[test] - fn test_parse_kvn_integer_line() { - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = 28800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: 28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = 00028800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: 28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = -28800 [s]", - true - ), - Ok(( - "", - KvnValue { - value: -28800, - unit: Some("s".to_string()) - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line( - "SCLK_OFFSET_AT_EPOCH", - "SCLK_OFFSET_AT_EPOCH = -28800", - true - ), - Ok(( - "", - KvnValue { - value: -28800, - unit: None - }, - )) - ); - - assert_eq!( - parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { - keyword: "SCLK_OFFSET_AT_EPOCH" - })) - ); - - assert_eq!( - parse_kvn_integer_line("SCLK_OFFSET_AT_EPOCH", "SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - keyword: "SCLK_OFFSET_AT_EPOCH" - })) - ); - } - #[test] fn test_parse_kvn_integer_line_new() { assert_eq!( @@ -1057,9 +634,9 @@ mod test { } #[test] - fn test_parse_kvn_numeric_line() { + fn test_parse_kvn_numeric_line_new() { assert_eq!( - parse_kvn_numeric_line("X", "X = 66559942 [km]", true), + parse_kvn_numeric_line_new("X = 66559942 [km]", true), Ok(( "", KvnValue { @@ -1070,7 +647,7 @@ mod test { ); assert_eq!( - parse_kvn_numeric_line("X", "X = 6655.9942 [km]", true), + parse_kvn_numeric_line_new("X = 6655.9942 [km]", true), Ok(( "", KvnValue { @@ -1081,7 +658,7 @@ mod test { ); assert_eq!( - parse_kvn_numeric_line("CX_X", "CX_X = 5.801003223606e-05", true), + parse_kvn_numeric_line_new("CX_X = 5.801003223606e-05", true), Ok(( "", KvnValue { From de69cd11dc35be309c3d4457f2af6af99b652711 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 29 May 2024 00:28:59 +0200 Subject: [PATCH 077/150] Implement OPM parsing with XML struct --- crates/lox-utils/src/ndm/kvn/parser.rs | 2 + crates/lox_derive/src/lib.rs | 1178 ++++++++++++++---------- 2 files changed, 681 insertions(+), 499 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 63dda38c..5a3403d7 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -172,6 +172,8 @@ pub trait KvnDeserializer { ) -> Result> where Self: Sized; + + fn should_check_key_match() -> bool; } //@TODO remove _new suffix diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 67f878c5..cd531594 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -6,502 +6,682 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ -use proc_macro2::Span; -use quote::quote; -use syn::{spanned::Spanned, DeriveInput, Field}; - -fn generate_call_to_deserializer_for_kvn_type( - type_name: &str, - expected_kvn_name: &str, -) -> Result { - match type_name { - "KvnDateTimeValue" | "KvnNumericValue" | "KvnStringValue" | "KvnIntegerValue" => { - let parser = match type_name { - "KvnDateTimeValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_datetime_line( - #expected_kvn_name, - next_line, - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "KvnStringValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_string_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "KvnNumericValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_numeric_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "KvnIntegerValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_integer_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - // Assumes the match list here exhaustively matches the one from above - _ => unreachable!(), - }; - - Ok(quote! { - match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name - }), - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key( - #expected_kvn_name, - next_line, - ); - - let result = if line_matches { - let next_line = lines.next().unwrap(); - - Ok(#parser) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, - }) - }; - - result - } - } - }) - } - - type_value => { - let type_ident = syn::Ident::new(&type_value, Span::call_site()); - - Ok(quote! { - { - let has_next_line = lines.peek().is_some(); - - let result = if has_next_line { - #type_ident::deserialize(lines) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: #expected_kvn_name - }) - }; - - result - } - }) - } - } -} - -fn generate_call_to_deserializer_for_kvn_type_new( - type_name: &str, -) -> Result { - match type_name { - "KvnDateTimeValue" | "f64" | "String" | "i32" => { - let parser = match type_name { - "KvnDateTimeValue" => quote! { //@TODO - crate::ndm::kvn::parser::parse_kvn_datetime_line_new( - lines.next().unwrap(), - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "String" => quote! { - crate::ndm::kvn::parser::parse_kvn_string_line_new( - lines.next().unwrap(), - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "f64" => quote! { - crate::ndm::kvn::parser::parse_kvn_numeric_line_new( - lines.next().unwrap(), - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "i32" => quote! { - crate::ndm::kvn::parser::parse_kvn_integer_line_new( - lines.next().unwrap(), - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - // Assumes the match list here exhaustively matches the one from above - _ => unreachable!(), - }; - - Ok(parser) - }, - type_value => { - let type_ident = syn::Ident::new(&type_value, Span::call_site()); - - Ok(quote! { - { - let has_next_line = lines.peek().is_some(); - - let result = if has_next_line { - #type_ident::deserialize(lines) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: "Blala" //@TODO - }) - }; - - result - } - }) - } - } -} - -fn get_generic_type_argument(field: &Field) -> Option { - if let syn::Type::Path(type_path) = &field.ty { - let path_part = type_path.path.segments.first(); - if let Some(path_part) = path_part { - if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - return Some(type_argument - .args - .first() - .unwrap() - .span() - .source_text() - .unwrap()); - } - } - } - - None -} - -fn generate_call_to_deserializer_for_option_type( - expected_kvn_name: &str, - field: &Field, -) -> Result { - let type_name = get_generic_type_argument(field); - - match type_name { - None => return Err( - syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") - .into_compile_error() - .into(), - ), - - Some(type_name) => { - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &expected_kvn_name, - )?; - - return Ok(quote! { - { - let result = #deserializer_for_kvn_type; - - match result { - Ok(item) => Some(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, - Err(e) => Err(e)?, - } - } - }); - } - } -} - -fn generate_call_to_deserializer_for_vec_type( - expected_kvn_name: &str, - field: &Field, -) -> Result { - if let syn::Type::Path(type_path) = &field.ty { - let path_part = type_path.path.segments.first(); - if let Some(path_part) = path_part { - if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - let type_name = type_argument - .args - .first() - .unwrap() - .span() - .source_text() - .unwrap(); - - let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); - - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &expected_kvn_name, - )?; - - let type_ident = syn::Ident::new(&type_name, Span::call_site()); - - return Ok(quote! { - { - let mut items: Vec<#type_ident> = Vec::new(); - - loop { - let result = #deserializer_for_kvn_type; - - match result { - Ok(item) => items.push(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, - Err(e) => Err(e)?, - } - } - - items - } - }); - } - } - } - - return Err( - syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") - .into_compile_error() - .into(), - ); -} - -fn is_value_unit_struct(item: &DeriveInput) -> bool { - for attr in item.attrs.iter() { - if attr.path().is_ident("kvn") { - if attr - .parse_nested_meta(|meta| { - if meta.path.is_ident("value_unit_struct") { - Ok(()) - } else { - Err(meta.error("unsupported attribute")) - } - }) - .is_ok() - { - return true; - } - } - } - - - false -} - -#[proc_macro_derive(KvnDeserialize, attributes(kvn))] -pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { - let item = syn::parse_macro_input!(item as syn::DeriveInput); - let name = &item.ident; - let is_value_unit_struct = is_value_unit_struct(&item); - - let syn::Data::Struct(strukt) = item.data else { - return syn::Error::new_spanned( - &item, - "only structs are supported for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into(); - }; - - let fields = match strukt.fields { - syn::Fields::Named(syn::FieldsNamed { named, .. }) => named, - _ => { - return syn::Error::new_spanned( - &strukt.fields, - "only named fields are supported for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into() - } - }; - - let deserializer = if is_value_unit_struct { - let mut deserializer = None; - let mut unit_type: Option = None; - - for (index, field) in fields.iter().enumerate() { - let field_name_ident = field.ident.as_ref().unwrap(); - - // Unwrap is okay because we only support named structs - let field_name = field_name_ident.span().source_text().unwrap(); - - match index { - 0 => { - if field_name.as_str() != "base" { - return syn::Error::new_spanned( - &field, - "The first field in a value unit struct should be called \"base\"", - ) - .into_compile_error() - .into() - } - - // Unwrap is okay because we expect this span to come from the source code - let field_type = field.ty.span().source_text().unwrap(); - - - match field_type.as_str() { - "KvnDateTimeValue" | "String" | "f64" | "i32" => { - match generate_call_to_deserializer_for_kvn_type_new(&field_type) { - Ok(deserializer_for_kvn_type) => deserializer = Some(deserializer_for_kvn_type), - Err(e) => return e, - } - }, - - _ => return syn::Error::new_spanned( - &field, - "Unsupported field type for deserializer", - ) - .into_compile_error() - .into() - } - }, - 1 => { - if field_name.as_str() != "units" { - return syn::Error::new_spanned( - &field, - "The second field in a value unit struct should be called \"units\"", - ) - .into_compile_error() - .into() - } - - unit_type = get_generic_type_argument(field); - }, - _ => return syn::Error::new_spanned( - &field, - "Only two fields \"base\" and \"units\" are called", - ) - .into_compile_error() - .into() - } - } - - // This unwrap is okay because we know the field exists. If it didn't exist we would've thrown an error. - let unit_type = unit_type.unwrap(); - - let unit_type_ident = syn::Ident::new(&unit_type, Span::call_site()); - - match deserializer { - None => return syn::Error::new_spanned( - &fields, - "Unable to create deserializer for struct", - ) - .into_compile_error() - .into(), - Some(deserializer) => quote! { - let kvn_value = #deserializer; - Ok(#name { - base: kvn_value.value, - units: kvn_value.unit.map(|unit| #unit_type_ident (unit)), - }) - } - } - } else { - let field_initializers: Result, _> = fields - .iter() - .enumerate() - .map(|(_, field)| { - let field_name = field.ident.as_ref().unwrap(); - - // Unwrap is okay because we only support named structs - let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); - - // Unwrap is okay because we expect this span to come from the source code - let field_type = field.ty.span().source_text().unwrap(); - - let type_ident = syn::Ident::new(&field_type, Span::call_site()); - - let parser = match field_type.as_str() { - "KvnDateTimeValue" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" => { - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &field_type, - &expected_kvn_name, - )?; - - quote! { - #deserializer_for_kvn_type? - } - } - "Option" => { - generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? - } - "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, - _ => { - quote! { - { - match lines.peek() { - None => Err( - crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name, - }, - )?, - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( - #expected_kvn_name, - next_line, - ); - - match line_matches { - Ok(true) => #type_ident::deserialize(lines), - Ok(false) => Err( - crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, - }, - ), - Err(crate::ndm::kvn::parser::KvnKeyMatchErr::KeywordNotFound { expected }) => Err( - crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::KeywordNotFound { - expected, - }, - ), - }? - } - } - } - } - } - }; - - Ok(quote! { - #field_name: #parser, - }) - }) - .collect(); - - if let Err(e) = field_initializers { - return e; - } - - let field_initializers = field_initializers.unwrap(); - - quote! { - Ok(#name { - #(#field_initializers)* - }) - } - }; - - - - let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); - - let deserializer = quote! { - impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #name #type_generics - #where_clause - { - fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) - -> Result<#name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { - - #deserializer - } - } - }; - - deserializer.into() -} + use proc_macro2::Span; + use quote::quote; + use syn::{spanned::Spanned, DeriveInput, Field}; + + fn generate_call_to_deserializer_for_kvn_type( + type_name: &str, + type_name_new: &syn::Path, + expected_kvn_name: &str, + ) -> Result { + match type_name { + "f64" | "String" | "i32" => { + let parser = match type_name { + "String" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line_new( + next_line, + false + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "f64" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line_new( + next_line, + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "i32" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line_new( + next_line, + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }), + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + let result = if line_matches { + let next_line = lines.next().unwrap(); + + Ok(#parser.value) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }) + }; + + result + } + } + }) + } + + "KvnNumericValue" | "KvnStringValue" | "KvnIntegerValue" => { + let parser = match type_name { + "KvnStringValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnNumericValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnIntegerValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }), + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + let result = if line_matches { + let next_line = lines.next().unwrap(); + + Ok(#parser) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }) + }; + + result + } + } + }) + } + + type_value => Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_name_new::deserialize(lines) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }) + }; + + result + } + }), + } + } + + //@TODO unify with above + fn generate_call_to_deserializer_for_kvn_type_new( + type_name: &str, + type_name_new: &syn::Path, + parent_type_name: &syn::Ident, + ) -> Result { + match type_name { + "f64" | "String" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { + let parser = match type_name { + "String" => { + let relaxed = parent_type_name.span().unwrap().source_text().unwrap().as_str() == "EpochType"; + + quote! { + crate::ndm::kvn::parser::parse_kvn_string_line_new( + lines.next().unwrap(), #relaxed + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + } + }, + "f64" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "i32" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(parser) + } + type_value => { + Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_name_new::deserialize(lines) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: "Blala" //@TODO + }) + }; + + result + } + }) + } + } + } + + fn get_generic_type_argument(field: &Field) -> Option { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + return Some( + type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(), + ); + } + } + } + + None + } + + fn get_generic_type_argument_new(field: &Field) -> Option<&syn::Path> { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + if let Some(syn::GenericArgument::Type(r#type)) = &type_argument.args.first() { + return extract_type_path(r#type); + } + } + } + } + + None + } + + fn generate_call_to_deserializer_for_option_type( + expected_kvn_name: &str, + field: &Field, + ) -> Result { + let type_name = get_generic_type_argument(field); + + // @TODO + let type_name_new = get_generic_type_argument_new(field).unwrap(); + + match type_name { + None => { + return Err(syn::Error::new_spanned( + &field, + "Malformed type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()) + } + + Some(type_name) => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &type_name_new, + &expected_kvn_name, + )?; + + let condition_shortcut = match type_name.as_str() { + "String" => quote! {}, + _ => quote! { ! #type_name_new::should_check_key_match() || }, + }; + + return Ok(quote! { + match lines.peek() { + None => None, + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + if #condition_shortcut line_matches { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => Some(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, + Err(e) => Err(e)?, + } + } else { + None + } + } + } + }); + } + } + } + + fn generate_call_to_deserializer_for_vec_type( + expected_kvn_name: &str, + field: &Field, + ) -> Result { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + let type_name = type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(); + + //@TODO + let bla = get_generic_type_argument_new(field).unwrap(); + + let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); + + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &bla, + &expected_kvn_name, + )?; + + let type_ident = syn::Ident::new(&type_name, Span::call_site()); + + return Ok(quote! { + { + let mut items: Vec<#type_ident> = Vec::new(); + + loop { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => items.push(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, + Err(e) => Err(e)?, + } + } + + items + } + }); + } + } + } + + return Err( + syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + .into_compile_error() + .into(), + ); + } + + fn is_value_unit_struct(item: &DeriveInput) -> bool { + for attr in item.attrs.iter() { + if attr.path().is_ident("kvn") { + if attr + .parse_nested_meta(|meta| { + if meta.path.is_ident("value_unit_struct") { + Ok(()) + } else { + Err(meta.error("unsupported attribute")) + } + }) + .is_ok() + { + return true; + } + } + } + + false + } + + fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> { + match *ty { + syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path), + _ => None, + } + } + + fn deserializer_for_struct_with_named_fields( + type_name: &proc_macro2::Ident, + fields: &syn::punctuated::Punctuated, + is_value_unit_struct: bool, + ) -> proc_macro2::TokenStream { + if type_name.to_string() == "UserDefinedType" { + //@TODO + return quote! { + Ok(Default::default()) + }; + } + + if is_value_unit_struct { + let mut deserializer = None; + let mut unit_type: Option = None; + let mut unit_field_name_ident: Option<&proc_macro2::Ident> = None; + let mut field_type: Option = None; + let mut field_type_new: Option<&syn::Path> = None; + + for (index, field) in fields.iter().enumerate() { + let field_name_ident = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + let field_name = field_name_ident.span().source_text().unwrap(); + + match index { + 0 => { + if field_name.as_str() != "base" { + return syn::Error::new_spanned( + &field, + "The first field in a value unit struct should be called \"base\"", + ) + .into_compile_error() + .into(); + } + + // Unwrap is okay because we expect this span to come from the source code + let local_field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let local_field_type_new = extract_type_path(&field.ty).unwrap(); + + let deserializer = match local_field_type.as_str() { + "KvnDateTimeValue" | "String" | "f64" | "i32" | "NonNegativeDouble" + | "NegativeDouble" | "PositiveDouble" => { + match generate_call_to_deserializer_for_kvn_type_new( + &local_field_type, + &local_field_type_new, + type_name, + ) { + Ok(deserializer_for_kvn_type) => { + deserializer = Some(deserializer_for_kvn_type) + } + Err(e) => return e.into(), + } + } + + _ => { + return syn::Error::new_spanned( + &field, + "Unsupported field type for deserializer", + ) + .into_compile_error() + .into() + } + }; + + field_type = Some(local_field_type); + field_type_new = Some(local_field_type_new); + + deserializer + } + 1 => { + if field_name.as_str() != "units" && field_name.as_str() != "parameter" { + return syn::Error::new_spanned( + &field, + "The second field in a value unit struct should be called \"units\" or \"parameter\"", + ) + .into_compile_error() + .into(); + } + + unit_type = get_generic_type_argument(field); + unit_field_name_ident = Some(field_name_ident); + } + _ => { + return syn::Error::new_spanned( + &field, + "Only two fields are allowed: \"base\" and (\"units\" or \"parameters\"", + ) + .into_compile_error() + .into() + } + } + } + + // This unwrap is okay because we know the field exists. If it didn't exist we would've thrown an error. + let unit_type = unit_type.unwrap(); + let unit_field_name_ident = unit_field_name_ident.unwrap(); + let field_type = field_type.unwrap(); + let field_type_new = field_type_new.unwrap(); + + let unit_type_ident = syn::Ident::new(&unit_type, Span::call_site()); + + let base = match field_type.as_str() { + "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { + quote! { #field_type_new (kvn_value.value) } + } + _ => quote! { kvn_value.value }, + }; + + match deserializer { + None => syn::Error::new_spanned(&fields, "Unable to create deserializer for struct") + .into_compile_error() + .into(), + Some(deserializer) => quote! { + let kvn_value = #deserializer; + Ok(#type_name { + base: #base, + #unit_field_name_ident: kvn_value.unit.map(|unit| #unit_type_ident (unit)), + }) + }, + } + } else { + let field_deserializers: Result, _> = fields + .iter() + .enumerate() + .map(|(_, field)| { + let field_name = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + let parser = match field_type.as_str() { + "EpochType" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &field_type, + field_type_new, + &expected_kvn_name, + )?; + + quote! { + #deserializer_for_kvn_type? + } + } + "Option" => { + generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? + } + "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, + _ => { + + let condition_shortcut = match field_type.as_str() { + "String" => quote! {}, + _ => quote! { ! #field_type_new::should_check_key_match() || }, + }; + + quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + })?, + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + if #condition_shortcut line_matches { + #field_type_new::deserialize(lines)? + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + })? + } + } + } + } + } + }; + + Ok(quote! { + #field_name: #parser, + }) + }) + .collect(); + + if let Err(e) = field_deserializers { + return e; + } + + let field_deserializers = field_deserializers.unwrap(); + + quote! { + Ok(#type_name { + #(#field_deserializers)* + }) + } + } + } + + fn deserializers_for_struct_with_unnamed_fields( + type_name: &proc_macro2::Ident, + fields: &syn::punctuated::Punctuated, + ) -> proc_macro2::TokenStream { + let field_deserializers: Result, _> = fields + .iter() + .enumerate() + .map(|(_, field)| { + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + let deserializer_for_kvn_type = + generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new, type_name)?; + + Ok(quote! { + #deserializer_for_kvn_type.value, + }) + }) + .collect(); + + if let Err(e) = field_deserializers { + return e; + } + + let field_deserializers = field_deserializers.unwrap(); + + quote! { + Ok(#type_name ( + #(#field_deserializers)* + )) + } + } + + #[proc_macro_derive(KvnDeserialize, attributes(kvn))] + pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let item = syn::parse_macro_input!(item as syn::DeriveInput); + let type_name = &item.ident; + let is_value_unit_struct = is_value_unit_struct(&item); + + let syn::Data::Struct(strukt) = item.data else { + return syn::Error::new_spanned( + &item, + "only structs are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into(); + }; + + let (struct_deserializer, should_check_key_match) = match strukt.fields { + syn::Fields::Named(syn::FieldsNamed { named, .. }) => ( + deserializer_for_struct_with_named_fields(type_name, &named, is_value_unit_struct), + is_value_unit_struct, + ), + syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => ( + deserializers_for_struct_with_unnamed_fields(type_name, &unnamed), + true, + ), + _ => { + return syn::Error::new_spanned( + &strukt.fields, + "only named fields are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into() + } + }; + + let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); + + let struct_deserializer = quote! { + impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #type_name #type_generics + #where_clause + { + fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) + -> Result<#type_name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { + + #struct_deserializer + } + + fn should_check_key_match () -> bool { + #should_check_key_match + } + } + }; + + struct_deserializer.into() + } + \ No newline at end of file From 8947f0920404a4b990de89a52975b4a5a254b564 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 30 May 2024 23:28:43 +0200 Subject: [PATCH 078/150] Implement OMM and OCM KVN parsers --- crates/lox-utils/src/ndm/common.rs | 290 ++++++++++++++++++++++--- crates/lox-utils/src/ndm/kvn/parser.rs | 14 +- crates/lox-utils/src/ndm/ocm.rs | 110 +++++++++- crates/lox-utils/src/ndm/omm.rs | 283 +++++++++++++++++++++--- crates/lox_derive/src/lib.rs | 8 +- 5 files changed, 627 insertions(+), 78 deletions(-) diff --git a/crates/lox-utils/src/ndm/common.rs b/crates/lox-utils/src/ndm/common.rs index 7380daf8..4eff4b78 100644 --- a/crates/lox-utils/src/ndm/common.rs +++ b/crates/lox-utils/src/ndm/common.rs @@ -32,7 +32,15 @@ pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct AreaUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); @@ -44,7 +52,15 @@ pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct GmUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct LengthUnits(#[serde(rename = "$text")] pub String); @@ -56,11 +72,27 @@ pub struct MassUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct MomentUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct WkgUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); @@ -93,7 +125,15 @@ pub struct VecDouble { pub items: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct Vec3Double(#[serde(rename = "$text")] pub f64); @@ -117,7 +157,15 @@ pub struct Vec9Double(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct EpochType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TimeUnits(#[serde(rename = "$text")] pub String); @@ -149,19 +197,51 @@ pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct PercentType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct Range100Type(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ProbabilityType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PercentageUnits(#[serde(rename = "$text")] pub String); @@ -169,43 +249,123 @@ pub struct PercentageUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct YesNoType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TrajBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct RevNumBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct CovBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManDcType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct NumPerYearUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ThrustUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct CovOrderType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct GeomagUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SolarFluxUnits(#[serde(rename = "$text")] pub String); @@ -482,7 +642,15 @@ pub struct DayIntervalType { pub units: DayIntervalUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmDayIntervalType { #[serde(rename = "$text")] @@ -572,7 +740,15 @@ pub struct LengthType { pub units: LengthUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmLengthType { #[serde(rename = "$text")] @@ -617,7 +793,15 @@ pub struct MomentType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct WkgType { #[serde(rename = "$text")] @@ -890,7 +1074,15 @@ pub struct RelTimeType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TimeOffsetType { #[serde(rename = "$text")] @@ -899,7 +1091,15 @@ pub struct TimeOffsetType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PercentageType { #[serde(rename = "$text")] @@ -908,7 +1108,15 @@ pub struct PercentageType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManeuverFreqType { #[serde(rename = "$text")] @@ -917,7 +1125,15 @@ pub struct ManeuverFreqType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ThrustType { #[serde(rename = "$text")] @@ -926,7 +1142,15 @@ pub struct ThrustType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct GeomagType { #[serde(rename = "$text")] @@ -935,7 +1159,15 @@ pub struct GeomagType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SolarFluxType { #[serde(rename = "$text")] diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 5a3403d7..3c603826 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -15,7 +15,6 @@ use nom::sequence as ns; use regex::Regex; pub type KvnStringValue = KvnValue; -pub type KvnIntegerValue = KvnValue; pub type KvnNumericValue = KvnValue; #[derive(Debug, PartialEq)] @@ -247,10 +246,13 @@ pub fn parse_kvn_string_line_new<'a>( Ok(("", KvnValue { value, unit: None })) } -pub fn parse_kvn_integer_line_new<'a>( +pub fn parse_kvn_integer_line_new<'a, T>( input: &'a str, with_unit: bool, -) -> nom::IResult<&'a str, KvnIntegerValue, KvnNumberLineParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnValue, KvnNumberLineParserErr<&'a str>> +where + T: std::str::FromStr, +{ if is_empty_value(input) { Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { //@TODO @@ -274,7 +276,7 @@ pub fn parse_kvn_integer_line_new<'a>( let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); - let value = value.parse::().map_err(|_| { + let value = value.parse::().map_err(|_| { nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { //@TODO keyword: "SCLK_OFFSET_AT_EPOCH", @@ -621,14 +623,14 @@ mod test { ); assert_eq!( - parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = -asd", true), + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = -asd", true), Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: "SCLK_OFFSET_AT_EPOCH" })) ); assert_eq!( - parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = [s]", true), + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = [s]", true), Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword: "SCLK_OFFSET_AT_EPOCH" })) diff --git a/crates/lox-utils/src/ndm/ocm.rs b/crates/lox-utils/src/ndm/ocm.rs index ce80d144..9aba7d7f 100644 --- a/crates/lox-utils/src/ndm/ocm.rs +++ b/crates/lox-utils/src/ndm/ocm.rs @@ -10,7 +10,15 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmType { #[serde(rename = "header")] @@ -23,14 +31,30 @@ pub struct OcmType { pub version: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmBody { #[serde(rename = "segment")] pub segment: OcmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmSegment { #[serde(rename = "metadata")] @@ -39,7 +63,15 @@ pub struct OcmSegment { pub data: OcmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmMetadata { #[serde(rename = "COMMENT")] @@ -140,7 +172,15 @@ pub struct OcmMetadata { pub celestial_source: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmData { #[serde(rename = "traj")] @@ -159,7 +199,15 @@ pub struct OcmData { pub user: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmTrajStateType { #[serde(rename = "COMMENT")] @@ -204,7 +252,15 @@ pub struct OcmTrajStateType { pub traj_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmPhysicalDescriptionType { #[serde(rename = "COMMENT")] @@ -311,7 +367,15 @@ pub struct OcmPhysicalDescriptionType { pub iyz: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmCovarianceMatrixType { #[serde(rename = "COMMENT")] @@ -346,7 +410,15 @@ pub struct OcmCovarianceMatrixType { pub cov_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmManeuverParametersType { #[serde(rename = "COMMENT")] @@ -415,7 +487,15 @@ pub struct OcmManeuverParametersType { pub man_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmPerturbationsType { #[serde(rename = "COMMENT")] @@ -480,7 +560,15 @@ pub struct OcmPerturbationsType { pub fixed_y10p7_mean: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmOdParametersType { #[serde(rename = "COMMENT")] diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs index e5fbd1c1..6abe3727 100644 --- a/crates/lox-utils/src/ndm/omm.rs +++ b/crates/lox-utils/src/ndm/omm.rs @@ -10,39 +10,111 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct BStarUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct BStarUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct BTermUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct BTermUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct AgomUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AgomUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct ElementSetNoType(#[serde(rename = "$text")] pub std::string::String); +pub struct ElementSetNoType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct RevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct RevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct DRevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DRevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct DdRevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DdRevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] -pub struct SpacewarnType(#[serde(rename = "$text")] pub std::string::String); +pub struct SpacewarnType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmType { #[serde(rename = "header")] @@ -55,14 +127,30 @@ pub struct OmmType { pub version: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmBody { #[serde(rename = "segment")] pub segment: OmmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmSegment { #[serde(rename = "metadata")] @@ -71,7 +159,15 @@ pub struct OmmSegment { pub data: OmmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmMetadata { #[serde(rename = "COMMENT")] @@ -92,7 +188,15 @@ pub struct OmmMetadata { pub mean_element_theory: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmData { #[serde(rename = "COMMENT")] @@ -109,7 +213,15 @@ pub struct OmmData { pub user_defined_parameters: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct MeanElementsType { #[serde(rename = "COMMENT")] @@ -134,7 +246,15 @@ pub struct MeanElementsType { pub gm: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TleParametersType { #[serde(rename = "COMMENT")] @@ -161,7 +281,15 @@ pub struct TleParametersType { pub agom: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BStarType { #[serde(rename = "$text")] @@ -170,7 +298,15 @@ pub struct BStarType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BTermType { #[serde(rename = "$text")] @@ -179,7 +315,15 @@ pub struct BTermType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct AgomType { #[serde(rename = "$text")] @@ -188,7 +332,15 @@ pub struct AgomType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct RevType { #[serde(rename = "$text")] @@ -197,7 +349,15 @@ pub struct RevType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DRevType { #[serde(rename = "$text")] @@ -206,7 +366,15 @@ pub struct DRevType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DdRevType { #[serde(rename = "$text")] @@ -1440,4 +1608,61 @@ mod test { assert!(message.is_err()); } + #[test] + fn test_parse_omm_message_kvn() { + //@TODO add back: CCSDS_OPM_VERS = 3.0 + //@TOOD add back user defined stuff + let kvn = r#"COMMENT this is a comment +COMMENT here is another one +CREATION_DATE = 2007-065T16:00:00 +ORIGINATOR = NOAA/USA +COMMENT this comment doesn't say much +OBJECT_NAME = GOES 9 +OBJECT_ID = 1995-025A +CENTER_NAME = EARTH +REF_FRAME = TOD +REF_FRAME_EPOCH = 2000-003T10:34:00 +TIME_SYSTEM = MRT +MEAN_ELEMENT_THEORY = SOME THEORY +COMMENT the following data is what we're looking for +EPOCH = 2000-005T10:00:00 +SEMI_MAJOR_AXIS = 6800 +ECCENTRICITY = 0.0005013 +INCLINATION = 3.0539 +RA_OF_ASC_NODE = 81.7939 +ARG_OF_PERICENTER = 249.2363 +MEAN_ANOMALY = 150.1602 +COMMENT spacecraft data +MASS = 300 +SOLAR_RAD_AREA = 5 +SOLAR_RAD_COEFF = 0.001 +DRAG_AREA = 4 +DRAG_COEFF = 0.002 +COMMENT Covariance matrix +COV_REF_FRAME = TNW +CX_X = 3.331349476038534e-04 +CY_X = 4.618927349220216e-04 +CY_Y = 6.782421679971363e-04 +CZ_X = -3.070007847730449e-04 +CZ_Y = -4.221234189514228e-04 +CZ_Z = 3.231931992380369e-04 +CX_DOT_X = -3.349365033922630e-07 +CX_DOT_Y = -4.686084221046758e-07 +CX_DOT_Z = 2.484949578400095e-07 +CX_DOT_X_DOT = 4.296022805587290e-10 +CY_DOT_X = -2.211832501084875e-07 +CY_DOT_Y = -2.864186892102733e-07 +CY_DOT_Z = 1.798098699846038e-07 +CY_DOT_X_DOT = 2.608899201686016e-10 +CY_DOT_Y_DOT = 1.767514756338532e-10 +CZ_DOT_X = -3.041346050686871e-07 +CZ_DOT_Y = -4.989496988610662e-07 +CZ_DOT_Z = 3.540310904497689e-07 +CZ_DOT_X_DOT = 1.869263192954590e-10 +CZ_DOT_Y_DOT = 1.008862586240695e-10 +CZ_DOT_Z_DOT = 6.224444338635500e-10"#; + + println!("{:#?}", OmmType::deserialize(&mut kvn.lines().peekable())); + // assert_eq!(OmmType::deserialize(&mut kvn.lines().peekable()), Ok()); + } } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index cd531594..e96fc3fc 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -16,7 +16,7 @@ expected_kvn_name: &str, ) -> Result { match type_name { - "f64" | "String" | "i32" => { + "f64" | "String" | "i32" | "u64" => { let parser = match type_name { "String" => quote! { crate::ndm::kvn::parser::parse_kvn_string_line_new( @@ -28,12 +28,14 @@ "f64" => quote! { crate::ndm::kvn::parser::parse_kvn_numeric_line_new( next_line, + true, ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, - "i32" => quote! { + "i32" | "u64" => quote! { crate::ndm::kvn::parser::parse_kvn_integer_line_new( next_line, + true, ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, @@ -267,7 +269,7 @@ )?; let condition_shortcut = match type_name.as_str() { - "String" => quote! {}, + "String" | "f64" | "i32" | "u64" => quote! {}, _ => quote! { ! #type_name_new::should_check_key_match() || }, }; From 9b2b2b16659031de1bfe385c5803edb659449b67 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 30 May 2024 23:29:22 +0200 Subject: [PATCH 079/150] Fix formatting --- crates/lox-utils/src/ndm/omm.rs | 866 +++++++++++++------------------- 1 file changed, 343 insertions(+), 523 deletions(-) diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs index 6abe3727..81b0a1d3 100644 --- a/crates/lox-utils/src/ndm/omm.rs +++ b/crates/lox-utils/src/ndm/omm.rs @@ -8,6 +8,8 @@ use serde; +use crate::ndm::kvn::parser::KvnDeserializer; + use super::common; #[derive( @@ -659,14 +661,13 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType( - "2021-03-24T23:00:00.000".to_string(), - ), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), originator: "CelesTrak".to_string(), message_id: None, }, @@ -686,19 +687,13 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2021-03-22T13:21:09.224928".to_string(), - ), + epoch: common::EpochType("2021-03-22T13:21:09.224928".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 13.82309053, - units: None, - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0205751, - ), + mean_motion: Some(RevType { + base: 13.82309053, + units: None, + },), + eccentricity: common::NonNegativeDouble(0.0205751,), inclination: common::InclinationType { base: 49.8237, units: None, @@ -719,46 +714,28 @@ mod test { gm: None, }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: Some( - 0, - ), - classification_type: Some( - "U".to_string(), - ), - norad_cat_id: Some( - 7646, - ), - element_set_no: Some( - ElementSetNoType( - "999".to_string(), - ), - ), - rev_at_epoch: Some( - 32997, - ), - bstar: Some( - BStarType { - base: -4.7102e-6, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0,), + classification_type: Some("U".to_string(),), + norad_cat_id: Some(7646,), + element_set_no: Some(ElementSetNoType("999".to_string(),),), + rev_at_epoch: Some(32997,), + bstar: Some(BStarType { + base: -4.7102e-6, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, }, - ), + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), covariance_matrix: None, user_defined_parameters: None, }, @@ -766,7 +743,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }); + } + ); } #[test] @@ -843,20 +821,15 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { - comment_list: vec![ - "THIS IS AN XML VERSION OF THE OMM".to_string(), - ], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), + creation_date: common::EpochType("2007-065T16:00:00".to_string(),), originator: "NOAA".to_string(), - message_id: Some( - "OMM 201113719185".to_string(), - ), + message_id: Some("OMM 201113719185".to_string(),), }, body: OmmBody { segment: OmmSegment { @@ -874,19 +847,13 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2007-064T10:34:41.4264".to_string(), - ), + epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 1.00273272, - units: None, - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), + mean_motion: Some(RevType { + base: 1.00273272, + units: None, + },), + eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { base: 3.0539, units: None, @@ -903,151 +870,130 @@ mod test { base: 150.1602, units: None, }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: None, - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: None, + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some( - 23581, - ), - element_set_no: Some( - ElementSetNoType( - "0925".to_string(), - ), - ), - rev_at_epoch: Some( - 4316, - ), - bstar: Some( - BStarType { - base: 0.0001, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some(23581,), + element_set_no: Some(ElementSetNoType("0925".to_string(),),), + rev_at_epoch: Some(4316,), + bstar: Some(BStarType { + base: 0.0001, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, }, - ), - covariance_matrix: Some( - common::OpmCovarianceMatrixType { - comment_list: vec![], - cov_ref_frame: Some( - "TEME".to_string(), - ), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some("TEME".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, }, - ), + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + },), user_defined_parameters: None, }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "3.0".to_string(), - }); + } + ); } #[test] @@ -1126,21 +1072,16 @@ mod test { "#; let message: OmmType = from_str(xml).unwrap(); - - assert_eq!(message, + + assert_eq!( + message, OmmType { header: common::OdmHeader { - comment_list: vec![ - "THIS IS AN XML VERSION OF THE OMM".to_string(), - ], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), + creation_date: common::EpochType("2007-065T16:00:00".to_string(),), originator: "NOAA".to_string(), - message_id: Some( - "OMM 201113719185".to_string(), - ), + message_id: Some("OMM 201113719185".to_string(),), }, body: OmmBody { segment: OmmSegment { @@ -1157,222 +1098,156 @@ mod test { data: OmmData { comment_list: vec![], mean_elements: MeanElementsType { - comment_list: vec![ - "mean Elements".to_string(), - ], - epoch: common::EpochType( - "2007-064T10:34:41.4264".to_string(), - ), + comment_list: vec!["mean Elements".to_string(),], + epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 1.00273272, - units: Some( - RevUnits( - "rev/day".to_string(), - ), - ), - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), + mean_motion: Some(RevType { + base: 1.00273272, + units: Some(RevUnits("rev/day".to_string(),),), + },), + eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { base: 3.0539, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { base: 81.7939, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { base: 249.2363, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { base: 150.1602, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: None, - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: None, + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![ - "tle Parameters".to_string(), - ], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some( - 23581, - ), - element_set_no: Some( - ElementSetNoType( - "0925".to_string(), - ), - ), - rev_at_epoch: Some( - 4316, - ), - bstar: Some( - BStarType { - base: 0.0001, - units: Some( - BStarUnits( - "1/ER".to_string(), - ), - ), - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: Some( - DRevUnits( - "rev/day**2".to_string(), - ), - ), - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: Some( - DRevUnits( - "rev/day**3".to_string(), - ), - ), - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec!["tle Parameters".to_string(),], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some(23581,), + element_set_no: Some(ElementSetNoType("0925".to_string(),),), + rev_at_epoch: Some(4316,), + bstar: Some(BStarType { + base: 0.0001, + units: Some(BStarUnits("1/ER".to_string(),),), + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: Some(DRevUnits("rev/day**2".to_string(),),), }, - ), - covariance_matrix: Some( - common::OpmCovarianceMatrixType { - comment_list: vec![ - "covariance Matrix".to_string(), - ], - cov_ref_frame: Some( - "TEME".to_string(), - ), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: Some(DRevUnits("rev/day**3".to_string(),),), + },), + agom: None, + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec!["covariance Matrix".to_string(),], + cov_ref_frame: Some("TEME".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, }, - ), + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + },), user_defined_parameters: None, }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "3.0".to_string(), - }); + } + ); } - #[test] fn test_parse_omm_message3() { let xml = r#" @@ -1423,14 +1298,13 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType( - "2021-03-24T23:00:00.000".to_string(), - ), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), originator: "CelesTrak".to_string(), message_id: None, }, @@ -1450,134 +1324,80 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2008-09-20T12:25:40.104192".to_string(), - ), + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 15.72125391, - units: Some( - RevUnits( - "rev/day".to_string(), - ), - ), - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0006703, - ), + mean_motion: Some(RevType { + base: 15.72125391, + units: Some(RevUnits("rev/day".to_string(),),), + },), + eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { base: 51.6416, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { base: 247.4627, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { base: 130.536, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { base: 325.0288, - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + units: Some(common::AngleUnits("deg".to_string(),),), }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: Some( - common::GmUnits( - "km**3/s**2".to_string(), - ), - ), - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: Some( - 0, - ), - classification_type: Some( - "U".to_string(), - ), - norad_cat_id: Some( - 7646, - ), - element_set_no: Some( - ElementSetNoType( - "999".to_string(), - ), - ), - rev_at_epoch: Some( - 32997, - ), - bstar: Some( - BStarType { - base: -4.7102e-6, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0,), + classification_type: Some("U".to_string(),), + norad_cat_id: Some(7646,), + element_set_no: Some(ElementSetNoType("999".to_string(),),), + rev_at_epoch: Some(32997,), + bstar: Some(BStarType { + base: -4.7102e-6, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, }, - ), + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), covariance_matrix: None, - user_defined_parameters: Some( - common::UserDefinedType { - comment_list: vec![], - user_defined_list: vec![ - common::UserDefinedParameterType { - base: "foo enters".to_string(), - parameter: "FOO".to_string(), - }, - common::UserDefinedParameterType { - base: "a bar".to_string(), - parameter: "BAR".to_string(), - }, - ], - }, - ), + user_defined_parameters: Some(common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "foo enters".to_string(), + parameter: "FOO".to_string(), + }, + common::UserDefinedParameterType { + base: "a bar".to_string(), + parameter: "BAR".to_string(), + }, + ], + },), }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }); + } + ); } - #[test] fn test_parse_omm_message_spurious() { let xml = r#" From 00e9f80c6a5cde502a32d8d9b6dbb99423529e5e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 31 May 2024 00:02:40 +0200 Subject: [PATCH 080/150] Add back a todo --- crates/lox-utils/src/ndm/opm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index 3fb2c11c..d8a365d9 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -577,8 +577,8 @@ mod test { #[test] fn test_parse_opm_message_kvn() { - //@TODO document limitation about the eager parsing of comments //@TODO add back: CCSDS_OPM_VERS = 3.0 + //@TOOD add user defined stuff let kvn = r#"COMMENT Generated by GSOC, R. Kiehling COMMENT Current intermediate orbit IO2 and maneuver planning data CREATION_DATE = 2021-06-03T05:33:00.123 From 4aaee44fccaec4de9f35af4bba5a481e4dbf7d2c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 31 May 2024 00:06:53 +0200 Subject: [PATCH 081/150] Relax parsing of string inputs --- crates/lox-utils/src/ndm/kvn/parser.rs | 27 ++++++++++++-------------- crates/lox_derive/src/lib.rs | 11 +++-------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 3c603826..4977ce67 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -199,7 +199,6 @@ pub fn kvn_line_matches_key_new<'a>( pub fn parse_kvn_string_line_new<'a>( input: &'a str, - relaxed: bool, ) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { if input.trim_start().starts_with("COMMENT") { //@TODO @@ -217,13 +216,11 @@ pub fn parse_kvn_string_line_new<'a>( )); } - // Figure F-8: CCSDS 502.0-B-3 - let re = if relaxed { + // Inspired by figure F-8: CCSDS 502.0-B-3, but accepts a more relaxed input. Orekit seems to suggest that there + // are quite a few messages being used which are not strictly compliant. + let re = Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:.*)))(?:\s*)$") - .unwrap() - } else { - Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:[0-9A-Z_\.\- ]*)|(?:[0-9a-z_\.\- ]*)))(?:\s*)$").unwrap() - }; + .unwrap(); // @TODO unwrap let captures = re.captures(input).unwrap(); @@ -432,7 +429,7 @@ mod test { // 7.5.1 A non-empty value field must be assigned to each mandatory keyword except for *‘_START’ and *‘_STOP’ keyword values // 7.4.6 Any white space immediately preceding or following the ‘equals’ sign shall not be significant. assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG", false), + parse_kvn_string_line_new("ASD = ASDFG"), Ok(( "", KvnValue { @@ -442,7 +439,7 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG", false), + parse_kvn_string_line_new("ASD = ASDFG"), Ok(( "", KvnValue { @@ -452,7 +449,7 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG", false), + parse_kvn_string_line_new("ASD = ASDFG"), Ok(( "", KvnValue { @@ -462,19 +459,19 @@ mod test { )) ); assert_eq!( - parse_kvn_string_line_new("ASD = ", false), + parse_kvn_string_line_new("ASD = "), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) ); assert_eq!( - parse_kvn_string_line_new("ASD = ", false), + parse_kvn_string_line_new("ASD = "), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) ); assert_eq!( - parse_kvn_string_line_new("ASD =", false), + parse_kvn_string_line_new("ASD ="), Err(nom::Err::Failure(KvnParserErr::EmptyValue { keyword: "ASD" })) @@ -482,7 +479,7 @@ mod test { // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( - parse_kvn_string_line_new("ASD = ASDFG ", false), + parse_kvn_string_line_new("ASD = ASDFG "), Ok(( "", KvnValue { @@ -539,7 +536,7 @@ mod test { // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. assert_eq!( - parse_kvn_string_line_new(" ASD = ASDFG", false), + parse_kvn_string_line_new(" ASD = ASDFG"), Ok(( "", KvnValue { diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index e96fc3fc..f9594a6a 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -20,8 +20,7 @@ let parser = match type_name { "String" => quote! { crate::ndm::kvn::parser::parse_kvn_string_line_new( - next_line, - false + next_line ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, @@ -151,17 +150,14 @@ fn generate_call_to_deserializer_for_kvn_type_new( type_name: &str, type_name_new: &syn::Path, - parent_type_name: &syn::Ident, ) -> Result { match type_name { "f64" | "String" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { let parser = match type_name { "String" => { - let relaxed = parent_type_name.span().unwrap().source_text().unwrap().as_str() == "EpochType"; - quote! { crate::ndm::kvn::parser::parse_kvn_string_line_new( - lines.next().unwrap(), #relaxed + lines.next().unwrap() ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? } @@ -437,7 +433,6 @@ match generate_call_to_deserializer_for_kvn_type_new( &local_field_type, &local_field_type_new, - type_name, ) { Ok(deserializer_for_kvn_type) => { deserializer = Some(deserializer_for_kvn_type) @@ -611,7 +606,7 @@ let field_type_new = extract_type_path(&field.ty).unwrap(); let deserializer_for_kvn_type = - generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new, type_name)?; + generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new)?; Ok(quote! { #deserializer_for_kvn_type.value, From 2dc1543ebdb05ece6d6e4a9d933fce79c4c224fc Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 31 May 2024 00:09:05 +0200 Subject: [PATCH 082/150] Add some todos to the code --- crates/lox_derive/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index f9594a6a..33772140 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -27,14 +27,14 @@ "f64" => quote! { crate::ndm::kvn::parser::parse_kvn_numeric_line_new( next_line, - true, + true, //@TODO ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "i32" | "u64" => quote! { crate::ndm::kvn::parser::parse_kvn_integer_line_new( next_line, - true, + true, //@TODO ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, From 9b170042d880c615b819c318b91ed49d06c1045f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 14:37:27 +0300 Subject: [PATCH 083/150] Add tests for COMMENT parsing --- crates/lox-utils/src/ndm/kvn/parser.rs | 43 ++++++++++++-------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 4977ce67..b4d483bb 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -201,8 +201,6 @@ pub fn parse_kvn_string_line_new<'a>( input: &'a str, ) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { if input.trim_start().starts_with("COMMENT") { - //@TODO - return Ok(( "", KvnValue { @@ -546,31 +544,30 @@ mod test { )) ); - //@TODO implement COMMENT // 7.8.5 All comment lines shall begin with the ‘COMMENT’ keyword followed by at least one space. // [...] White space shall be retained (shall be significant) in comment values. - // assert_eq!( - // parse_kvn_string_line_new(" COMMENT asd a asd a ads as "), - // Ok(( - // "", - // KvnValue { - // value: "asd a asd a ads as ".to_string(), - // unit: None - // } - // )) - // ); + assert_eq!( + parse_kvn_string_line_new(" COMMENT asd a asd a ads as "), + Ok(( + "", + KvnValue { + value: "asd a asd a ads as ".to_string(), + unit: None + } + )) + ); - // assert_eq!( - // parse_kvn_string_line_new(" COMMENT "), - // Ok(( - // "", - // KvnValue { - // value: "".to_string(), - // unit: None - // } - // )) - // ); + assert_eq!( + parse_kvn_string_line_new(" COMMENT "), + Ok(( + "", + KvnValue { + value: "".to_string(), + unit: None + } + )) + ); } #[test] From e0f546ccd288e197f43615b71a27f4ee3176f759 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 15:04:37 +0300 Subject: [PATCH 084/150] Remove keyword from error type --- crates/lox-utils/src/ndm/kvn/parser.rs | 98 +++++++++++--------------- 1 file changed, 42 insertions(+), 56 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index b4d483bb..a9daac29 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -20,7 +20,7 @@ pub type KvnNumericValue = KvnValue; #[derive(Debug, PartialEq)] pub enum KvnParserErr { KeywordNotFound { expected: I }, - EmptyValue { keyword: I }, + EmptyValue { input: I }, ParserError(I, ErrorKind), } @@ -33,25 +33,25 @@ pub enum KvnKeyMatchErr { pub enum KvnNumberLineParserErr { ParserError(I, ErrorKind), KeywordNotFound { expected: I }, - EmptyValue { keyword: I }, - InvalidFormat { keyword: I }, + EmptyValue { input: I }, + InvalidFormat { input: I }, } #[derive(PartialEq, Debug)] pub enum KvnDateTimeParserErr { ParserError(I, ErrorKind), KeywordNotFound { expected: I }, - EmptyValue { keyword: I }, - InvalidFormat { keyword: I }, + EmptyValue { input: I }, + InvalidFormat { input: I }, } #[derive(PartialEq, Debug)] pub enum KvnDeserializerErr { - InvalidDateTimeFormat { keyword: I }, - InvalidNumberFormat { keyword: I }, + InvalidDateTimeFormat { input: I }, + InvalidNumberFormat { input: I }, KeywordNotFound { expected: I }, UnexpectedKeyword { found: I, expected: I }, - EmptyValue { keyword: I }, + EmptyValue { input: I }, UnexpectedEndOfInput { keyword: I }, GeneralParserError(I, ErrorKind), } @@ -59,9 +59,9 @@ pub enum KvnDeserializerErr { impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnParserErr::EmptyValue { keyword }) - | nom::Err::Failure(KvnParserErr::EmptyValue { keyword }) => { - KvnDeserializerErr::EmptyValue { keyword } + nom::Err::Error(KvnParserErr::EmptyValue { input }) + | nom::Err::Failure(KvnParserErr::EmptyValue { input }) => { + KvnDeserializerErr::EmptyValue { input } } nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) | nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { @@ -80,17 +80,17 @@ impl From>> for KvnDeserializerErr { impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnDateTimeParserErr::EmptyValue { keyword }) - | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { keyword }) => { - KvnDeserializerErr::EmptyValue { keyword } + nom::Err::Error(KvnDateTimeParserErr::EmptyValue { input }) + | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { input }) => { + KvnDeserializerErr::EmptyValue { input } } nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound { expected }) | nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound { expected }) => { KvnDeserializerErr::KeywordNotFound { expected } } - nom::Err::Error(KvnDateTimeParserErr::InvalidFormat { keyword }) - | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { keyword }) => { - KvnDeserializerErr::InvalidDateTimeFormat { keyword } + nom::Err::Error(KvnDateTimeParserErr::InvalidFormat { input }) + | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { input }) => { + KvnDeserializerErr::InvalidDateTimeFormat { input } } nom::Err::Error(KvnDateTimeParserErr::ParserError(i, k)) | nom::Err::Failure(KvnDateTimeParserErr::ParserError(i, k)) => { @@ -105,17 +105,17 @@ impl From>> for KvnDeserializerErr { impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue { keyword }) - | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { keyword }) => { - KvnDeserializerErr::EmptyValue { keyword } + nom::Err::Error(KvnNumberLineParserErr::EmptyValue { input }) + | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { input }) => { + KvnDeserializerErr::EmptyValue { input } } nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) | nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) => { KvnDeserializerErr::KeywordNotFound { expected } } - nom::Err::Error(KvnNumberLineParserErr::InvalidFormat { keyword }) - | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword }) => { - KvnDeserializerErr::InvalidDateTimeFormat { keyword } + nom::Err::Error(KvnNumberLineParserErr::InvalidFormat { input }) + | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }) => { + KvnDeserializerErr::InvalidDateTimeFormat { input } } nom::Err::Error(KvnNumberLineParserErr::ParserError(i, k)) | nom::Err::Failure(KvnNumberLineParserErr::ParserError(i, k)) => { @@ -232,10 +232,7 @@ pub fn parse_kvn_string_line_new<'a>( .to_owned(); if value.len() == 0 { - //@TODO - return Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD", - })); + return Err(nom::Err::Failure(KvnParserErr::EmptyValue { input })); } Ok(("", KvnValue { value, unit: None })) @@ -250,8 +247,7 @@ where { if is_empty_value(input) { Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - //@TODO - keyword: "SCLK_OFFSET_AT_EPOCH", + input, }))? }; @@ -259,24 +255,19 @@ where let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$") .unwrap(); - // @TODO unwrap let captures = re.captures(input) .ok_or(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { - //@TODO - keyword: "SCLK_OFFSET_AT_EPOCH", + input, }))?; // @TODO unwrap let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); - let value = value.parse::().map_err(|_| { - nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { - //@TODO - keyword: "SCLK_OFFSET_AT_EPOCH", - }) - })?; + let value = value + .parse::() + .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }))?; Ok(("", KvnValue { value, unit })) } @@ -296,8 +287,7 @@ pub fn parse_kvn_numeric_line_new<'a>( ) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { if is_empty_value(input) { Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - //@TODO - keyword: "SCLK_OFFSET_AT_EPOCH", + input, }))? }; @@ -311,10 +301,8 @@ pub fn parse_kvn_numeric_line_new<'a>( let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); - let value = fast_float::parse(value).map_err(|_| { - //@TODO - nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { keyword: "blalala" }) - })?; + let value = fast_float::parse(value) + .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }))?; Ok(("", KvnValue { value, unit })) } @@ -324,8 +312,7 @@ pub fn parse_kvn_datetime_line_new<'a>( ) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { if is_empty_value(input) { Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { - //@TODO - keyword: "CREATION_DATE", + input, }))? }; @@ -335,8 +322,7 @@ pub fn parse_kvn_datetime_line_new<'a>( let captures = re.captures(input) .ok_or(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { - //@TODO - keyword: "CREATION_DATE", + input, }))?; // yr is a mandatory decimal in the regex so we expect the capture to be @@ -459,19 +445,19 @@ mod test { assert_eq!( parse_kvn_string_line_new("ASD = "), Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" + input: "ASD = " })) ); assert_eq!( parse_kvn_string_line_new("ASD = "), Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" + input: "ASD = " })) ); assert_eq!( parse_kvn_string_line_new("ASD ="), Err(nom::Err::Failure(KvnParserErr::EmptyValue { - keyword: "ASD" + input: "ASD =" })) ); @@ -619,14 +605,14 @@ mod test { assert_eq!( parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = -asd", true), Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { - keyword: "SCLK_OFFSET_AT_EPOCH" + input: "SCLK_OFFSET_AT_EPOCH = -asd" })) ); assert_eq!( parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = [s]", true), Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - keyword: "SCLK_OFFSET_AT_EPOCH" + input: "SCLK_OFFSET_AT_EPOCH = [s]" })) ); } @@ -708,21 +694,21 @@ mod test { assert_eq!( parse_kvn_datetime_line_new("CREATION_DATE = 2021,06,03Q05!33!00-123"), Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { - keyword: "CREATION_DATE" + input: "CREATION_DATE = 2021,06,03Q05!33!00-123" })) ); assert_eq!( parse_kvn_datetime_line_new("CREATION_DATE = asdffggg"), Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { - keyword: "CREATION_DATE" + input: "CREATION_DATE = asdffggg" })) ); assert_eq!( parse_kvn_datetime_line_new("CREATION_DATE = "), Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { - keyword: "CREATION_DATE" + input: "CREATION_DATE = " })) ); } From 16add1b488541dee7023b51021ef05d7fe31dea2 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 16:38:39 +0300 Subject: [PATCH 085/150] Implement InvalidFormat and EmptyKeyword detection --- crates/lox-utils/src/ndm/kvn/parser.rs | 120 ++++++++++++------------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index a9daac29..f5b6bcf8 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -18,9 +18,10 @@ pub type KvnStringValue = KvnValue; pub type KvnNumericValue = KvnValue; #[derive(Debug, PartialEq)] -pub enum KvnParserErr { - KeywordNotFound { expected: I }, +pub enum KvnStringParserErr { + EmptyKeyword { input: I }, EmptyValue { input: I }, + InvalidFormat { input: I }, ParserError(I, ErrorKind), } @@ -49,26 +50,32 @@ pub enum KvnDateTimeParserErr { pub enum KvnDeserializerErr { InvalidDateTimeFormat { input: I }, InvalidNumberFormat { input: I }, + InvalidStringFormat { input: I }, KeywordNotFound { expected: I }, UnexpectedKeyword { found: I, expected: I }, + EmptyKeyword { input: I }, EmptyValue { input: I }, UnexpectedEndOfInput { keyword: I }, GeneralParserError(I, ErrorKind), } -impl From>> for KvnDeserializerErr { - fn from(value: nom::Err>) -> Self { +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnParserErr::EmptyValue { input }) - | nom::Err::Failure(KvnParserErr::EmptyValue { input }) => { + nom::Err::Error(KvnStringParserErr::EmptyValue { input }) + | nom::Err::Failure(KvnStringParserErr::EmptyValue { input }) => { KvnDeserializerErr::EmptyValue { input } } - nom::Err::Error(KvnParserErr::KeywordNotFound { expected }) - | nom::Err::Failure(KvnParserErr::KeywordNotFound { expected }) => { - KvnDeserializerErr::KeywordNotFound { expected } + nom::Err::Error(KvnStringParserErr::EmptyKeyword { input }) + | nom::Err::Failure(KvnStringParserErr::EmptyKeyword { input }) => { + KvnDeserializerErr::EmptyKeyword { input } + } + nom::Err::Error(KvnStringParserErr::InvalidFormat { input }) + | nom::Err::Failure(KvnStringParserErr::InvalidFormat { input }) => { + KvnDeserializerErr::InvalidStringFormat { input } } - nom::Err::Error(KvnParserErr::ParserError(i, k)) - | nom::Err::Failure(KvnParserErr::ParserError(i, k)) => { + nom::Err::Error(KvnStringParserErr::ParserError(i, k)) + | nom::Err::Failure(KvnStringParserErr::ParserError(i, k)) => { KvnDeserializerErr::GeneralParserError(i, k) } // We don't use streaming deserialization @@ -137,9 +144,9 @@ impl From> for KvnDeserializerErr { } } -impl ParseError for KvnParserErr { +impl ParseError for KvnStringParserErr { fn from_error_kind(input: I, kind: ErrorKind) -> Self { - KvnParserErr::ParserError(input, kind) + KvnStringParserErr::ParserError(input, kind) } fn append(_: I, _: ErrorKind, other: Self) -> Self { @@ -199,7 +206,7 @@ pub fn kvn_line_matches_key_new<'a>( pub fn parse_kvn_string_line_new<'a>( input: &'a str, -) -> nom::IResult<&'a str, KvnStringValue, KvnParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnStringValue, KvnStringParserErr<&'a str>> { if input.trim_start().starts_with("COMMENT") { return Ok(( "", @@ -220,8 +227,25 @@ pub fn parse_kvn_string_line_new<'a>( Regex::new(r"^(?:\s*)(?[0-9A-Z_]*)(?:\s*)=(?:\s*)(?(?:(?:.*)))(?:\s*)$") .unwrap(); + let captures = + re.captures(input) + .ok_or(nom::Err::Failure(KvnStringParserErr::InvalidFormat { + input, + }))?; + // @TODO unwrap - let captures = re.captures(input).unwrap(); + let keyword = captures + .name("keyword") + .unwrap() + .as_str() + .trim_end() + .to_owned(); + + if keyword.len() == 0 { + return Err(nom::Err::Failure(KvnStringParserErr::EmptyKeyword { + input, + })); + } // @TODO unwrap let value = captures @@ -232,7 +256,7 @@ pub fn parse_kvn_string_line_new<'a>( .to_owned(); if value.len() == 0 { - return Err(nom::Err::Failure(KvnParserErr::EmptyValue { input })); + return Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input })); } Ok(("", KvnValue { value, unit: None })) @@ -444,23 +468,36 @@ mod test { ); assert_eq!( parse_kvn_string_line_new("ASD = "), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { + Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input: "ASD = " })) ); assert_eq!( parse_kvn_string_line_new("ASD = "), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { + Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input: "ASD = " })) ); assert_eq!( parse_kvn_string_line_new("ASD ="), - Err(nom::Err::Failure(KvnParserErr::EmptyValue { + Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input: "ASD =" })) ); + assert_eq!( + parse_kvn_string_line_new("ASD [km]"), + Err(nom::Err::Failure(KvnStringParserErr::InvalidFormat { + input: "ASD [km]" + })) + ); + assert_eq!( + parse_kvn_string_line_new(" = [km]"), + Err(nom::Err::Failure(KvnStringParserErr::EmptyKeyword { + input: " = [km]" + })) + ); + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. assert_eq!( parse_kvn_string_line_new("ASD = ASDFG "), @@ -473,51 +510,6 @@ mod test { )) ); - //@TODO move to numeric test - // a) there must be at least one blank character between the value and the units text; - // b) the units must be enclosed within square brackets (e.g., ‘[m]’); - // assert_eq!( - // parse_kvn_string_line_new("ASD = ASDFG [km]"), - // Ok(( - // "", - // KvnValue { - // value: "ASDFG".to_string(), - // unit: Some("km".to_string()) - // } - // )) - // ); - // assert_eq!( - // parse_kvn_string_line_new("ASD = ASDFG [km]"), - // Ok(( - // "", - // KvnValue { - // value: "ASDFG".to_string(), - // unit: Some("km".to_string()) - // } - // )) - // ); - - // assert_eq!( - // parse_kvn_string_line_new("ASD = [km]"), - // Err(nom::Err::Failure(KvnParserErr::EmptyValue { - // keyword: "ASD" - // })) - // ); - - // assert_eq!( - // parse_kvn_string_line_new("ASD [km]"), - // Err(nom::Err::Error(KvnParserErr::ParserError( - // "[km]", - // nom::error::ErrorKind::Char - // ))) - // ); - // assert_eq!( - // parse_kvn_string_line_new(" = [km]"), - // Err(nom::Err::Failure(KvnParserErr::KeywordNotFound { - // expected: "ASD" - // })) - // ); - // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. assert_eq!( parse_kvn_string_line_new(" ASD = ASDFG"), From e15c4e353334a181b198dfe70ccc60a5064882f8 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 17:24:13 +0300 Subject: [PATCH 086/150] Extend number tests --- crates/lox-utils/src/ndm/kvn/parser.rs | 248 ++++++++++++++++++++++--- 1 file changed, 221 insertions(+), 27 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index f5b6bcf8..87efb966 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -31,9 +31,9 @@ pub enum KvnKeyMatchErr { } #[derive(PartialEq, Debug)] -pub enum KvnNumberLineParserErr { +pub enum KvnNumberParserErr { ParserError(I, ErrorKind), - KeywordNotFound { expected: I }, + EmptyKeyword { input: I }, EmptyValue { input: I }, InvalidFormat { input: I }, } @@ -109,23 +109,23 @@ impl From>> for KvnDeserializerErr { } } -impl From>> for KvnDeserializerErr { - fn from(value: nom::Err>) -> Self { +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { match value { - nom::Err::Error(KvnNumberLineParserErr::EmptyValue { input }) - | nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { input }) => { + nom::Err::Error(KvnNumberParserErr::EmptyValue { input }) + | nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }) => { KvnDeserializerErr::EmptyValue { input } } - nom::Err::Error(KvnNumberLineParserErr::KeywordNotFound { expected }) - | nom::Err::Failure(KvnNumberLineParserErr::KeywordNotFound { expected }) => { - KvnDeserializerErr::KeywordNotFound { expected } + nom::Err::Error(KvnNumberParserErr::EmptyKeyword { input }) + | nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { input }) => { + KvnDeserializerErr::EmptyKeyword { input } } - nom::Err::Error(KvnNumberLineParserErr::InvalidFormat { input }) - | nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }) => { + nom::Err::Error(KvnNumberParserErr::InvalidFormat { input }) + | nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input }) => { KvnDeserializerErr::InvalidDateTimeFormat { input } } - nom::Err::Error(KvnNumberLineParserErr::ParserError(i, k)) - | nom::Err::Failure(KvnNumberLineParserErr::ParserError(i, k)) => { + nom::Err::Error(KvnNumberParserErr::ParserError(i, k)) + | nom::Err::Failure(KvnNumberParserErr::ParserError(i, k)) => { KvnDeserializerErr::GeneralParserError(i, k) } // We don't use streaming deserialization @@ -265,14 +265,12 @@ pub fn parse_kvn_string_line_new<'a>( pub fn parse_kvn_integer_line_new<'a, T>( input: &'a str, with_unit: bool, -) -> nom::IResult<&'a str, KvnValue, KvnNumberLineParserErr<&'a str>> +) -> nom::IResult<&'a str, KvnValue, KvnNumberParserErr<&'a str>> where T: std::str::FromStr, { if is_empty_value(input) { - Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - input, - }))? + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; // Modified from Figure F-9: CCSDS 502.0-B-3 @@ -281,17 +279,31 @@ where let captures = re.captures(input) - .ok_or(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + .ok_or(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input, }))?; + // @TODO unwrap + let keyword = captures + .name("keyword") + .unwrap() + .as_str() + .trim_end() + .to_owned(); + + if keyword.len() == 0 { + return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { + input, + })); + } + // @TODO unwrap let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); let value = value .parse::() - .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }))?; + .map_err(|_| nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input }))?; Ok(("", KvnValue { value, unit })) } @@ -308,25 +320,40 @@ fn is_empty_value(input: &str) -> bool { pub fn parse_kvn_numeric_line_new<'a>( input: &'a str, with_unit: bool, -) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberLineParserErr<&'a str>> { +) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberParserErr<&'a str>> { if is_empty_value(input) { - Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { - input, - }))? + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; // Figure F-9: CCSDS 502.0-B-3 let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?(?:[eE][+-]?(?:\d+))?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$").unwrap(); + let captures = + re.captures(input) + .ok_or(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { + input, + }))?; + // @TODO unwrap - let captures = re.captures(input).unwrap(); + let keyword = captures + .name("keyword") + .unwrap() + .as_str() + .trim_end() + .to_owned(); + + if keyword.len() == 0 { + return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { + input, + })); + } // @TODO unwrap let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); let value = fast_float::parse(value) - .map_err(|_| nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { input }))?; + .map_err(|_| nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input }))?; Ok(("", KvnValue { value, unit })) } @@ -550,6 +577,8 @@ mod test { #[test] fn test_parse_kvn_integer_line_new() { + // a) there must be at least one blank character between the value and the units text; + // b) the units must be enclosed within square brackets (e.g., ‘[m]’); assert_eq!( parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", true), Ok(( @@ -561,6 +590,43 @@ mod test { )) ); + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", true), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + } + )) + ); + + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 ", false), + Ok(( + "", + KvnValue { + value: 28800, + unit: None + } + )) + ); + + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + + assert_eq!( + parse_kvn_integer_line_new(" SCLK_OFFSET_AT_EPOCH = 28800", false), + Ok(( + "", + KvnValue { + value: 28800, + unit: None + } + )) + ); + assert_eq!( parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 00028800 [s]", true), Ok(( @@ -594,23 +660,68 @@ mod test { )) ); + assert_eq!( + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", false), + Ok(( + "", + KvnValue { + value: 28800, + unit: Some("s".to_string()) + }, + )) + ); + assert_eq!( parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = -asd", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::InvalidFormat { + Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input: "SCLK_OFFSET_AT_EPOCH = -asd" })) ); assert_eq!( parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = [s]", true), - Err(nom::Err::Failure(KvnNumberLineParserErr::EmptyValue { + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input: "SCLK_OFFSET_AT_EPOCH = [s]" })) ); + + assert_eq!( + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = ", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "SCLK_OFFSET_AT_EPOCH = " + })) + ); + assert_eq!( + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = ", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "SCLK_OFFSET_AT_EPOCH = " + })) + ); + assert_eq!( + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH =", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "SCLK_OFFSET_AT_EPOCH =" + })) + ); + + assert_eq!( + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH [km]", true), + Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { + input: "SCLK_OFFSET_AT_EPOCH [km]" + })) + ); + assert_eq!( + parse_kvn_integer_line_new::(" = 123 [km]", true), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { + input: " = 123 [km]" + })) + ); } #[test] fn test_parse_kvn_numeric_line_new() { + // a) there must be at least one blank character between the value and the units text; + // b) the units must be enclosed within square brackets (e.g., ‘[m]’); assert_eq!( parse_kvn_numeric_line_new("X = 66559942 [km]", true), Ok(( @@ -622,6 +733,43 @@ mod test { )) ); + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + + assert_eq!( + parse_kvn_numeric_line_new("X = 66559942 [km]", true), + Ok(( + "", + KvnValue { + value: 66559942f64, + unit: Some("km".to_string()) + } + )) + ); + + assert_eq!( + parse_kvn_numeric_line_new("X = 66559942 ", false), + Ok(( + "", + KvnValue { + value: 66559942f64, + unit: None + } + )) + ); + + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + + assert_eq!( + parse_kvn_numeric_line_new(" X = 66559942", false), + Ok(( + "", + KvnValue { + value: 66559942f64, + unit: None + } + )) + ); + assert_eq!( parse_kvn_numeric_line_new("X = 6655.9942 [km]", true), Ok(( @@ -643,6 +791,52 @@ mod test { }, )) ); + + assert_eq!( + parse_kvn_numeric_line_new("X = -asd", true), + Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { + input: "X = -asd" + })) + ); + + assert_eq!( + parse_kvn_numeric_line_new("X = [s]", true), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "X = [s]" + })) + ); + + assert_eq!( + parse_kvn_numeric_line_new("X = ", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "X = " + })) + ); + assert_eq!( + parse_kvn_numeric_line_new("X = ", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "X = " + })) + ); + assert_eq!( + parse_kvn_numeric_line_new("X =", false), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { + input: "X =" + })) + ); + + assert_eq!( + parse_kvn_numeric_line_new("X [km]", true), + Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { + input: "X [km]" + })) + ); + assert_eq!( + parse_kvn_numeric_line_new(" = 123 [km]", true), + Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { + input: " = 123 [km]" + })) + ); } #[test] From ddd0eaf21c29e494d57c961900ec85da49acc7cc Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 17:26:14 +0300 Subject: [PATCH 087/150] Add empty value check for string --- crates/lox-utils/src/ndm/kvn/parser.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 87efb966..e4de61e0 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -221,6 +221,10 @@ pub fn parse_kvn_string_line_new<'a>( )); } + if is_empty_value(input) { + Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input }))? + }; + // Inspired by figure F-8: CCSDS 502.0-B-3, but accepts a more relaxed input. Orekit seems to suggest that there // are quite a few messages being used which are not strictly compliant. let re = @@ -519,9 +523,9 @@ mod test { })) ); assert_eq!( - parse_kvn_string_line_new(" = [km]"), + parse_kvn_string_line_new(" = asd [km]"), Err(nom::Err::Failure(KvnStringParserErr::EmptyKeyword { - input: " = [km]" + input: " = asd [km]" })) ); From cf0d4a9959c5411a8eee5a3a699d3ba5d65357da Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 18:05:30 +0300 Subject: [PATCH 088/150] Expand datetime test --- crates/lox-utils/src/ndm/kvn/parser.rs | 87 ++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index e4de61e0..4663d54f 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -41,7 +41,7 @@ pub enum KvnNumberParserErr { #[derive(PartialEq, Debug)] pub enum KvnDateTimeParserErr { ParserError(I, ErrorKind), - KeywordNotFound { expected: I }, + EmptyKeyword { input: I }, EmptyValue { input: I }, InvalidFormat { input: I }, } @@ -91,9 +91,9 @@ impl From>> for KvnDeserializerErr { | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { input }) => { KvnDeserializerErr::EmptyValue { input } } - nom::Err::Error(KvnDateTimeParserErr::KeywordNotFound { expected }) - | nom::Err::Failure(KvnDateTimeParserErr::KeywordNotFound { expected }) => { - KvnDeserializerErr::KeywordNotFound { expected } + nom::Err::Error(KvnDateTimeParserErr::EmptyKeyword { input }) + | nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { input }) => { + KvnDeserializerErr::EmptyKeyword { input } } nom::Err::Error(KvnDateTimeParserErr::InvalidFormat { input }) | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { input }) => { @@ -380,6 +380,20 @@ pub fn parse_kvn_datetime_line_new<'a>( input, }))?; + // @TODO unwrap + let keyword = captures + .name("keyword") + .unwrap() + .as_str() + .trim_end() + .to_owned(); + + if keyword.len() == 0 { + return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { + input, + })); + } + // yr is a mandatory decimal in the regex so we expect the capture to be // always there and unwrap is fine let year = captures @@ -879,6 +893,44 @@ mod test { )) ); + // 7.4.7 Any white space immediately preceding the end of line shall not be significant. + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = 2021-06-03T05:33:01 "), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 1, + fractional_second: 0.0, + full_value: "2021-06-03T05:33:01".to_string(), + }, + )) + ); + + // 7.4.5 Any white space immediately preceding or following the keyword shall not be significant. + + assert_eq!( + parse_kvn_datetime_line_new(" CREATION_DATE = 2021-06-03T05:33:01"), + Ok(( + "", + KvnDateTimeValue { + year: 2021, + month: 6, + day: 3, + hour: 5, + minute: 33, + second: 1, + fractional_second: 0.0, + full_value: "2021-06-03T05:33:01".to_string(), + }, + )) + ); + // @TODO add support for ddd format assert_eq!( @@ -901,6 +953,33 @@ mod test { input: "CREATION_DATE = " })) ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE = "), + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + input: "CREATION_DATE = " + })) + ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE ="), + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { + input: "CREATION_DATE =" + })) + ); + + assert_eq!( + parse_kvn_datetime_line_new("CREATION_DATE "), + Err(nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { + input: "CREATION_DATE " + })) + ); + assert_eq!( + parse_kvn_datetime_line_new(" = 2021-06-03T05:33:01"), + Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { + input: " = 2021-06-03T05:33:01" + })) + ); } #[derive(Default, Debug, PartialEq)] From a138c263381743d430ecd153db1de9ffa0cbdc23 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 18:11:55 +0300 Subject: [PATCH 089/150] Remove todo from fixed test --- crates/lox-utils/src/ndm/kvn/parser.rs | 2 -- crates/lox_derive/src/lib.rs | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 4663d54f..88dff3bb 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -465,8 +465,6 @@ mod test { ); assert_eq!(kvn_line_matches_key_new("ASD", "ASD = ASDFG"), Ok(true)); - // 7.4.4 Keywords must be uppercase and must not contain blanks - // @TODO assert_eq!( kvn_line_matches_key_new("ASD", "ASD ASD = ASDFG"), Ok(false) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 33772140..adb06ad7 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -515,6 +515,7 @@ let field_name = field.ident.as_ref().unwrap(); // Unwrap is okay because we only support named structs + // 7.4.4 Keywords must be uppercase and must not contain blanks let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); // Unwrap is okay because we expect this span to come from the source code From d9d11b87cf528f2fd2177c986e6fc45bee88b26f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 18:13:17 +0300 Subject: [PATCH 090/150] Fix formatting --- crates/lox_derive/src/lib.rs | 1333 +++++++++++++++++----------------- 1 file changed, 666 insertions(+), 667 deletions(-) diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index adb06ad7..0bfe0e00 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -6,680 +6,679 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ - use proc_macro2::Span; - use quote::quote; - use syn::{spanned::Spanned, DeriveInput, Field}; - - fn generate_call_to_deserializer_for_kvn_type( - type_name: &str, - type_name_new: &syn::Path, - expected_kvn_name: &str, - ) -> Result { - match type_name { - "f64" | "String" | "i32" | "u64" => { - let parser = match type_name { - "String" => quote! { - crate::ndm::kvn::parser::parse_kvn_string_line_new( - next_line - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "f64" => quote! { - crate::ndm::kvn::parser::parse_kvn_numeric_line_new( - next_line, - true, //@TODO - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "i32" | "u64" => quote! { - crate::ndm::kvn::parser::parse_kvn_integer_line_new( - next_line, - true, //@TODO - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - // Assumes the match list here exhaustively matches the one from above - _ => unreachable!(), - }; - - Ok(quote! { - match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name - }), - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( - #expected_kvn_name, - next_line, - )?; - - let result = if line_matches { - let next_line = lines.next().unwrap(); - - Ok(#parser.value) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, - }) - }; - - result - } - } - }) - } - - "KvnNumericValue" | "KvnStringValue" | "KvnIntegerValue" => { - let parser = match type_name { - "KvnStringValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_string_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "KvnNumericValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_numeric_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "KvnIntegerValue" => quote! { - crate::ndm::kvn::parser::parse_kvn_integer_line( - #expected_kvn_name, - next_line, - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - // Assumes the match list here exhaustively matches the one from above - _ => unreachable!(), - }; - - Ok(quote! { - match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name - }), - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( - #expected_kvn_name, - next_line, - )?; - - let result = if line_matches { - let next_line = lines.next().unwrap(); - - Ok(#parser) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, - }) - }; - - result - } - } - }) - } - - type_value => Ok(quote! { - { - let has_next_line = lines.peek().is_some(); - - let result = if has_next_line { - #type_name_new::deserialize(lines) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: #expected_kvn_name - }) - }; - - result - } - }), - } - } - - //@TODO unify with above - fn generate_call_to_deserializer_for_kvn_type_new( - type_name: &str, - type_name_new: &syn::Path, - ) -> Result { - match type_name { - "f64" | "String" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { - let parser = match type_name { - "String" => { - quote! { - crate::ndm::kvn::parser::parse_kvn_string_line_new( - lines.next().unwrap() - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - } - }, - "f64" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => quote! { - crate::ndm::kvn::parser::parse_kvn_numeric_line_new( - lines.next().unwrap(), - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - "i32" => quote! { - crate::ndm::kvn::parser::parse_kvn_integer_line_new( - lines.next().unwrap(), - true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) - .map(|x| x.1)? - }, - // Assumes the match list here exhaustively matches the one from above - _ => unreachable!(), - }; - - Ok(parser) - } - type_value => { - Ok(quote! { - { - let has_next_line = lines.peek().is_some(); - - let result = if has_next_line { - #type_name_new::deserialize(lines) - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: "Blala" //@TODO - }) - }; - - result - } - }) - } - } - } - - fn get_generic_type_argument(field: &Field) -> Option { - if let syn::Type::Path(type_path) = &field.ty { - let path_part = type_path.path.segments.first(); - if let Some(path_part) = path_part { - if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - return Some( - type_argument - .args - .first() - .unwrap() - .span() - .source_text() - .unwrap(), - ); - } - } - } - - None - } - - fn get_generic_type_argument_new(field: &Field) -> Option<&syn::Path> { - if let syn::Type::Path(type_path) = &field.ty { - let path_part = type_path.path.segments.first(); - if let Some(path_part) = path_part { - if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - if let Some(syn::GenericArgument::Type(r#type)) = &type_argument.args.first() { - return extract_type_path(r#type); - } - } - } - } - - None - } - - fn generate_call_to_deserializer_for_option_type( - expected_kvn_name: &str, - field: &Field, - ) -> Result { - let type_name = get_generic_type_argument(field); - - // @TODO - let type_name_new = get_generic_type_argument_new(field).unwrap(); - - match type_name { - None => { - return Err(syn::Error::new_spanned( - &field, - "Malformed type for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into()) - } - - Some(type_name) => { - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &type_name_new, - &expected_kvn_name, - )?; - - let condition_shortcut = match type_name.as_str() { - "String" | "f64" | "i32" | "u64" => quote! {}, - _ => quote! { ! #type_name_new::should_check_key_match() || }, - }; - - return Ok(quote! { - match lines.peek() { - None => None, - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( - #expected_kvn_name, - next_line, - )?; - - if #condition_shortcut line_matches { - let result = #deserializer_for_kvn_type; - - match result { - Ok(item) => Some(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, - Err(e) => Err(e)?, - } - } else { - None - } - } - } - }); - } - } - } - - fn generate_call_to_deserializer_for_vec_type( - expected_kvn_name: &str, - field: &Field, - ) -> Result { - if let syn::Type::Path(type_path) = &field.ty { - let path_part = type_path.path.segments.first(); - if let Some(path_part) = path_part { - if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { - let type_name = type_argument - .args - .first() - .unwrap() - .span() - .source_text() - .unwrap(); - - //@TODO - let bla = get_generic_type_argument_new(field).unwrap(); - - let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); - - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &bla, - &expected_kvn_name, - )?; - - let type_ident = syn::Ident::new(&type_name, Span::call_site()); - - return Ok(quote! { - { - let mut items: Vec<#type_ident> = Vec::new(); - - loop { - let result = #deserializer_for_kvn_type; - - match result { - Ok(item) => items.push(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, - Err(e) => Err(e)?, - } - } - - items - } - }); - } - } - } - - return Err( - syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") - .into_compile_error() - .into(), - ); - } - - fn is_value_unit_struct(item: &DeriveInput) -> bool { - for attr in item.attrs.iter() { - if attr.path().is_ident("kvn") { - if attr - .parse_nested_meta(|meta| { - if meta.path.is_ident("value_unit_struct") { - Ok(()) - } else { - Err(meta.error("unsupported attribute")) - } - }) - .is_ok() - { - return true; - } - } - } - - false - } - - fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> { - match *ty { - syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path), - _ => None, - } - } - - fn deserializer_for_struct_with_named_fields( - type_name: &proc_macro2::Ident, - fields: &syn::punctuated::Punctuated, - is_value_unit_struct: bool, - ) -> proc_macro2::TokenStream { - if type_name.to_string() == "UserDefinedType" { - //@TODO - return quote! { - Ok(Default::default()) - }; - } - - if is_value_unit_struct { - let mut deserializer = None; - let mut unit_type: Option = None; - let mut unit_field_name_ident: Option<&proc_macro2::Ident> = None; - let mut field_type: Option = None; - let mut field_type_new: Option<&syn::Path> = None; - - for (index, field) in fields.iter().enumerate() { - let field_name_ident = field.ident.as_ref().unwrap(); - - // Unwrap is okay because we only support named structs - let field_name = field_name_ident.span().source_text().unwrap(); - - match index { - 0 => { - if field_name.as_str() != "base" { - return syn::Error::new_spanned( - &field, - "The first field in a value unit struct should be called \"base\"", - ) - .into_compile_error() - .into(); - } - - // Unwrap is okay because we expect this span to come from the source code - let local_field_type = extract_type_path(&field.ty) - .unwrap() - .span() - .source_text() - .unwrap(); - let local_field_type_new = extract_type_path(&field.ty).unwrap(); - - let deserializer = match local_field_type.as_str() { - "KvnDateTimeValue" | "String" | "f64" | "i32" | "NonNegativeDouble" - | "NegativeDouble" | "PositiveDouble" => { - match generate_call_to_deserializer_for_kvn_type_new( - &local_field_type, - &local_field_type_new, - ) { - Ok(deserializer_for_kvn_type) => { - deserializer = Some(deserializer_for_kvn_type) - } - Err(e) => return e.into(), - } - } - - _ => { - return syn::Error::new_spanned( - &field, - "Unsupported field type for deserializer", - ) - .into_compile_error() - .into() - } - }; - - field_type = Some(local_field_type); - field_type_new = Some(local_field_type_new); - - deserializer - } - 1 => { - if field_name.as_str() != "units" && field_name.as_str() != "parameter" { - return syn::Error::new_spanned( +use proc_macro2::Span; +use quote::quote; +use syn::{spanned::Spanned, DeriveInput, Field}; + +fn generate_call_to_deserializer_for_kvn_type( + type_name: &str, + type_name_new: &syn::Path, + expected_kvn_name: &str, +) -> Result { + match type_name { + "f64" | "String" | "i32" | "u64" => { + let parser = match type_name { + "String" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line_new( + next_line + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "f64" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line_new( + next_line, + true, //@TODO + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "i32" | "u64" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line_new( + next_line, + true, //@TODO + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }), + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + let result = if line_matches { + let next_line = lines.next().unwrap(); + + Ok(#parser.value) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }) + }; + + result + } + } + }) + } + + "KvnNumericValue" | "KvnStringValue" | "KvnIntegerValue" => { + let parser = match type_name { + "KvnStringValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_string_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnNumericValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "KvnIntegerValue" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line( + #expected_kvn_name, + next_line, + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }), + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + let result = if line_matches { + let next_line = lines.next().unwrap(); + + Ok(#parser) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + }) + }; + + result + } + } + }) + } + + type_value => Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_name_new::deserialize(lines) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: #expected_kvn_name + }) + }; + + result + } + }), + } +} + +//@TODO unify with above +fn generate_call_to_deserializer_for_kvn_type_new( + type_name: &str, + type_name_new: &syn::Path, +) -> Result { + match type_name { + "f64" | "String" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { + let parser = match type_name { + "String" => { + quote! { + crate::ndm::kvn::parser::parse_kvn_string_line_new( + lines.next().unwrap() + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + } + } + "f64" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => quote! { + crate::ndm::kvn::parser::parse_kvn_numeric_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + "i32" => quote! { + crate::ndm::kvn::parser::parse_kvn_integer_line_new( + lines.next().unwrap(), + true + ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + .map(|x| x.1)? + }, + // Assumes the match list here exhaustively matches the one from above + _ => unreachable!(), + }; + + Ok(parser) + } + type_value => { + Ok(quote! { + { + let has_next_line = lines.peek().is_some(); + + let result = if has_next_line { + #type_name_new::deserialize(lines) + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + keyword: "Blala" //@TODO + }) + }; + + result + } + }) + } + } +} + +fn get_generic_type_argument(field: &Field) -> Option { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + return Some( + type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(), + ); + } + } + } + + None +} + +fn get_generic_type_argument_new(field: &Field) -> Option<&syn::Path> { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + if let Some(syn::GenericArgument::Type(r#type)) = &type_argument.args.first() { + return extract_type_path(r#type); + } + } + } + } + + None +} + +fn generate_call_to_deserializer_for_option_type( + expected_kvn_name: &str, + field: &Field, +) -> Result { + let type_name = get_generic_type_argument(field); + + // @TODO + let type_name_new = get_generic_type_argument_new(field).unwrap(); + + match type_name { + None => { + return Err(syn::Error::new_spanned( + &field, + "Malformed type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()) + } + + Some(type_name) => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &type_name_new, + &expected_kvn_name, + )?; + + let condition_shortcut = match type_name.as_str() { + "String" | "f64" | "i32" | "u64" => quote! {}, + _ => quote! { ! #type_name_new::should_check_key_match() || }, + }; + + return Ok(quote! { + match lines.peek() { + None => None, + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + if #condition_shortcut line_matches { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => Some(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, + Err(e) => Err(e)?, + } + } else { + None + } + } + } + }); + } + } +} + +fn generate_call_to_deserializer_for_vec_type( + expected_kvn_name: &str, + field: &Field, +) -> Result { + if let syn::Type::Path(type_path) = &field.ty { + let path_part = type_path.path.segments.first(); + if let Some(path_part) = path_part { + if let syn::PathArguments::AngleBracketed(type_argument) = &path_part.arguments { + let type_name = type_argument + .args + .first() + .unwrap() + .span() + .source_text() + .unwrap(); + + //@TODO + let bla = get_generic_type_argument_new(field).unwrap(); + + let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); + + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &type_name.as_ref(), + &bla, + &expected_kvn_name, + )?; + + let type_ident = syn::Ident::new(&type_name, Span::call_site()); + + return Ok(quote! { + { + let mut items: Vec<#type_ident> = Vec::new(); + + loop { + let result = #deserializer_for_kvn_type; + + match result { + Ok(item) => items.push(item), + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, + Err(e) => Err(e)?, + } + } + + items + } + }); + } + } + } + + return Err( + syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + .into_compile_error() + .into(), + ); +} + +fn is_value_unit_struct(item: &DeriveInput) -> bool { + for attr in item.attrs.iter() { + if attr.path().is_ident("kvn") { + if attr + .parse_nested_meta(|meta| { + if meta.path.is_ident("value_unit_struct") { + Ok(()) + } else { + Err(meta.error("unsupported attribute")) + } + }) + .is_ok() + { + return true; + } + } + } + + false +} + +fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> { + match *ty { + syn::Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path), + _ => None, + } +} + +fn deserializer_for_struct_with_named_fields( + type_name: &proc_macro2::Ident, + fields: &syn::punctuated::Punctuated, + is_value_unit_struct: bool, +) -> proc_macro2::TokenStream { + if type_name.to_string() == "UserDefinedType" { + //@TODO + return quote! { + Ok(Default::default()) + }; + } + + if is_value_unit_struct { + let mut deserializer = None; + let mut unit_type: Option = None; + let mut unit_field_name_ident: Option<&proc_macro2::Ident> = None; + let mut field_type: Option = None; + let mut field_type_new: Option<&syn::Path> = None; + + for (index, field) in fields.iter().enumerate() { + let field_name_ident = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + let field_name = field_name_ident.span().source_text().unwrap(); + + match index { + 0 => { + if field_name.as_str() != "base" { + return syn::Error::new_spanned( + &field, + "The first field in a value unit struct should be called \"base\"", + ) + .into_compile_error() + .into(); + } + + // Unwrap is okay because we expect this span to come from the source code + let local_field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let local_field_type_new = extract_type_path(&field.ty).unwrap(); + + let deserializer = match local_field_type.as_str() { + "KvnDateTimeValue" | "String" | "f64" | "i32" | "NonNegativeDouble" + | "NegativeDouble" | "PositiveDouble" => { + match generate_call_to_deserializer_for_kvn_type_new( + &local_field_type, + &local_field_type_new, + ) { + Ok(deserializer_for_kvn_type) => { + deserializer = Some(deserializer_for_kvn_type) + } + Err(e) => return e.into(), + } + } + + _ => { + return syn::Error::new_spanned( + &field, + "Unsupported field type for deserializer", + ) + .into_compile_error() + .into() + } + }; + + field_type = Some(local_field_type); + field_type_new = Some(local_field_type_new); + + deserializer + } + 1 => { + if field_name.as_str() != "units" && field_name.as_str() != "parameter" { + return syn::Error::new_spanned( &field, "The second field in a value unit struct should be called \"units\" or \"parameter\"", ) .into_compile_error() .into(); - } - - unit_type = get_generic_type_argument(field); - unit_field_name_ident = Some(field_name_ident); - } - _ => { - return syn::Error::new_spanned( - &field, - "Only two fields are allowed: \"base\" and (\"units\" or \"parameters\"", - ) - .into_compile_error() - .into() - } - } - } - - // This unwrap is okay because we know the field exists. If it didn't exist we would've thrown an error. - let unit_type = unit_type.unwrap(); - let unit_field_name_ident = unit_field_name_ident.unwrap(); - let field_type = field_type.unwrap(); - let field_type_new = field_type_new.unwrap(); - - let unit_type_ident = syn::Ident::new(&unit_type, Span::call_site()); - - let base = match field_type.as_str() { - "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { - quote! { #field_type_new (kvn_value.value) } - } - _ => quote! { kvn_value.value }, - }; - - match deserializer { - None => syn::Error::new_spanned(&fields, "Unable to create deserializer for struct") - .into_compile_error() - .into(), - Some(deserializer) => quote! { - let kvn_value = #deserializer; - Ok(#type_name { - base: #base, - #unit_field_name_ident: kvn_value.unit.map(|unit| #unit_type_ident (unit)), - }) - }, - } - } else { - let field_deserializers: Result, _> = fields + } + + unit_type = get_generic_type_argument(field); + unit_field_name_ident = Some(field_name_ident); + } + _ => { + return syn::Error::new_spanned( + &field, + "Only two fields are allowed: \"base\" and (\"units\" or \"parameters\"", + ) + .into_compile_error() + .into() + } + } + } + + // This unwrap is okay because we know the field exists. If it didn't exist we would've thrown an error. + let unit_type = unit_type.unwrap(); + let unit_field_name_ident = unit_field_name_ident.unwrap(); + let field_type = field_type.unwrap(); + let field_type_new = field_type_new.unwrap(); + + let unit_type_ident = syn::Ident::new(&unit_type, Span::call_site()); + + let base = match field_type.as_str() { + "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { + quote! { #field_type_new (kvn_value.value) } + } + _ => quote! { kvn_value.value }, + }; + + match deserializer { + None => syn::Error::new_spanned(&fields, "Unable to create deserializer for struct") + .into_compile_error() + .into(), + Some(deserializer) => quote! { + let kvn_value = #deserializer; + Ok(#type_name { + base: #base, + #unit_field_name_ident: kvn_value.unit.map(|unit| #unit_type_ident (unit)), + }) + }, + } + } else { + let field_deserializers: Result, _> = fields .iter() .enumerate() .map(|(_, field)| { - let field_name = field.ident.as_ref().unwrap(); - - // Unwrap is okay because we only support named structs - // 7.4.4 Keywords must be uppercase and must not contain blanks - let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); - - // Unwrap is okay because we expect this span to come from the source code - let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); - let field_type_new = extract_type_path(&field.ty).unwrap(); - - let parser = match field_type.as_str() { - "EpochType" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { - let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &field_type, - field_type_new, - &expected_kvn_name, - )?; - - quote! { - #deserializer_for_kvn_type? - } - } - "Option" => { - generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? - } - "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, - _ => { - - let condition_shortcut = match field_type.as_str() { - "String" => quote! {}, - _ => quote! { ! #field_type_new::should_check_key_match() || }, - }; - - quote! { - match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name - })?, - Some(next_line) => { - let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( - #expected_kvn_name, - next_line, - )?; - - if #condition_shortcut line_matches { - #field_type_new::deserialize(lines)? - } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, - })? - } - } - } - } - } - }; - - Ok(quote! { - #field_name: #parser, - }) + let field_name = field.ident.as_ref().unwrap(); + + // Unwrap is okay because we only support named structs + // 7.4.4 Keywords must be uppercase and must not contain blanks + let expected_kvn_name = field_name.span().source_text().unwrap().to_uppercase(); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + let parser = match field_type.as_str() { + "EpochType" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { + let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( + &field_type, + field_type_new, + &expected_kvn_name, + )?; + + quote! { + #deserializer_for_kvn_type? + } + } + "Option" => { + generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? + } + "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, + _ => { + + let condition_shortcut = match field_type.as_str() { + "String" => quote! {}, + _ => quote! { ! #field_type_new::should_check_key_match() || }, + }; + + quote! { + match lines.peek() { + None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + keyword: #expected_kvn_name + })?, + Some(next_line) => { + let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( + #expected_kvn_name, + next_line, + )?; + + if #condition_shortcut line_matches { + #field_type_new::deserialize(lines)? + } else { + Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + found: next_line, + expected: #expected_kvn_name, + })? + } + } + } + } + } + }; + + Ok(quote! { + #field_name: #parser, + }) }) .collect(); - - if let Err(e) = field_deserializers { - return e; - } - - let field_deserializers = field_deserializers.unwrap(); - - quote! { - Ok(#type_name { - #(#field_deserializers)* - }) - } - } - } - - fn deserializers_for_struct_with_unnamed_fields( - type_name: &proc_macro2::Ident, - fields: &syn::punctuated::Punctuated, - ) -> proc_macro2::TokenStream { - let field_deserializers: Result, _> = fields - .iter() - .enumerate() - .map(|(_, field)| { - // Unwrap is okay because we expect this span to come from the source code - let field_type = extract_type_path(&field.ty) - .unwrap() - .span() - .source_text() - .unwrap(); - let field_type_new = extract_type_path(&field.ty).unwrap(); - - let deserializer_for_kvn_type = - generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new)?; - - Ok(quote! { - #deserializer_for_kvn_type.value, - }) - }) - .collect(); - - if let Err(e) = field_deserializers { - return e; - } - - let field_deserializers = field_deserializers.unwrap(); - - quote! { - Ok(#type_name ( - #(#field_deserializers)* - )) - } - } - - #[proc_macro_derive(KvnDeserialize, attributes(kvn))] - pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { - let item = syn::parse_macro_input!(item as syn::DeriveInput); - let type_name = &item.ident; - let is_value_unit_struct = is_value_unit_struct(&item); - - let syn::Data::Struct(strukt) = item.data else { - return syn::Error::new_spanned( - &item, - "only structs are supported for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into(); - }; - - let (struct_deserializer, should_check_key_match) = match strukt.fields { - syn::Fields::Named(syn::FieldsNamed { named, .. }) => ( - deserializer_for_struct_with_named_fields(type_name, &named, is_value_unit_struct), - is_value_unit_struct, - ), - syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => ( - deserializers_for_struct_with_unnamed_fields(type_name, &unnamed), - true, - ), - _ => { - return syn::Error::new_spanned( - &strukt.fields, - "only named fields are supported for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into() - } - }; - - let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); - - let struct_deserializer = quote! { - impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #type_name #type_generics - #where_clause - { - fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) - -> Result<#type_name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { - - #struct_deserializer - } - - fn should_check_key_match () -> bool { - #should_check_key_match - } - } - }; - - struct_deserializer.into() - } - \ No newline at end of file + + if let Err(e) = field_deserializers { + return e; + } + + let field_deserializers = field_deserializers.unwrap(); + + quote! { + Ok(#type_name { + #(#field_deserializers)* + }) + } + } +} + +fn deserializers_for_struct_with_unnamed_fields( + type_name: &proc_macro2::Ident, + fields: &syn::punctuated::Punctuated, +) -> proc_macro2::TokenStream { + let field_deserializers: Result, _> = fields + .iter() + .enumerate() + .map(|(_, field)| { + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + let deserializer_for_kvn_type = + generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new)?; + + Ok(quote! { + #deserializer_for_kvn_type.value, + }) + }) + .collect(); + + if let Err(e) = field_deserializers { + return e; + } + + let field_deserializers = field_deserializers.unwrap(); + + quote! { + Ok(#type_name ( + #(#field_deserializers)* + )) + } +} + +#[proc_macro_derive(KvnDeserialize, attributes(kvn))] +pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + let item = syn::parse_macro_input!(item as syn::DeriveInput); + let type_name = &item.ident; + let is_value_unit_struct = is_value_unit_struct(&item); + + let syn::Data::Struct(strukt) = item.data else { + return syn::Error::new_spanned( + &item, + "only structs are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into(); + }; + + let (struct_deserializer, should_check_key_match) = match strukt.fields { + syn::Fields::Named(syn::FieldsNamed { named, .. }) => ( + deserializer_for_struct_with_named_fields(type_name, &named, is_value_unit_struct), + is_value_unit_struct, + ), + syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => ( + deserializers_for_struct_with_unnamed_fields(type_name, &unnamed), + true, + ), + _ => { + return syn::Error::new_spanned( + &strukt.fields, + "only named fields are supported for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into() + } + }; + + let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); + + let struct_deserializer = quote! { + impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #type_name #type_generics + #where_clause + { + fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) + -> Result<#type_name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { + + #struct_deserializer + } + + fn should_check_key_match () -> bool { + #should_check_key_match + } + } + }; + + struct_deserializer.into() +} From 1664f59cde6c570b35bf2aa49f4131b0cc82149f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 18:28:01 +0300 Subject: [PATCH 091/150] Clean-up todos --- crates/lox-utils/src/ndm/kvn/parser.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 88dff3bb..7757b8ed 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -237,9 +237,9 @@ pub fn parse_kvn_string_line_new<'a>( input, }))?; - // @TODO unwrap let keyword = captures .name("keyword") + // This unwrap is okay because the keyword uses * so it will always capture .unwrap() .as_str() .trim_end() @@ -251,9 +251,9 @@ pub fn parse_kvn_string_line_new<'a>( })); } - // @TODO unwrap let value = captures .name("value") + // This unwrap is okay because the value uses * so it will always capture .unwrap() .as_str() .trim_end() @@ -287,9 +287,9 @@ where input, }))?; - // @TODO unwrap let keyword = captures .name("keyword") + // This unwrap is okay because the keyword is marked as * so it will always capture .unwrap() .as_str() .trim_end() @@ -301,7 +301,7 @@ where })); } - // @TODO unwrap + // This unwrap is okay because the value uses * so it will always capture let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); @@ -338,9 +338,9 @@ pub fn parse_kvn_numeric_line_new<'a>( input, }))?; - // @TODO unwrap let keyword = captures .name("keyword") + // This unwrap is okay because the keyword is marked as * so it will always capture .unwrap() .as_str() .trim_end() @@ -352,7 +352,7 @@ pub fn parse_kvn_numeric_line_new<'a>( })); } - // @TODO unwrap + // This unwrap is okay because the value uses * so it will always capture let value = captures.name("value").unwrap().as_str(); let unit = captures.name("unit").map(|x| x.as_str().to_owned()); @@ -380,8 +380,8 @@ pub fn parse_kvn_datetime_line_new<'a>( input, }))?; - // @TODO unwrap let keyword = captures + // This unwrap is okay because the keyword is marked as * so it will always capture .name("keyword") .unwrap() .as_str() From 04c98220921ead161efd08e09b5fae62ea96b6a2 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 20:00:58 +0300 Subject: [PATCH 092/150] Add support for version field --- crates/lox-utils/src/ndm/kvn/parser.rs | 16 ++++--- crates/lox-utils/src/ndm/ndm.rs | 14 +++--- crates/lox-utils/src/ndm/omm.rs | 16 +++---- crates/lox-utils/src/ndm/opm.rs | 11 +++-- crates/lox_derive/src/lib.rs | 61 +++++++++++++++++++++++--- 5 files changed, 86 insertions(+), 32 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index 7757b8ed..d5eacbd0 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -991,21 +991,27 @@ mod test { } #[derive(KvnDeserialize, Default, Debug, PartialEq)] - struct KvnWithUnitStruct { - semi_major_axis: DistanceType, + struct AsdType { + pub semi_major_axis: DistanceType, + pub asdfg: f64, + pub version: String, } #[test] fn test_parse_with_unit_struct() { - let kvn = r#"SEMI_MAJOR_AXIS = 41399.5123 [km]"#; + let kvn = r#"CCSDS_ASD_VERS = 3.0 + SEMI_MAJOR_AXIS = 41399.5123 [km] + ASDFG = 12333.5123"#; assert_eq!( - KvnWithUnitStruct::deserialize(&mut kvn.lines().peekable()), - Ok(KvnWithUnitStruct { + AsdType::deserialize(&mut kvn.lines().peekable()), + Ok(AsdType { semi_major_axis: DistanceType { base: 41399.5123, units: Some(PositionUnits("km".to_string(),)), }, + asdfg: 12333.5123f64, + version: "3.0".to_string(), },) ) } diff --git a/crates/lox-utils/src/ndm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs index 38fe336b..46d888d9 100644 --- a/crates/lox-utils/src/ndm/ndm.rs +++ b/crates/lox-utils/src/ndm/ndm.rs @@ -427,7 +427,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -511,7 +511,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Opm(opm::OpmType { @@ -642,7 +642,7 @@ mod test { }, }, id: Some("CCSDS_OPM_VERS".to_string()), - version: Some("2.0".to_string()), + version: "2.0".to_string(), },), NdmChildChoice::Opm(opm::OpmType { header: common::OdmHeader { @@ -744,7 +744,7 @@ mod test { }, }, id: Some("CCSDS_OPM_VERS".to_string()), - version: Some("2.0".to_string()), + version: "2.0".to_string(), },), NdmChildChoice::Oem(oem::OemType { header: common::OdmHeader { @@ -975,7 +975,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -1059,7 +1059,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -1143,7 +1143,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), ], diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs index 81b0a1d3..a32fe2b8 100644 --- a/crates/lox-utils/src/ndm/omm.rs +++ b/crates/lox-utils/src/ndm/omm.rs @@ -124,7 +124,7 @@ pub struct OmmType { #[serde(rename = "body")] pub body: OmmBody, #[serde(rename = "@id")] - pub id: String, + pub id: Option, #[serde(rename = "@version")] pub version: String, } @@ -608,7 +608,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }); } @@ -741,7 +741,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), } ); @@ -990,7 +990,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "3.0".to_string(), } ); @@ -1242,7 +1242,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "3.0".to_string(), } ); @@ -1392,7 +1392,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), } ); @@ -1430,9 +1430,9 @@ mod test { #[test] fn test_parse_omm_message_kvn() { - //@TODO add back: CCSDS_OPM_VERS = 3.0 //@TOOD add back user defined stuff - let kvn = r#"COMMENT this is a comment + let kvn = r#"CCSDS_OMM_VERS = 3.0 +COMMENT this is a comment COMMENT here is another one CREATION_DATE = 2007-065T16:00:00 ORIGINATOR = NOAA/USA diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs index d8a365d9..de3b784a 100644 --- a/crates/lox-utils/src/ndm/opm.rs +++ b/crates/lox-utils/src/ndm/opm.rs @@ -29,8 +29,7 @@ pub struct OpmType { // Marked as option for the KVN deserializer pub id: Option, #[serde(rename = "@version")] - // Marked as option for the KVN deserializer - pub version: Option, + pub version: String, } #[derive( @@ -532,7 +531,7 @@ mod test { }, }, id: Some("CCSDS_OPM_VERS".to_string()), - version: Some("3.0".to_string()), + version: "3.0".to_string(), } ); } @@ -577,9 +576,9 @@ mod test { #[test] fn test_parse_opm_message_kvn() { - //@TODO add back: CCSDS_OPM_VERS = 3.0 //@TOOD add user defined stuff - let kvn = r#"COMMENT Generated by GSOC, R. Kiehling + let kvn = r#"CCSDS_OPM_VERS = 3.0 +COMMENT Generated by GSOC, R. Kiehling COMMENT Current intermediate orbit IO2 and maneuver planning data CREATION_DATE = 2021-06-03T05:33:00.123 ORIGINATOR = GSOC @@ -797,7 +796,7 @@ MAN_DV_3 = 0.00000000 [km/s]"#; }, }, id: None, - version: None, + version: "3.0".to_string(), },) ); } diff --git a/crates/lox_derive/src/lib.rs b/crates/lox_derive/src/lib.rs index 0bfe0e00..53993f12 100644 --- a/crates/lox_derive/src/lib.rs +++ b/crates/lox_derive/src/lib.rs @@ -508,10 +508,58 @@ fn deserializer_for_struct_with_named_fields( }, } } else { - let field_deserializers: Result, _> = fields + let version_field_deserializers: Result, _> = fields + .iter() + .filter(|field| { + let field_name = field.ident.as_ref().unwrap(); + + field_name == "version" + }).map(|field| { + let string_type_name = type_name.to_string(); + + if ! string_type_name.ends_with("Type") { + return Err(syn::Error::new_spanned(&fields, "Types with \"version\" field should be of the form SomethingType") + .into_compile_error() + .into()); + } + + let message_type_name = string_type_name.trim_end_matches("Type").to_owned().to_uppercase(); + + let field_name = field.ident.as_ref().unwrap(); + + // 7.4.4 Keywords must be uppercase and must not contain blanks + let expected_kvn_name = format!("CCSDS_{}_VERS", message_type_name); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + + let parser = generate_call_to_deserializer_for_kvn_type( + &field_type, + field_type_new, + &expected_kvn_name, + )?; + + Ok(quote! { + #field_name: #parser?, + }) + }).collect(); + + if let Err(e) = version_field_deserializers { + return e; + } + + let version_field_deserializers = version_field_deserializers.unwrap(); + + let other_field_deserializers: Result, _> = fields .iter() - .enumerate() - .map(|(_, field)| { + .filter(|field| { + let field_name = field.ident.as_ref().unwrap(); + + field_name != "version" + }) + .map(|field| { let field_name = field.ident.as_ref().unwrap(); // Unwrap is okay because we only support named structs @@ -576,15 +624,16 @@ fn deserializer_for_struct_with_named_fields( }) .collect(); - if let Err(e) = field_deserializers { + if let Err(e) = other_field_deserializers { return e; } - let field_deserializers = field_deserializers.unwrap(); + let other_field_deserializers = other_field_deserializers.unwrap(); quote! { Ok(#type_name { - #(#field_deserializers)* + #(#version_field_deserializers)* + #(#other_field_deserializers)* }) } } From 410c4a5485fb544e5cd1e60268fdde46f9a02eae Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 3 Jun 2024 20:06:14 +0300 Subject: [PATCH 093/150] Enable OMM test --- crates/lox-utils/src/ndm/omm.rs | 213 +++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 2 deletions(-) diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs index a32fe2b8..e7887aba 100644 --- a/crates/lox-utils/src/ndm/omm.rs +++ b/crates/lox-utils/src/ndm/omm.rs @@ -1482,7 +1482,216 @@ CZ_DOT_X_DOT = 1.869263192954590e-10 CZ_DOT_Y_DOT = 1.008862586240695e-10 CZ_DOT_Z_DOT = 6.224444338635500e-10"#; - println!("{:#?}", OmmType::deserialize(&mut kvn.lines().peekable())); - // assert_eq!(OmmType::deserialize(&mut kvn.lines().peekable()), Ok()); + assert_eq!(OmmType::deserialize(&mut kvn.lines().peekable()), Ok( + OmmType { + header: common::OdmHeader { + comment_list: vec![ + "this is a comment".to_string(), + "here is another one".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType( + "2007-065T16:00:00".to_string(), + ), + originator: "NOAA/USA".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec![ + "this comment doesn't say much".to_string(), + ], + object_name: "GOES 9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TOD".to_string(), + ref_frame_epoch: Some( + common::EpochType( + "2000-003T10:34:00".to_string(), + ), + ), + time_system: "MRT".to_string(), + mean_element_theory: "SOME THEORY".to_string(), + }, + data: OmmData { + comment_list: vec![ + "the following data is what we're looking for".to_string(), + ], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType( + "2000-005T10:00:00".to_string(), + ), + semi_major_axis: Some( + common::DistanceType { + base: 6800.0, + units: None, + }, + ), + mean_motion: None, + eccentricity: common::NonNegativeDouble( + 0.0005013, + ), + inclination: common::InclinationType { + base: 3.0539, + units: None, + }, + ra_of_asc_node: common::AngleType { + base: 81.7939, + units: None, + }, + arg_of_pericenter: common::AngleType { + base: 249.2363, + units: None, + }, + mean_anomaly: common::AngleType { + base: 150.1602, + units: None, + }, + gm: None, + }, + spacecraft_parameters: Some( + common::SpacecraftParametersType { + comment_list: vec![ + "spacecraft data".to_string(), + ], + mass: Some( + common::MassType { + base: common::NonNegativeDouble( + 300.0, + ), + units: None, + }, + ), + solar_rad_area: Some( + common::AreaType { + base: common::NonNegativeDouble( + 5.0, + ), + units: None, + }, + ), + solar_rad_coeff: Some( + common::NonNegativeDouble( + 0.001, + ), + ), + drag_area: Some( + common::AreaType { + base: common::NonNegativeDouble( + 4.0, + ), + units: None, + }, + ), + drag_coeff: Some( + common::NonNegativeDouble( + 0.002, + ), + ), + }, + ), + tle_parameters: None, + covariance_matrix: Some( + common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some( + "TNW".to_string(), + ), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + }, + ), + user_defined_parameters: None, + }, + }, + }, + id: None, + version: "3.0".to_string(), + }, + )); } } From 6372a152b0271f3bdb6c1f47ad3b8cd79988307f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 14:56:38 +0300 Subject: [PATCH 094/150] Clean-up imports --- Cargo.lock | 291 ++++++++++++++++++++++++++++++++++-- Cargo.toml | 4 + crates/lox-utils/Cargo.toml | 16 +- 3 files changed, 289 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49555284..f348c504 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstyle" version = "1.0.7" @@ -50,12 +65,36 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets 0.52.5", +] + [[package]] name = "clap" version = "4.5.4" @@ -88,6 +127,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "csv" version = "1.3.0" @@ -156,6 +201,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "fast-float" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" + [[package]] name = "fast_polynomial" version = "0.1.0" @@ -307,6 +358,29 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "indoc" version = "2.0.4" @@ -328,6 +402,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -362,6 +445,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + [[package]] name = "lox-bodies" version = "0.1.0" @@ -457,12 +546,29 @@ dependencies = [ name = "lox-utils" version = "0.1.0" dependencies = [ + "fast-float", "fast_polynomial", "float_eq", + "lox_derive", + "nom", + "quick-xml", + "regex", "rstest", + "serde", + "serde-aux", + "serde_json", "thiserror", ] +[[package]] +name = "lox_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "memchr" version = "2.6.4" @@ -597,7 +703,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -626,9 +732,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -722,6 +828,16 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.35" @@ -910,6 +1026,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-aux" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" +dependencies = [ + "chrono", + "serde", + "serde_json", +] + [[package]] name = "serde_derive" version = "1.0.199" @@ -921,6 +1048,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "slab" version = "0.4.9" @@ -938,9 +1076,9 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -1029,13 +1167,76 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1044,13 +1245,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1059,38 +1276,86 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml index 0a3eb2fa..c838adb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ lox_derive = { path = "./crates/lox_derive" } csv = "1.3.0" divan = "0.1.14" dyn-clone = "1.0.17" +fast-float = "0.2.0" fast_polynomial = "0.1.0" float_eq = "1.0.1" glam = "0.25.0" @@ -32,7 +33,10 @@ nom = "7.1.3" num = "0.4.1" proptest = "1.4.0" pyo3 = "0.21.1" +quick-xml = { version = "0.31.0", features = ["serde", "serialize"] } regex = "1.10.4" rstest = "0.18.2" serde = { version = "1.0.199", features = ["derive"] } +serde-aux = "4.5.0" +serde_json = "1.0.113" thiserror = "1.0" diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 08fdcd7b..6fd2becf 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -6,15 +6,13 @@ edition = "2021" [dependencies] fast_polynomial.workspace = true thiserror.workspace = true -nom = "7.1.3" -fast_polynomial = "0.1.0" -quick-xml = { version = "0.31.0", features = ["serde"] } -serde = { version = "1.0.194", features = ["serde_derive"] } -serde_json = "1.0.113" -error = "0.1.9" -serde-aux = "4.5.0" -regex = "1.10.4" -fast-float = "0.2.0" +nom.workspace = true +quick-xml.workspace = true +serde.workspace = true +serde_json.workspace = true +serde-aux.workspace = true +regex.workspace = true +fast-float.workspace = true lox_derive.workspace = true [dev-dependencies] From 737875ecf90e4e89b24d328b0ee6e702d2a7c5b4 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 15:01:49 +0300 Subject: [PATCH 095/150] Fix crate name case --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- crates/{lox_derive => lox-derive}/Cargo.toml | 2 +- crates/{lox_derive => lox-derive}/src/lib.rs | 0 crates/lox-utils/Cargo.toml | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) rename crates/{lox_derive => lox-derive}/Cargo.toml (87%) rename crates/{lox_derive => lox-derive}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index f348c504..ceeb1ae0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,15 @@ dependencies = [ "lox-utils", ] +[[package]] +name = "lox-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "lox-earth" version = "0.1.0" @@ -549,7 +558,7 @@ dependencies = [ "fast-float", "fast_polynomial", "float_eq", - "lox_derive", + "lox-derive", "nom", "quick-xml", "regex", @@ -560,15 +569,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "lox_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "memchr" version = "2.6.4" diff --git a/Cargo.toml b/Cargo.toml index c838adb5..cd100528 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ lox-io = { path = "crates/lox-io" } lox-space = { path = "crates/lox-space" } lox-time = { path = "crates/lox-time" } lox-utils = { path = "crates/lox-utils" } -lox_derive = { path = "./crates/lox_derive" } +lox-derive = { path = "./crates/lox-derive" } csv = "1.3.0" divan = "0.1.14" diff --git a/crates/lox_derive/Cargo.toml b/crates/lox-derive/Cargo.toml similarity index 87% rename from crates/lox_derive/Cargo.toml rename to crates/lox-derive/Cargo.toml index e3caed5f..32479ef2 100644 --- a/crates/lox_derive/Cargo.toml +++ b/crates/lox-derive/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lox_derive" +name = "lox-derive" version = "0.1.0" edition = "2021" diff --git a/crates/lox_derive/src/lib.rs b/crates/lox-derive/src/lib.rs similarity index 100% rename from crates/lox_derive/src/lib.rs rename to crates/lox-derive/src/lib.rs diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 6fd2becf..4c6c3425 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -13,7 +13,7 @@ serde_json.workspace = true serde-aux.workspace = true regex.workspace = true fast-float.workspace = true -lox_derive.workspace = true +lox-derive.workspace = true [dev-dependencies] float_eq.workspace = true From 8324b5fcfc22155891740b01122b003a268f839c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 15:03:54 +0300 Subject: [PATCH 096/150] Add missing test cfg annotation --- crates/lox-utils/src/ndm/json/omm.rs | 1 + crates/lox-utils/src/ndm/kvn/parser.rs | 1 + crates/lox-utils/src/ndm/xml/ndm.rs | 1 + crates/lox-utils/src/ndm/xml/ocm.rs | 1 + crates/lox-utils/src/ndm/xml/omm.rs | 1 + crates/lox-utils/src/ndm/xml/opm.rs | 1 + 6 files changed, 6 insertions(+) diff --git a/crates/lox-utils/src/ndm/json/omm.rs b/crates/lox-utils/src/ndm/json/omm.rs index 53c75dcb..6312f900 100644 --- a/crates/lox-utils/src/ndm/json/omm.rs +++ b/crates/lox-utils/src/ndm/json/omm.rs @@ -287,6 +287,7 @@ pub struct OmmType { pub user_defined_parameters: HashMap>, } +#[cfg(test)] mod test { use super::*; diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index d5eacbd0..bd28ad0e 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -452,6 +452,7 @@ pub fn parse_kvn_datetime_line_new<'a>( )) } +#[cfg(test)] mod test { use lox_derive::KvnDeserialize; diff --git a/crates/lox-utils/src/ndm/xml/ndm.rs b/crates/lox-utils/src/ndm/xml/ndm.rs index d92dfa43..6dab3dba 100644 --- a/crates/lox-utils/src/ndm/xml/ndm.rs +++ b/crates/lox-utils/src/ndm/xml/ndm.rs @@ -31,6 +31,7 @@ pub struct NdmType { pub child_list: Vec, } +#[cfg(test)] mod test { use super::super::common; use super::*; diff --git a/crates/lox-utils/src/ndm/xml/ocm.rs b/crates/lox-utils/src/ndm/xml/ocm.rs index ce80d144..6acfd948 100644 --- a/crates/lox-utils/src/ndm/xml/ocm.rs +++ b/crates/lox-utils/src/ndm/xml/ocm.rs @@ -545,6 +545,7 @@ pub struct OcmOdParametersType { pub data_types: Option, } +#[cfg(test)] mod test { use super::*; diff --git a/crates/lox-utils/src/ndm/xml/omm.rs b/crates/lox-utils/src/ndm/xml/omm.rs index 39201ac2..7df08cf4 100644 --- a/crates/lox-utils/src/ndm/xml/omm.rs +++ b/crates/lox-utils/src/ndm/xml/omm.rs @@ -215,6 +215,7 @@ pub struct DdRevType { pub units: Option, } +#[cfg(test)] mod test { use super::*; diff --git a/crates/lox-utils/src/ndm/xml/opm.rs b/crates/lox-utils/src/ndm/xml/opm.rs index efbbe876..b788045c 100644 --- a/crates/lox-utils/src/ndm/xml/opm.rs +++ b/crates/lox-utils/src/ndm/xml/opm.rs @@ -121,6 +121,7 @@ pub struct ManeuverParametersType { pub man_dv_3: common::VelocityType, } +#[cfg(test)] mod test { use super::*; From e7cbbda4c4ff5966d79b8e81b6236746f291ec2f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 15:14:16 +0300 Subject: [PATCH 097/150] Fix formatting --- crates/lox-derive/src/lib.rs | 29 +- crates/lox-utils/src/ndm/xml/omm.rs | 929 +++++++++++----------------- 2 files changed, 377 insertions(+), 581 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 53993f12..ef2aeccb 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -514,16 +514,23 @@ fn deserializer_for_struct_with_named_fields( let field_name = field.ident.as_ref().unwrap(); field_name == "version" - }).map(|field| { + }) + .map(|field| { let string_type_name = type_name.to_string(); - if ! string_type_name.ends_with("Type") { - return Err(syn::Error::new_spanned(&fields, "Types with \"version\" field should be of the form SomethingType") + if !string_type_name.ends_with("Type") { + return Err(syn::Error::new_spanned( + &fields, + "Types with \"version\" field should be of the form SomethingType", + ) .into_compile_error() .into()); } - let message_type_name = string_type_name.trim_end_matches("Type").to_owned().to_uppercase(); + let message_type_name = string_type_name + .trim_end_matches("Type") + .to_owned() + .to_uppercase(); let field_name = field.ident.as_ref().unwrap(); @@ -531,10 +538,13 @@ fn deserializer_for_struct_with_named_fields( let expected_kvn_name = format!("CCSDS_{}_VERS", message_type_name); // Unwrap is okay because we expect this span to come from the source code - let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); + let field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); let field_type_new = extract_type_path(&field.ty).unwrap(); - let parser = generate_call_to_deserializer_for_kvn_type( &field_type, field_type_new, @@ -544,12 +554,13 @@ fn deserializer_for_struct_with_named_fields( Ok(quote! { #field_name: #parser?, }) - }).collect(); - + }) + .collect(); + if let Err(e) = version_field_deserializers { return e; } - + let version_field_deserializers = version_field_deserializers.unwrap(); let other_field_deserializers: Result, _> = fields diff --git a/crates/lox-utils/src/ndm/xml/omm.rs b/crates/lox-utils/src/ndm/xml/omm.rs index 7df08cf4..c99e235a 100644 --- a/crates/lox-utils/src/ndm/xml/omm.rs +++ b/crates/lox-utils/src/ndm/xml/omm.rs @@ -500,14 +500,13 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType( - "2021-03-24T23:00:00.000".to_string(), - ), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), originator: "CelesTrak".to_string(), message_id: None, }, @@ -527,86 +526,54 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2021-03-22T13:21:09.224928".to_string(), - ), + epoch: common::EpochType("2021-03-22T13:21:09.224928".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 13.82309053, - units: None, - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0205751, - ), + mean_motion: Some(RevType { + base: 13.82309053, + units: None, + },), + eccentricity: common::NonNegativeDouble(0.0205751,), inclination: common::InclinationType { - base: common::InclinationRange( - 49.8237, - ), + base: common::InclinationRange(49.8237,), units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 93.8140, - ), + base: common::AngleRange(93.8140,), units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 224.8348, - ), + base: common::AngleRange(224.8348,), units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 133.5761, - ), + base: common::AngleRange(133.5761,), units: None, }, gm: None, }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: Some( - 0, - ), - classification_type: Some( - "U".to_string(), - ), - norad_cat_id: Some( - 7646, - ), - element_set_no: Some( - ElementSetNoType( - "999".to_string(), - ), - ), - rev_at_epoch: Some( - 32997, - ), - bstar: Some( - BStarType { - base: -4.7102e-6, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0,), + classification_type: Some("U".to_string(),), + norad_cat_id: Some(7646,), + element_set_no: Some(ElementSetNoType("999".to_string(),),), + rev_at_epoch: Some(32997,), + bstar: Some(BStarType { + base: -4.7102e-6, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, }, - ), + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), covariance_matrix: None, user_defined_parameters: None, }, @@ -614,7 +581,8 @@ mod test { }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }); + } + ); } #[test] @@ -691,20 +659,15 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { - comment_list: vec![ - "THIS IS AN XML VERSION OF THE OMM".to_string(), - ], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), + creation_date: common::EpochType("2007-065T16:00:00".to_string(),), originator: "NOAA".to_string(), - message_id: Some( - "OMM 201113719185".to_string(), - ), + message_id: Some("OMM 201113719185".to_string(),), }, body: OmmBody { segment: OmmSegment { @@ -722,188 +685,153 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2007-064T10:34:41.4264".to_string(), - ), + epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 1.00273272, - units: None, - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), + mean_motion: Some(RevType { + base: 1.00273272, + units: None, + },), + eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), + base: common::InclinationRange(3.0539,), units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), + base: common::AngleRange(81.7939,), units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), + base: common::AngleRange(249.2363,), units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), + base: common::AngleRange(150.1602,), units: None, }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: None, - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: None, + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some( - 23581, - ), - element_set_no: Some( - ElementSetNoType( - "0925".to_string(), - ), - ), - rev_at_epoch: Some( - 4316, - ), - bstar: Some( - BStarType { - base: 0.0001, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some(23581,), + element_set_no: Some(ElementSetNoType("0925".to_string(),),), + rev_at_epoch: Some(4316,), + bstar: Some(BStarType { + base: 0.0001, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: None, }, - ), - covariance_matrix: Some( - common::OpmCovarianceMatrixType { - comment_list: vec![], - cov_ref_frame: Some( - "TEME".to_string(), - ), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some("TEME".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, }, - ), + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + },), user_defined_parameters: None, }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "3.0".to_string(), - }); + } + ); } #[test] @@ -982,21 +910,16 @@ mod test { "#; let message: OmmType = from_str(xml).unwrap(); - - assert_eq!(message, + + assert_eq!( + message, OmmType { header: common::OdmHeader { - comment_list: vec![ - "THIS IS AN XML VERSION OF THE OMM".to_string(), - ], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), + creation_date: common::EpochType("2007-065T16:00:00".to_string(),), originator: "NOAA".to_string(), - message_id: Some( - "OMM 201113719185".to_string(), - ), + message_id: Some("OMM 201113719185".to_string(),), }, body: OmmBody { segment: OmmSegment { @@ -1013,230 +936,156 @@ mod test { data: OmmData { comment_list: vec![], mean_elements: MeanElementsType { - comment_list: vec![ - "mean Elements".to_string(), - ], - epoch: common::EpochType( - "2007-064T10:34:41.4264".to_string(), - ), + comment_list: vec!["mean Elements".to_string(),], + epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 1.00273272, - units: Some( - RevUnits( - "rev/day".to_string(), - ), - ), - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), + mean_motion: Some(RevType { + base: 1.00273272, + units: Some(RevUnits("rev/day".to_string(),),), + },), + eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::InclinationRange(3.0539,), + units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(81.7939,), + units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(249.2363,), + units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(150.1602,), + units: Some(common::AngleUnits("deg".to_string(),),), }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: None, - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: None, + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![ - "tle Parameters".to_string(), - ], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some( - 23581, - ), - element_set_no: Some( - ElementSetNoType( - "0925".to_string(), - ), - ), - rev_at_epoch: Some( - 4316, - ), - bstar: Some( - BStarType { - base: 0.0001, - units: Some( - BStarUnits( - "1/ER".to_string(), - ), - ), - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: Some( - DRevUnits( - "rev/day**2".to_string(), - ), - ), - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: Some( - DRevUnits( - "rev/day**3".to_string(), - ), - ), - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec!["tle Parameters".to_string(),], + ephemeris_type: None, + classification_type: None, + norad_cat_id: Some(23581,), + element_set_no: Some(ElementSetNoType("0925".to_string(),),), + rev_at_epoch: Some(4316,), + bstar: Some(BStarType { + base: 0.0001, + units: Some(BStarUnits("1/ER".to_string(),),), + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.13e-6, + units: Some(DRevUnits("rev/day**2".to_string(),),), }, - ), - covariance_matrix: Some( - common::OpmCovarianceMatrixType { - comment_list: vec![ - "covariance Matrix".to_string(), - ], - cov_ref_frame: Some( - "TEME".to_string(), - ), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: Some(DRevUnits("rev/day**3".to_string(),),), + },), + agom: None, + },), + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec!["covariance Matrix".to_string(),], + cov_ref_frame: Some("TEME".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, }, - ), + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + },), user_defined_parameters: None, }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "3.0".to_string(), - }); + } + ); } - #[test] fn test_parse_omm_message3() { let xml = r#" @@ -1287,14 +1136,13 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!( + message, OmmType { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType( - "2021-03-24T23:00:00.000".to_string(), - ), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), originator: "CelesTrak".to_string(), message_id: None, }, @@ -1314,142 +1162,80 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType( - "2008-09-20T12:25:40.104192".to_string(), - ), + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), semi_major_axis: None, - mean_motion: Some( - RevType { - base: 15.72125391, - units: Some( - RevUnits( - "rev/day".to_string(), - ), - ), - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0006703, - ), + mean_motion: Some(RevType { + base: 15.72125391, + units: Some(RevUnits("rev/day".to_string(),),), + },), + eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { - base: common::InclinationRange( - 51.6416, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::InclinationRange(51.6416,), + units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 247.4627, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(247.4627,), + units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 130.536, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(130.536,), + units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 325.0288, - ), - units: Some( - common::AngleUnits( - "deg".to_string(), - ), - ), + base: common::AngleRange(325.0288,), + units: Some(common::AngleUnits("deg".to_string(),),), }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: Some( - common::GmUnits( - "km**3/s**2".to_string(), - ), - ), - }, - ), + gm: Some(common::GmType { + base: common::PositiveDouble(398600.8,), + units: Some(common::GmUnits("km**3/s**2".to_string(),),), + },), }, spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: Some( - 0, - ), - classification_type: Some( - "U".to_string(), - ), - norad_cat_id: Some( - 7646, - ), - element_set_no: Some( - ElementSetNoType( - "999".to_string(), - ), - ), - rev_at_epoch: Some( - 32997, - ), - bstar: Some( - BStarType { - base: -4.7102e-6, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, + tle_parameters: Some(TleParametersType { + comment_list: vec![], + ephemeris_type: Some(0,), + classification_type: Some("U".to_string(),), + norad_cat_id: Some(7646,), + element_set_no: Some(ElementSetNoType("999".to_string(),),), + rev_at_epoch: Some(32997,), + bstar: Some(BStarType { + base: -4.7102e-6, + units: None, + },), + bterm: None, + mean_motion_dot: DRevType { + base: -1.47e-6, + units: None, }, - ), + mean_motion_ddot: Some(DRevType { + base: 0.0, + units: None, + },), + agom: None, + },), covariance_matrix: None, - user_defined_parameters: Some( - common::UserDefinedType { - comment_list: vec![], - user_defined_list: vec![ - common::UserDefinedParameterType { - base: "foo enters".to_string(), - parameter: "FOO".to_string(), - }, - common::UserDefinedParameterType { - base: "a bar".to_string(), - parameter: "BAR".to_string(), - }, - ], - }, - ), + user_defined_parameters: Some(common::UserDefinedType { + comment_list: vec![], + user_defined_list: vec![ + common::UserDefinedParameterType { + base: "foo enters".to_string(), + parameter: "FOO".to_string(), + }, + common::UserDefinedParameterType { + base: "a bar".to_string(), + parameter: "BAR".to_string(), + }, + ], + },), }, }, }, id: "CCSDS_OMM_VERS".to_string(), version: "2.0".to_string(), - }); + } + ); } - #[test] fn test_parse_omm_message_spurious() { let xml = r#" @@ -1479,5 +1265,4 @@ mod test { assert!(message.is_err()); } - } From 556407b5725816c1ed711a9c19bbac9c1e143e6b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 15:17:09 +0300 Subject: [PATCH 098/150] Make clippy happy --- crates/lox-utils/src/ndm/kvn/parser.rs | 44 ++++++++++++-------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index bd28ad0e..f7204a57 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -188,9 +188,8 @@ pub fn kvn_line_matches_key_new<'a>( input: &'a str, ) -> Result> { if key == "COMMENT" { - ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input) - .and_then(|_| Ok(true)) - .or_else(|_| Ok(false)) + ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input).map(|_| true) + .or(Ok(false)) } else { let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); @@ -198,15 +197,14 @@ pub fn kvn_line_matches_key_new<'a>( return Err(KvnKeyMatchErr::KeywordNotFound { expected: key }); } - ns::delimited(nc::space0, nb::tag(key), equals)(input) - .and_then(|_| Ok(true)) - .or_else(|_| Ok(false)) + ns::delimited(nc::space0, nb::tag(key), equals)(input).map(|_| true) + .or(Ok(false)) } } -pub fn parse_kvn_string_line_new<'a>( - input: &'a str, -) -> nom::IResult<&'a str, KvnStringValue, KvnStringParserErr<&'a str>> { +pub fn parse_kvn_string_line_new( + input: &str, +) -> nom::IResult<&str, KvnStringValue, KvnStringParserErr<&str>> { if input.trim_start().starts_with("COMMENT") { return Ok(( "", @@ -245,7 +243,7 @@ pub fn parse_kvn_string_line_new<'a>( .trim_end() .to_owned(); - if keyword.len() == 0 { + if keyword.is_empty() { return Err(nom::Err::Failure(KvnStringParserErr::EmptyKeyword { input, })); @@ -259,17 +257,17 @@ pub fn parse_kvn_string_line_new<'a>( .trim_end() .to_owned(); - if value.len() == 0 { + if value.is_empty() { return Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input })); } Ok(("", KvnValue { value, unit: None })) } -pub fn parse_kvn_integer_line_new<'a, T>( - input: &'a str, +pub fn parse_kvn_integer_line_new( + input: &str, with_unit: bool, -) -> nom::IResult<&'a str, KvnValue, KvnNumberParserErr<&'a str>> +) -> nom::IResult<&str, KvnValue, KvnNumberParserErr<&str>> where T: std::str::FromStr, { @@ -295,7 +293,7 @@ where .trim_end() .to_owned(); - if keyword.len() == 0 { + if keyword.is_empty() { return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { input, })); @@ -321,10 +319,10 @@ fn is_empty_value(input: &str) -> bool { re.is_match(input) } -pub fn parse_kvn_numeric_line_new<'a>( - input: &'a str, +pub fn parse_kvn_numeric_line_new( + input: &str, with_unit: bool, -) -> nom::IResult<&'a str, KvnNumericValue, KvnNumberParserErr<&'a str>> { +) -> nom::IResult<&str, KvnNumericValue, KvnNumberParserErr<&str>> { if is_empty_value(input) { Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; @@ -346,7 +344,7 @@ pub fn parse_kvn_numeric_line_new<'a>( .trim_end() .to_owned(); - if keyword.len() == 0 { + if keyword.is_empty() { return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { input, })); @@ -362,9 +360,9 @@ pub fn parse_kvn_numeric_line_new<'a>( Ok(("", KvnValue { value, unit })) } -pub fn parse_kvn_datetime_line_new<'a>( - input: &'a str, -) -> nom::IResult<&'a str, KvnDateTimeValue, KvnDateTimeParserErr<&'a str>> { +pub fn parse_kvn_datetime_line_new( + input: &str, +) -> nom::IResult<&str, KvnDateTimeValue, KvnDateTimeParserErr<&str>> { if is_empty_value(input) { Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { input, @@ -388,7 +386,7 @@ pub fn parse_kvn_datetime_line_new<'a>( .trim_end() .to_owned(); - if keyword.len() == 0 { + if keyword.is_empty() { return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { input, })); From dc3654efeef3436c61f9ea32e5014125d48d9081 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 16:41:31 +0300 Subject: [PATCH 099/150] Remove leftover trailing whitespace --- crates/lox-derive/src/lib.rs | 4 ++-- crates/lox-utils/src/ndm/kvn/parser.rs | 6 ++++-- crates/lox-utils/src/ndm/xml/omm.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index ef2aeccb..18f9525e 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -603,7 +603,7 @@ fn deserializer_for_struct_with_named_fields( "String" => quote! {}, _ => quote! { ! #field_type_new::should_check_key_match() || }, }; - + quote! { match lines.peek() { None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { @@ -614,7 +614,7 @@ fn deserializer_for_struct_with_named_fields( #expected_kvn_name, next_line, )?; - + if #condition_shortcut line_matches { #field_type_new::deserialize(lines)? } else { diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-utils/src/ndm/kvn/parser.rs index f7204a57..2bf6e16b 100644 --- a/crates/lox-utils/src/ndm/kvn/parser.rs +++ b/crates/lox-utils/src/ndm/kvn/parser.rs @@ -188,7 +188,8 @@ pub fn kvn_line_matches_key_new<'a>( input: &'a str, ) -> Result> { if key == "COMMENT" { - ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input).map(|_| true) + ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input) + .map(|_| true) .or(Ok(false)) } else { let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); @@ -197,7 +198,8 @@ pub fn kvn_line_matches_key_new<'a>( return Err(KvnKeyMatchErr::KeywordNotFound { expected: key }); } - ns::delimited(nc::space0, nb::tag(key), equals)(input).map(|_| true) + ns::delimited(nc::space0, nb::tag(key), equals)(input) + .map(|_| true) .or(Ok(false)) } } diff --git a/crates/lox-utils/src/ndm/xml/omm.rs b/crates/lox-utils/src/ndm/xml/omm.rs index c99e235a..9f50ba85 100644 --- a/crates/lox-utils/src/ndm/xml/omm.rs +++ b/crates/lox-utils/src/ndm/xml/omm.rs @@ -282,7 +282,7 @@ mod test { let message: OmmType = from_str(xml).unwrap(); - assert_eq!(message, + assert_eq!(message, OmmType { header: common::OdmHeader { comment_list: vec![ From 2016c379593ee7b20795114aa2d8cee5bf61deef Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 16:43:20 +0300 Subject: [PATCH 100/150] Remove file leftover from merge resolve --- crates/lox-utils/src/ndm/common.rs | 1622 -------------------------- crates/lox-utils/src/ndm/ndm.rs | 1153 ------------------- crates/lox-utils/src/ndm/ocm.rs | 1076 ------------------ crates/lox-utils/src/ndm/oem.rs | 684 ----------- crates/lox-utils/src/ndm/omm.rs | 1697 ---------------------------- crates/lox-utils/src/ndm/opm.rs | 803 ------------- crates/lox-utils/src/odm.rs | 6 - 7 files changed, 7041 deletions(-) delete mode 100644 crates/lox-utils/src/ndm/common.rs delete mode 100644 crates/lox-utils/src/ndm/ndm.rs delete mode 100644 crates/lox-utils/src/ndm/ocm.rs delete mode 100644 crates/lox-utils/src/ndm/oem.rs delete mode 100644 crates/lox-utils/src/ndm/omm.rs delete mode 100644 crates/lox-utils/src/ndm/opm.rs delete mode 100644 crates/lox-utils/src/odm.rs diff --git a/crates/lox-utils/src/ndm/common.rs b/crates/lox-utils/src/ndm/common.rs deleted file mode 100644 index 4eff4b78..00000000 --- a/crates/lox-utils/src/ndm/common.rs +++ /dev/null @@ -1,1622 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use serde; - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AccUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngMomentumUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AreaUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct GmUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct LengthUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct MassUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct MomentUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct WkgUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Ms2Units(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2Units(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2sUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2s2Units(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct PositionUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct VelocityUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq)] -pub struct VecDouble { - pub items: Vec, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct Vec3Double(#[serde(rename = "$text")] pub f64); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Vec6Double(#[serde(rename = "$text")] pub f64); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Vec9Double(#[serde(rename = "$text")] pub f64); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct EpochType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct TimeUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TimeSystemType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct PercentType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct Range100Type(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ProbabilityType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct PercentageUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct YesNoType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct TrajBasisType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct RevNumBasisType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct CovBasisType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ManBasisType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ManDcType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct NumPerYearUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ThrustUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct CovOrderType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct GeomagUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct SolarFluxUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AltRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LonRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatLonUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ControlledType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct DisintegrationType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionComponentType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotDirectionType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotseqType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleKeywordType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ApmRateFrameType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TorqueUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CLASSIFICATION")] - pub classification_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AccType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AngleType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AngleRateType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngMomentumType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: AngMomentumUnits, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AngVelComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngVelStateType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "REF_FRAME_A")] - pub ref_frame_a: String, - #[serde(rename = "REF_FRAME_B")] - pub ref_frame_b: String, - #[serde(rename = "ANGVEL_FRAME")] - pub angvel_frame: AngVelFrameType, - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct AngVelType { - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AreaType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct DayIntervalType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: DayIntervalUnits, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmDayIntervalType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct DeltamassType { - #[serde(rename = "$text")] - pub base: NegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct DeltamassTypeZ { - #[serde(rename = "$text")] - pub base: NonPositiveDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct FrequencyType { - #[serde(rename = "$text")] - pub base: PositiveDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct GmType { - #[serde(rename = "$text")] - pub base: PositiveDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct InclinationType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LengthType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: LengthUnits, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmLengthType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct MassType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct MomentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct WkgType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: WkgUnits, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OdParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "TIME_LASTOB_START")] - pub time_lastob_start: Option, - #[serde(rename = "TIME_LASTOB_END")] - pub time_lastob_end: Option, - #[serde(rename = "RECOMMENDED_OD_SPAN")] - pub recommended_od_span: Option, - #[serde(rename = "ACTUAL_OD_SPAN")] - pub actual_od_span: Option, - #[serde(rename = "OBS_AVAILABLE")] - pub obs_available: Option, - #[serde(rename = "OBS_USED")] - pub obs_used: Option, - #[serde(rename = "TRACKS_AVAILABLE")] - pub tracks_available: Option, - #[serde(rename = "TRACKS_USED")] - pub tracks_used: Option, - #[serde(rename = "RESIDUALS_ACCEPTED")] - pub residuals_accepted: Option, - #[serde(rename = "WEIGHTED_RMS")] - pub weighted_rms: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct SpacecraftParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MASS")] - pub mass: Option, - #[serde(rename = "SOLAR_RAD_AREA")] - pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] - pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] - pub drag_coeff: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct StateVectorType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "X")] - pub x: PositionType, - #[serde(rename = "Y")] - pub y: PositionType, - #[serde(rename = "Z")] - pub z: PositionType, - #[serde(rename = "X_DOT")] - pub x_dot: VelocityType, - #[serde(rename = "Y_DOT")] - pub y_dot: VelocityType, - #[serde(rename = "Z_DOT")] - pub z_dot: VelocityType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct StateVectorAccType { - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "X")] - pub x: PositionType, - #[serde(rename = "Y")] - pub y: PositionType, - #[serde(rename = "Z")] - pub z: PositionType, - #[serde(rename = "X_DOT")] - pub x_dot: VelocityType, - #[serde(rename = "Y_DOT")] - pub y_dot: VelocityType, - #[serde(rename = "Z_DOT")] - pub z_dot: VelocityType, - #[serde(rename = "X_DDOT")] - pub x_ddot: Option, - #[serde(rename = "Y_DDOT")] - pub y_ddot: Option, - #[serde(rename = "Z_DDOT")] - pub z_ddot: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Ms2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Ms2Units, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2sType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2s2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct DistanceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct PositionType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmPositionType { - #[serde(rename = "$text")] - pub base: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct VelocityType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmVelocityType { - #[serde(rename = "$text")] - pub base: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct DurationType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RelTimeType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct TimeOffsetType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct PercentageType { - #[serde(rename = "$text")] - pub base: Range100Type, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ManeuverFreqType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ThrustType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct GeomagType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct SolarFluxType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemCovarianceMatrixType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: EpochType, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: Option, - #[serde(rename = "CX_X")] - pub cx_x: PositionCovarianceType, - #[serde(rename = "CY_X")] - pub cy_x: PositionCovarianceType, - #[serde(rename = "CY_Y")] - pub cy_y: PositionCovarianceType, - #[serde(rename = "CZ_X")] - pub cz_x: PositionCovarianceType, - #[serde(rename = "CZ_Y")] - pub cz_y: PositionCovarianceType, - #[serde(rename = "CZ_Z")] - pub cz_z: PositionCovarianceType, - #[serde(rename = "CX_DOT_X")] - pub cx_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Y")] - pub cx_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Z")] - pub cx_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_X_DOT")] - pub cx_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_X")] - pub cy_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Y")] - pub cy_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Z")] - pub cy_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_X_DOT")] - pub cy_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_Y_DOT")] - pub cy_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_X")] - pub cz_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y")] - pub cz_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z")] - pub cz_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_X_DOT")] - pub cz_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y_DOT")] - pub cz_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z_DOT")] - pub cz_dot_z_dot: VelocityCovarianceType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmCovarianceMatrixType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: Option, - #[serde(rename = "CX_X")] - pub cx_x: PositionCovarianceType, - #[serde(rename = "CY_X")] - pub cy_x: PositionCovarianceType, - #[serde(rename = "CY_Y")] - pub cy_y: PositionCovarianceType, - #[serde(rename = "CZ_X")] - pub cz_x: PositionCovarianceType, - #[serde(rename = "CZ_Y")] - pub cz_y: PositionCovarianceType, - #[serde(rename = "CZ_Z")] - pub cz_z: PositionCovarianceType, - #[serde(rename = "CX_DOT_X")] - pub cx_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Y")] - pub cx_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_Z")] - pub cx_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CX_DOT_X_DOT")] - pub cx_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_X")] - pub cy_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Y")] - pub cy_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_Z")] - pub cy_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CY_DOT_X_DOT")] - pub cy_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CY_DOT_Y_DOT")] - pub cy_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_X")] - pub cz_dot_x: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y")] - pub cz_dot_y: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z")] - pub cz_dot_z: PositionVelocityCovarianceType, - #[serde(rename = "CZ_DOT_X_DOT")] - pub cz_dot_x_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Y_DOT")] - pub cz_dot_y_dot: VelocityCovarianceType, - #[serde(rename = "CZ_DOT_Z_DOT")] - pub cz_dot_z_dot: VelocityCovarianceType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct PositionCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct VelocityCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct PositionVelocityCovarianceType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AtmosphericReentryParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "ORBIT_LIFETIME")] - pub orbit_lifetime: DayIntervalType, - #[serde(rename = "REENTRY_ALTITUDE")] - pub reentry_altitude: PositionType, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] - pub orbit_lifetime_window_start: Option, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] - pub orbit_lifetime_window_end: Option, - #[serde(rename = "NOMINAL_REENTRY_EPOCH")] - pub nominal_reentry_epoch: Option, - #[serde(rename = "REENTRY_WINDOW_START")] - pub reentry_window_start: Option, - #[serde(rename = "REENTRY_WINDOW_END")] - pub reentry_window_end: Option, - #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] - pub orbit_lifetime_confidence_level: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct GroundImpactParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "PROBABILITY_OF_IMPACT")] - pub probability_of_impact: Option, - #[serde(rename = "PROBABILITY_OF_BURN_UP")] - pub probability_of_burn_up: Option, - #[serde(rename = "PROBABILITY_OF_BREAK_UP")] - pub probability_of_break_up: Option, - #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] - pub probability_of_land_impact: Option, - #[serde(rename = "PROBABILITY_OF_CASUALTY")] - pub probability_of_casualty: Option, - #[serde(rename = "NOMINAL_IMPACT_EPOCH")] - pub nominal_impact_epoch: Option, - #[serde(rename = "IMPACT_WINDOW_START")] - pub impact_window_start: Option, - #[serde(rename = "IMPACT_WINDOW_END")] - pub impact_window_end: Option, - #[serde(rename = "IMPACT_REF_FRAME")] - pub impact_ref_frame: Option, - #[serde(rename = "NOMINAL_IMPACT_LON")] - pub nominal_impact_lon: Option, - #[serde(rename = "NOMINAL_IMPACT_LAT")] - pub nominal_impact_lat: Option, - #[serde(rename = "NOMINAL_IMPACT_ALT")] - pub nominal_impact_alt: Option, - #[serde(rename = "IMPACT_1_CONFIDENCE")] - pub impact_1_confidence: Option, - #[serde(rename = "IMPACT_1_START_LON")] - pub impact_1_start_lon: Option, - #[serde(rename = "IMPACT_1_START_LAT")] - pub impact_1_start_lat: Option, - #[serde(rename = "IMPACT_1_STOP_LON")] - pub impact_1_stop_lon: Option, - #[serde(rename = "IMPACT_1_STOP_LAT")] - pub impact_1_stop_lat: Option, - #[serde(rename = "IMPACT_1_CROSS_TRACK")] - pub impact_1_cross_track: Option, - #[serde(rename = "IMPACT_2_CONFIDENCE")] - pub impact_2_confidence: Option, - #[serde(rename = "IMPACT_2_START_LON")] - pub impact_2_start_lon: Option, - #[serde(rename = "IMPACT_2_START_LAT")] - pub impact_2_start_lat: Option, - #[serde(rename = "IMPACT_2_STOP_LON")] - pub impact_2_stop_lon: Option, - #[serde(rename = "IMPACT_2_STOP_LAT")] - pub impact_2_stop_lat: Option, - #[serde(rename = "IMPACT_2_CROSS_TRACK")] - pub impact_2_cross_track: Option, - #[serde(rename = "IMPACT_3_CONFIDENCE")] - pub impact_3_confidence: Option, - #[serde(rename = "IMPACT_3_START_LON")] - pub impact_3_start_lon: Option, - #[serde(rename = "IMPACT_3_START_LAT")] - pub impact_3_start_lat: Option, - #[serde(rename = "IMPACT_3_STOP_LON")] - pub impact_3_stop_lon: Option, - #[serde(rename = "IMPACT_3_STOP_LAT")] - pub impact_3_stop_lat: Option, - #[serde(rename = "IMPACT_3_CROSS_TRACK")] - pub impact_3_cross_track: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmSpacecraftParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "WET_MASS")] - pub wet_mass: Option, - #[serde(rename = "DRY_MASS")] - pub dry_mass: Option, - #[serde(rename = "HAZARDOUS_SUBSTANCES")] - pub hazardous_substances: Option, - #[serde(rename = "SOLAR_RAD_AREA")] - pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] - pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] - pub drag_coeff: Option, - #[serde(rename = "RCS")] - pub rcs: Option, - #[serde(rename = "BALLISTIC_COEFF")] - pub ballistic_coeff: Option, - #[serde(rename = "THRUST_ACCELERATION")] - pub thrust_acceleration: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AltType { - #[serde(rename = "$text")] - pub base: AltRange, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct BallisticCoeffType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatType { - #[serde(rename = "$text")] - pub base: LatRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LonType { - #[serde(rename = "$text")] - pub base: LonRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct UserDefinedType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "USER_DEFINED")] - pub user_defined_list: Vec, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct UserDefinedParameterType { - #[serde(rename = "$text")] - pub base: String, - #[serde(rename = "@parameter")] - pub parameter: String, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionType {} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionRateType {} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionDotType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleType { - #[serde(rename = "rotation1")] - pub rotation1: RotationAngleComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationAngleComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationAngleComponentType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleComponentTypeold { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@value")] - pub value: f64, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateType { - #[serde(rename = "rotation1")] - pub rotation1: RotationRateComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationRateComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationRateComponentType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateComponentTypeOld { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@value")] - pub value: f64, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TorqueType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} diff --git a/crates/lox-utils/src/ndm/ndm.rs b/crates/lox-utils/src/ndm/ndm.rs deleted file mode 100644 index 46d888d9..00000000 --- a/crates/lox-utils/src/ndm/ndm.rs +++ /dev/null @@ -1,1153 +0,0 @@ -use serde; - -use super::{ocm, oem, omm, opm}; - -#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde()] -pub enum NdmChildChoice { - #[serde(rename = "ocm")] - Ocm(ocm::OcmType), - - #[serde(rename = "oem")] - Oem(oem::OemType), - - #[serde(rename = "omm")] - Omm(omm::OmmType), - - #[serde(rename = "opm")] - Opm(opm::OpmType), -} - -/// Combined instantiation type. Currently does not support AEM, APM, CDM, RDM, TDM -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NdmType { - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - - #[serde(rename = "$value")] - pub child_list: Vec, -} - -mod test { - use super::super::common; - use super::*; - - use quick_xml::de::from_str; - - #[test] - fn test_parse_combined_ndm() { - let xml = r#" -bla -asdfg - -
- - -
- - - - -
- -
- - -
- - - - NUSAT-2 (BATATA) - 2016-033C - EARTH - TEME - UTC - SGP4 - - - - 2020-12-04T15:27:01.975104 - 15.30610336 - .0011780 - 97.4090 - 71.7453 - 193.9419 - 272.1492 - - - 0 - U - 41558 - 999 - 25191 - .15913E-3 - 4.64E-5 - 0 - - - - -
- -
- 2004-281T17:26:06 - me -
- - - - Cassini - 1997-061A - Saturn - IAU-Saturn - UTC - - - final COMMENT, I think - - 2004-100T00:00:00Z - 1 - 1 - 1 - 1 - 1 - 1 - - - 1 - 0 - 45 - 0 - 15 - 15 - 398644 - - - 100 - 2 - 1 - 2 - 2.0 - - - 2004-125T00:00:00Z - 0 - -1 - GRC - 1 - 1 - 1 - - - - -
- - -
- 2004-281T17:26:06 - me -
- - - - Cassini - 1997-061A - Saturn - IAU-Saturn - UTC - - - - this is a comment - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - This is a COMMENT - 100 - 2 - 1 - 2 - 2.0 - - - This is a COMMENT - 2004-125T00:00:00 - 0 - -1 - GRC - 1 - 1 - 1 - - - - -
- - - -
- 2004-281T17:26:06 - me -
- - - - Cassini - 1997-061A - Saturn - IAU-Saturn - UTC - 2004-100T00:00:00.000000 - 2004-100T01:00:00.000000 - Hermite - 1 - - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - - -
- -
- - -
- - - - NUSAT-13 (EMMY) - 2020-079G - EARTH - TEME - UTC - SGP4 - - - - 2020-12-04T13:30:01.539648 - 15.31433655 - .0009574 - 97.2663 - 51.2167 - 149.8567 - 322.5146 - - - 0 - U - 46833 - 999 - 434 - .14401E-3 - 4.301E-5 - 0 - - - - -
- -
- - -
- - - - NUSAT-17 (MARY) - 2020-079J - EARTH - TEME - UTC - SGP4 - - - - 2020-12-04T16:27:08.698176 - 15.31317097 - .0009674 - 97.2671 - 51.3486 - 160.8608 - 302.2789 - - - 0 - U - 46835 - 999 - 436 - -.13273E-3 - -4.087E-5 - 0 - - - - -
- -
- - -
- - - - NUSAT-18 (VERA) - 2020-079K - EARTH - TEME - UTC - SGP4 - - - - 2020-12-04T13:13:33.140064 - 15.32037173 - .0009024 - 97.2666 - 51.2301 - 167.2057 - 304.5569 - - - 0 - U - 46836 - 999 - 434 - .13328E-3 - 4.05E-5 - 0 - - - - -
- -
"#; - - let message: NdmType = from_str(xml).unwrap(); - - println!("{:#?}", message); - assert_eq!( - message, - NdmType { - message_id: Some("bla".to_string()), - comment_list: vec!["asdfg".to_string()], - child_list: vec![ - NdmChildChoice::Omm(omm::OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("".to_string()), - originator: "".to_string(), - message_id: None, - }, - body: omm::OmmBody { - segment: omm::OmmSegment { - metadata: omm::OmmMetadata { - comment_list: vec![], - object_name: "".to_string(), - object_id: "".to_string(), - center_name: "".to_string(), - ref_frame: "".to_string(), - ref_frame_epoch: None, - time_system: "".to_string(), - mean_element_theory: "".to_string(), - }, - data: omm::OmmData { - comment_list: vec![], - mean_elements: omm::MeanElementsType { - comment_list: vec![], - epoch: common::EpochType("".to_string()), - semi_major_axis: None, - mean_motion: None, - eccentricity: common::NonNegativeDouble(0.0), - inclination: common::InclinationType { - base: 0.0, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 0.0, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 0.0, - units: None, - }, - mean_anomaly: common::AngleType { - base: 0.0, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: None, - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }), - NdmChildChoice::Omm(omm::OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("".to_string()), - originator: "".to_string(), - message_id: None, - }, - body: omm::OmmBody { - segment: omm::OmmSegment { - metadata: omm::OmmMetadata { - comment_list: vec![], - object_name: "NUSAT-2 (BATATA)".to_string(), - object_id: "2016-033C".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: omm::OmmData { - comment_list: vec![], - mean_elements: omm::MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2020-12-04T15:27:01.975104".to_string() - ), - semi_major_axis: None, - mean_motion: Some(omm::RevType { - base: 15.30610336, - units: None, - }), - eccentricity: common::NonNegativeDouble(0.001178), - inclination: common::InclinationType { - base: 97.409, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 71.7453, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 193.9419, - units: None, - }, - mean_anomaly: common::AngleType { - base: 272.1492, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: Some(omm::TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0), - classification_type: Some("U".to_string()), - norad_cat_id: Some(41558), - element_set_no: Some(omm::ElementSetNoType( - "999".to_string() - )), - rev_at_epoch: Some(25191), - bstar: Some(omm::BStarType { - base: 0.00015913, - units: None, - }), - bterm: None, - mean_motion_dot: omm::DRevType { - base: 4.64e-5, - units: None, - }, - mean_motion_ddot: Some(omm::DRevType { - base: 0.0, - units: None, - }), - agom: None, - }), - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }), - NdmChildChoice::Opm(opm::OpmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string()), - originator: "me".to_string(), - message_id: None, - }, - body: opm::OpmBody { - segment: opm::OpmSegment { - metadata: opm::OpmMetadata { - comment_list: vec![], - object_name: "Cassini".to_string(), - object_id: "1997-061A".to_string(), - center_name: "Saturn".to_string(), - ref_frame: "IAU-Saturn".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - }, - data: opm::OpmData { - comment_list: vec!["final COMMENT, I think".to_string(),], - state_vector: common::StateVectorType { - comment_list: vec![], - epoch: common::EpochType("2004-100T00:00:00Z".to_string(),), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - }, - keplerian_elements: Some(opm::KeplerianElementsType { - comment_list: vec![], - semi_major_axis: common::DistanceType { - base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), - }, - eccentricity: common::NonNegativeDouble(0.0,), - inclination: common::InclinationType { - base: 45.0, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - ra_of_asc_node: common::AngleType { - base: 0.0, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - arg_of_pericenter: common::AngleType { - base: 15.0, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - true_anomaly: Some(common::AngleType { - base: 15.0, - units: Some(common::AngleUnits("deg".to_string(),),), - },), - mean_anomaly: None, - gm: common::GmType { - base: common::PositiveDouble(398644.0,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), - }, - },), - spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec![], - mass: Some(common::MassType { - base: common::NonNegativeDouble(100.0,), - units: Some(common::MassUnits("kg".to_string(),),), - },), - solar_rad_area: Some(common::AreaType { - base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), - },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), - drag_area: Some(common::AreaType { - base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), - },), - drag_coeff: Some(common::NonNegativeDouble(2.0,),), - },), - covariance_matrix: None, - maneuver_parameters_list: vec![opm::ManeuverParametersType { - comment_list: vec![], - man_epoch_ignition: common::EpochType( - "2004-125T00:00:00Z".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(0.0,), - units: None, - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-1.0,), - units: None, - }, - man_ref_frame: "GRC".to_string(), - man_dv_1: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_2: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_3: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - },], - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OPM_VERS".to_string()), - version: "2.0".to_string(), - },), - NdmChildChoice::Opm(opm::OpmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), - originator: "me".to_string(), - message_id: None, - }, - body: opm::OpmBody { - segment: opm::OpmSegment { - metadata: opm::OpmMetadata { - comment_list: vec![], - object_name: "Cassini".to_string(), - object_id: "1997-061A".to_string(), - center_name: "Saturn".to_string(), - ref_frame: "IAU-Saturn".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - }, - data: opm::OpmData { - comment_list: vec![], - state_vector: common::StateVectorType { - comment_list: vec!["this is a comment".to_string(),], - epoch: common::EpochType("2004-100T00:00:00".to_string(),), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - }, - keplerian_elements: None, - spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec!["This is a COMMENT".to_string(),], - mass: Some(common::MassType { - base: common::NonNegativeDouble(100.0,), - units: None, - },), - solar_rad_area: Some(common::AreaType { - base: common::NonNegativeDouble(2.0,), - units: None, - },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), - drag_area: Some(common::AreaType { - base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), - },), - drag_coeff: Some(common::NonNegativeDouble(2.0,),), - },), - covariance_matrix: None, - maneuver_parameters_list: vec![opm::ManeuverParametersType { - comment_list: vec!["This is a COMMENT".to_string(),], - man_epoch_ignition: common::EpochType( - "2004-125T00:00:00".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(0.0,), - units: Some(common::TimeUnits("s".to_string(),),), - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-1.0,), - units: Some(common::MassUnits("kg".to_string(),),), - }, - man_ref_frame: "GRC".to_string(), - man_dv_1: common::VelocityType { - base: 1.0, - units: None, - }, - man_dv_2: common::VelocityType { - base: 1.0, - units: None, - }, - man_dv_3: common::VelocityType { - base: 1.0, - units: None, - }, - },], - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OPM_VERS".to_string()), - version: "2.0".to_string(), - },), - NdmChildChoice::Oem(oem::OemType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), - originator: "me".to_string(), - message_id: None, - }, - body: oem::OemBody { - segment_list: vec![oem::OemSegment { - metadata: oem::OemMetadata { - comment_list: vec![], - object_name: "Cassini".to_string(), - object_id: "1997-061A".to_string(), - center_name: "Saturn".to_string(), - ref_frame: "IAU-Saturn".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - start_time: common::EpochType( - "2004-100T00:00:00.000000".to_string(), - ), - useable_start_time: None, - useable_stop_time: None, - stop_time: common::EpochType( - "2004-100T01:00:00.000000".to_string(), - ), - interpolation: Some("Hermite".to_string(),), - interpolation_degree: Some(1,), - }, - data: oem::OemData { - comment_list: vec![], - state_vector_list: vec![ - common::StateVectorAccType { - epoch: common::EpochType( - "2004-100T00:00:00".to_string(), - ), - x: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits( - "km".to_string(), - ),), - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits( - "km/s".to_string(), - ),), - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - common::StateVectorAccType { - epoch: common::EpochType( - "2004-100T00:00:00".to_string(), - ), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits( - "km".to_string(), - ),), - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits( - "km/s".to_string(), - ),), - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - common::StateVectorAccType { - epoch: common::EpochType( - "2004-100T00:00:00".to_string(), - ), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits( - "km".to_string(), - ),), - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits( - "km/s".to_string(), - ),), - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - ], - covariance_matrix_list: vec![], - }, - },], - }, - id: "CCSDS_OEM_VERS".to_string(), - version: "2.0".to_string(), - },), - NdmChildChoice::Omm(omm::OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("".to_string()), - originator: "".to_string(), - message_id: None, - }, - body: omm::OmmBody { - segment: omm::OmmSegment { - metadata: omm::OmmMetadata { - comment_list: vec![], - object_name: "NUSAT-13 (EMMY)".to_string(), - object_id: "2020-079G".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: omm::OmmData { - comment_list: vec![], - mean_elements: omm::MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2020-12-04T13:30:01.539648".to_string() - ), - semi_major_axis: None, - mean_motion: Some(omm::RevType { - base: 15.31433655, - units: None, - }), - eccentricity: common::NonNegativeDouble(0.0009574), - inclination: common::InclinationType { - base: 97.2663, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 51.2167, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 149.8567, - units: None, - }, - mean_anomaly: common::AngleType { - base: 322.5146, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: Some(omm::TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0), - classification_type: Some("U".to_string()), - norad_cat_id: Some(46833), - element_set_no: Some(omm::ElementSetNoType( - "999".to_string() - )), - rev_at_epoch: Some(434), - bstar: Some(omm::BStarType { - base: 0.00014401, - units: None, - }), - bterm: None, - mean_motion_dot: omm::DRevType { - base: 4.301e-5, - units: None, - }, - mean_motion_ddot: Some(omm::DRevType { - base: 0.0, - units: None, - }), - agom: None, - }), - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }), - NdmChildChoice::Omm(omm::OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("".to_string()), - originator: "".to_string(), - message_id: None, - }, - body: omm::OmmBody { - segment: omm::OmmSegment { - metadata: omm::OmmMetadata { - comment_list: vec![], - object_name: "NUSAT-17 (MARY)".to_string(), - object_id: "2020-079J".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: omm::OmmData { - comment_list: vec![], - mean_elements: omm::MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2020-12-04T16:27:08.698176".to_string() - ), - semi_major_axis: None, - mean_motion: Some(omm::RevType { - base: 15.31317097, - units: None, - }), - eccentricity: common::NonNegativeDouble(0.0009674), - inclination: common::InclinationType { - base: 97.2671, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 51.3486, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 160.8608, - units: None, - }, - mean_anomaly: common::AngleType { - base: 302.2789, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: Some(omm::TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0), - classification_type: Some("U".to_string()), - norad_cat_id: Some(46835), - element_set_no: Some(omm::ElementSetNoType( - "999".to_string() - )), - rev_at_epoch: Some(436), - bstar: Some(omm::BStarType { - base: -0.00013273, - units: None, - }), - bterm: None, - mean_motion_dot: omm::DRevType { - base: -4.087e-5, - units: None, - }, - mean_motion_ddot: Some(omm::DRevType { - base: 0.0, - units: None, - }), - agom: None, - }), - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }), - NdmChildChoice::Omm(omm::OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("".to_string()), - originator: "".to_string(), - message_id: None, - }, - body: omm::OmmBody { - segment: omm::OmmSegment { - metadata: omm::OmmMetadata { - comment_list: vec![], - object_name: "NUSAT-18 (VERA)".to_string(), - object_id: "2020-079K".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: omm::OmmData { - comment_list: vec![], - mean_elements: omm::MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2020-12-04T13:13:33.140064".to_string() - ), - semi_major_axis: None, - mean_motion: Some(omm::RevType { - base: 15.32037173, - units: None, - }), - eccentricity: common::NonNegativeDouble(0.0009024), - inclination: common::InclinationType { - base: 97.2666, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 51.2301, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 167.2057, - units: None, - }, - mean_anomaly: common::AngleType { - base: 304.5569, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: Some(omm::TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0), - classification_type: Some("U".to_string()), - norad_cat_id: Some(46836), - element_set_no: Some(omm::ElementSetNoType( - "999".to_string() - )), - rev_at_epoch: Some(434), - bstar: Some(omm::BStarType { - base: 0.00013328, - units: None, - }), - bterm: None, - mean_motion_dot: omm::DRevType { - base: 4.05e-5, - units: None, - }, - mean_motion_ddot: Some(omm::DRevType { - base: 0.0, - units: None, - }), - agom: None, - }), - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }), - ], - }, - ); - } -} diff --git a/crates/lox-utils/src/ndm/ocm.rs b/crates/lox-utils/src/ndm/ocm.rs deleted file mode 100644 index 9aba7d7f..00000000 --- a/crates/lox-utils/src/ndm/ocm.rs +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use serde; - -use super::common; - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OcmBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmBody { - #[serde(rename = "segment")] - pub segment: OcmSegment, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmSegment { - #[serde(rename = "metadata")] - pub metadata: OcmMetadata, - #[serde(rename = "data")] - pub data: OcmData, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: Option, - #[serde(rename = "INTERNATIONAL_DESIGNATOR")] - pub international_designator: Option, - #[serde(rename = "CATALOG_NAME")] - pub catalog_name: Option, - #[serde(rename = "OBJECT_DESIGNATOR")] - pub object_designator: Option, - #[serde(rename = "ALTERNATE_NAMES")] - pub alternate_names: Option, - #[serde(rename = "ORIGINATOR_POC")] - pub originator_poc: Option, - #[serde(rename = "ORIGINATOR_POSITION")] - pub originator_position: Option, - #[serde(rename = "ORIGINATOR_PHONE")] - pub originator_phone: Option, - #[serde(rename = "ORIGINATOR_EMAIL")] - pub originator_email: Option, - #[serde(rename = "ORIGINATOR_ADDRESS")] - pub originator_address: Option, - #[serde(rename = "TECH_ORG")] - pub tech_org: Option, - #[serde(rename = "TECH_POC")] - pub tech_poc: Option, - #[serde(rename = "TECH_POSITION")] - pub tech_position: Option, - #[serde(rename = "TECH_PHONE")] - pub tech_phone: Option, - #[serde(rename = "TECH_EMAIL")] - pub tech_email: Option, - #[serde(rename = "TECH_ADDRESS")] - pub tech_address: Option, - #[serde(rename = "PREVIOUS_MESSAGE_ID")] - pub previous_message_id: Option, - #[serde(rename = "NEXT_MESSAGE_ID")] - pub next_message_id: Option, - #[serde(rename = "ADM_MSG_LINK")] - pub adm_msg_link: Option, - #[serde(rename = "CDM_MSG_LINK")] - pub cdm_msg_link: Option, - #[serde(rename = "PRM_MSG_LINK")] - pub prm_msg_link: Option, - #[serde(rename = "RDM_MSG_LINK")] - pub rdm_msg_link: Option, - #[serde(rename = "TDM_MSG_LINK")] - pub tdm_msg_link: Option, - #[serde(rename = "OPERATOR")] - pub operator: Option, - #[serde(rename = "OWNER")] - pub owner: Option, - #[serde(rename = "COUNTRY")] - pub country: Option, - #[serde(rename = "CONSTELLATION")] - pub constellation: Option, - #[serde(rename = "OBJECT_TYPE")] - pub object_type: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "EPOCH_TZERO")] - pub epoch_tzero: common::EpochType, - #[serde(rename = "OPS_STATUS")] - pub ops_status: Option, - #[serde(rename = "ORBIT_CATEGORY")] - pub orbit_category: Option, - #[serde(rename = "OCM_DATA_ELEMENTS")] - pub ocm_data_elements: Option, - #[serde(rename = "SCLK_OFFSET_AT_EPOCH")] - pub sclk_offset_at_epoch: Option, - #[serde(rename = "SCLK_SEC_PER_SI_SEC")] - pub sclk_sec_per_si_sec: Option, - #[serde(rename = "PREVIOUS_MESSAGE_EPOCH")] - pub previous_message_epoch: Option, - #[serde(rename = "NEXT_MESSAGE_EPOCH")] - pub next_message_epoch: Option, - #[serde(rename = "START_TIME")] - pub start_time: Option, - #[serde(rename = "STOP_TIME")] - pub stop_time: Option, - #[serde(rename = "TIME_SPAN")] - pub time_span: Option, - #[serde(rename = "TAIMUTC_AT_TZERO")] - pub taimutc_at_tzero: Option, - #[serde(rename = "NEXT_LEAP_EPOCH")] - pub next_leap_epoch: Option, - #[serde(rename = "NEXT_LEAP_TAIMUTC")] - pub next_leap_taimutc: Option, - #[serde(rename = "UT1MUTC_AT_TZERO")] - pub ut1mutc_at_tzero: Option, - #[serde(rename = "EOP_SOURCE")] - pub eop_source: Option, - #[serde(rename = "INTERP_METHOD_EOP")] - pub interp_method_eop: Option, - #[serde(rename = "CELESTIAL_SOURCE")] - pub celestial_source: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmData { - #[serde(rename = "traj")] - pub traj_list: Vec, - #[serde(rename = "phys")] - pub phys: Option, - #[serde(rename = "cov")] - pub cov_list: Vec, - #[serde(rename = "man")] - pub man_list: Vec, - #[serde(rename = "pert")] - pub pert: Option, - #[serde(rename = "od")] - pub od: Option, - #[serde(rename = "user")] - pub user: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmTrajStateType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "TRAJ_ID")] - pub traj_id: Option, - #[serde(rename = "TRAJ_PREV_ID")] - pub traj_prev_id: Option, - #[serde(rename = "TRAJ_NEXT_ID")] - pub traj_next_id: Option, - #[serde(rename = "TRAJ_BASIS")] - pub traj_basis: Option, - #[serde(rename = "TRAJ_BASIS_ID")] - pub traj_basis_id: Option, - #[serde(rename = "INTERPOLATION")] - pub interpolation: Option, - #[serde(rename = "INTERPOLATION_DEGREE")] - pub interpolation_degree: Option, - #[serde(rename = "PROPAGATOR")] - pub propagator: Option, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "TRAJ_REF_FRAME")] - pub traj_ref_frame: String, - #[serde(rename = "TRAJ_FRAME_EPOCH")] - pub traj_frame_epoch: Option, - #[serde(rename = "USEABLE_START_TIME")] - pub useable_start_time: Option, - #[serde(rename = "USEABLE_STOP_TIME")] - pub useable_stop_time: Option, - #[serde(rename = "ORB_REVNUM")] - pub orb_revnum: Option, - #[serde(rename = "ORB_REVNUM_BASIS")] - pub orb_revnum_basis: Option, - #[serde(rename = "TRAJ_TYPE")] - pub traj_type: String, - #[serde(rename = "ORB_AVERAGING")] - pub orb_averaging: Option, - #[serde(rename = "TRAJ_UNITS")] - pub traj_units: Option, - #[serde(rename = "trajLine")] - pub traj_line_list: Vec, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmPhysicalDescriptionType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MANUFACTURER")] - pub manufacturer: Option, - #[serde(rename = "BUS_MODEL")] - pub bus_model: Option, - #[serde(rename = "DOCKED_WITH")] - pub docked_with: Option, - #[serde(rename = "DRAG_CONST_AREA")] - pub drag_const_area: Option, - #[serde(rename = "DRAG_COEFF_NOM")] - pub drag_coeff_nom: Option, - #[serde(rename = "DRAG_UNCERTAINTY")] - pub drag_uncertainty: Option, - #[serde(rename = "INITIAL_WET_MASS")] - pub initial_wet_mass: Option, - #[serde(rename = "WET_MASS")] - pub wet_mass: Option, - #[serde(rename = "DRY_MASS")] - pub dry_mass: Option, - #[serde(rename = "OEB_PARENT_FRAME")] - pub oeb_parent_frame: Option, - #[serde(rename = "OEB_PARENT_FRAME_EPOCH")] - pub oeb_parent_frame_epoch: Option, - #[serde(rename = "OEB_Q1")] - pub oeb_q1: Option, - #[serde(rename = "OEB_Q2")] - pub oeb_q2: Option, - #[serde(rename = "OEB_Q3")] - pub oeb_q3: Option, - #[serde(rename = "OEB_QC")] - pub oeb_qc: Option, - #[serde(rename = "OEB_MAX")] - pub oeb_max: Option, - #[serde(rename = "OEB_INT")] - pub oeb_int: Option, - #[serde(rename = "OEB_MIN")] - pub oeb_min: Option, - #[serde(rename = "AREA_ALONG_OEB_MAX")] - pub area_along_oeb_max: Option, - #[serde(rename = "AREA_ALONG_OEB_INT")] - pub area_along_oeb_int: Option, - #[serde(rename = "AREA_ALONG_OEB_MIN")] - pub area_along_oeb_min: Option, - #[serde(rename = "AREA_MIN_FOR_PC")] - pub area_min_for_pc: Option, - #[serde(rename = "AREA_MAX_FOR_PC")] - pub area_max_for_pc: Option, - #[serde(rename = "AREA_TYP_FOR_PC")] - pub area_typ_for_pc: Option, - #[serde(rename = "RCS")] - pub rcs: Option, - #[serde(rename = "RCS_MIN")] - pub rcs_min: Option, - #[serde(rename = "RCS_MAX")] - pub rcs_max: Option, - #[serde(rename = "SRP_CONST_AREA")] - pub srp_const_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "SOLAR_RAD_UNCERTAINTY")] - pub solar_rad_uncertainty: Option, - #[serde(rename = "VM_ABSOLUTE")] - pub vm_absolute: Option, - #[serde(rename = "VM_APPARENT_MIN")] - pub vm_apparent_min: Option, - #[serde(rename = "VM_APPARENT")] - pub vm_apparent: Option, - #[serde(rename = "VM_APPARENT_MAX")] - pub vm_apparent_max: Option, - #[serde(rename = "REFLECTANCE")] - pub reflectance: Option, - #[serde(rename = "ATT_CONTROL_MODE")] - pub att_control_mode: Option, - #[serde(rename = "ATT_ACTUATOR_TYPE")] - pub att_actuator_type: Option, - #[serde(rename = "ATT_KNOWLEDGE")] - pub att_knowledge: Option, - #[serde(rename = "ATT_CONTROL")] - pub att_control: Option, - #[serde(rename = "ATT_POINTING")] - pub att_pointing: Option, - #[serde(rename = "AVG_MANEUVER_FREQ")] - pub avg_maneuver_freq: Option, - #[serde(rename = "MAX_THRUST")] - pub max_thrust: Option, - #[serde(rename = "DV_BOL")] - pub dv_bol: Option, - #[serde(rename = "DV_REMAINING")] - pub dv_remaining: Option, - #[serde(rename = "IXX")] - pub ixx: Option, - #[serde(rename = "IYY")] - pub iyy: Option, - #[serde(rename = "IZZ")] - pub izz: Option, - #[serde(rename = "IXY")] - pub ixy: Option, - #[serde(rename = "IXZ")] - pub ixz: Option, - #[serde(rename = "IYZ")] - pub iyz: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmCovarianceMatrixType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "COV_ID")] - pub cov_id: Option, - #[serde(rename = "COV_PREV_ID")] - pub cov_prev_id: Option, - #[serde(rename = "COV_NEXT_ID")] - pub cov_next_id: Option, - #[serde(rename = "COV_BASIS")] - pub cov_basis: Option, - #[serde(rename = "COV_BASIS_ID")] - pub cov_basis_id: Option, - #[serde(rename = "COV_REF_FRAME")] - pub cov_ref_frame: String, - #[serde(rename = "COV_FRAME_EPOCH")] - pub cov_frame_epoch: Option, - #[serde(rename = "COV_SCALE_MIN")] - pub cov_scale_min: Option, - #[serde(rename = "COV_SCALE_MAX")] - pub cov_scale_max: Option, - #[serde(rename = "COV_CONFIDENCE")] - pub cov_confidence: Option, - #[serde(rename = "COV_TYPE")] - pub cov_type: String, - #[serde(rename = "COV_ORDERING")] - pub cov_ordering: common::CovOrderType, - #[serde(rename = "COV_UNITS")] - pub cov_units: Option, - #[serde(rename = "covLine")] - pub cov_line_list: Vec, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmManeuverParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MAN_ID")] - pub man_id: String, - #[serde(rename = "MAN_PREV_ID")] - pub man_prev_id: Option, - #[serde(rename = "MAN_NEXT_ID")] - pub man_next_id: Option, - #[serde(rename = "MAN_BASIS")] - pub man_basis: Option, - #[serde(rename = "MAN_BASIS_ID")] - pub man_basis_id: Option, - #[serde(rename = "MAN_DEVICE_ID")] - pub man_device_id: String, - #[serde(rename = "MAN_PREV_EPOCH")] - pub man_prev_epoch: Option, - #[serde(rename = "MAN_NEXT_EPOCH")] - pub man_next_epoch: Option, - #[serde(rename = "MAN_PURPOSE")] - pub man_purpose: Option, - #[serde(rename = "MAN_PRED_SOURCE")] - pub man_pred_source: Option, - #[serde(rename = "MAN_REF_FRAME")] - pub man_ref_frame: String, - #[serde(rename = "MAN_FRAME_EPOCH")] - pub man_frame_epoch: Option, - #[serde(rename = "GRAV_ASSIST_NAME")] - pub grav_assist_name: Option, - #[serde(rename = "DC_TYPE")] - pub dc_type: common::ManDcType, - #[serde(rename = "DC_WIN_OPEN")] - pub dc_win_open: Option, - #[serde(rename = "DC_WIN_CLOSE")] - pub dc_win_close: Option, - #[serde(rename = "DC_MIN_CYCLES")] - pub dc_min_cycles: Option, - #[serde(rename = "DC_MAX_CYCLES")] - pub dc_max_cycles: Option, - #[serde(rename = "DC_EXEC_START")] - pub dc_exec_start: Option, - #[serde(rename = "DC_EXEC_STOP")] - pub dc_exec_stop: Option, - #[serde(rename = "DC_REF_TIME")] - pub dc_ref_time: Option, - #[serde(rename = "DC_TIME_PULSE_DURATION")] - pub dc_time_pulse_duration: Option, - #[serde(rename = "DC_TIME_PULSE_PERIOD")] - pub dc_time_pulse_period: Option, - #[serde(rename = "DC_REF_DIR")] - pub dc_ref_dir: Option, - #[serde(rename = "DC_BODY_FRAME")] - pub dc_body_frame: Option, - #[serde(rename = "DC_BODY_TRIGGER")] - pub dc_body_trigger: Option, - #[serde(rename = "DC_PA_START_ANGLE")] - pub dc_pa_start_angle: Option, - #[serde(rename = "DC_PA_STOP_ANGLE")] - pub dc_pa_stop_angle: Option, - #[serde(rename = "MAN_COMPOSITION")] - pub man_composition: String, - #[serde(rename = "MAN_UNITS")] - pub man_units: Option, - #[serde(rename = "manLine")] - pub man_line_list: Vec, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmPerturbationsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "ATMOSPHERIC_MODEL")] - pub atmospheric_model: Option, - #[serde(rename = "GRAVITY_MODEL")] - pub gravity_model: Option, - #[serde(rename = "EQUATORIAL_RADIUS")] - pub equatorial_radius: Option, - #[serde(rename = "GM")] - pub gm: Option, - #[serde(rename = "N_BODY_PERTURBATIONS")] - pub n_body_perturbations: Option, - #[serde(rename = "CENTRAL_BODY_ROTATION")] - pub central_body_rotation: Option, - #[serde(rename = "OBLATE_FLATTENING")] - pub oblate_flattening: Option, - #[serde(rename = "OCEAN_TIDES_MODEL")] - pub ocean_tides_model: Option, - #[serde(rename = "SOLID_TIDES_MODEL")] - pub solid_tides_model: Option, - #[serde(rename = "REDUCTION_THEORY")] - pub reduction_theory: Option, - #[serde(rename = "ALBEDO_MODEL")] - pub albedo_model: Option, - #[serde(rename = "ALBEDO_GRID_SIZE")] - pub albedo_grid_size: Option, - #[serde(rename = "SHADOW_MODEL")] - pub shadow_model: Option, - #[serde(rename = "SHADOW_BODIES")] - pub shadow_bodies: Option, - #[serde(rename = "SRP_MODEL")] - pub srp_model: Option, - #[serde(rename = "SW_DATA_SOURCE")] - pub sw_data_source: Option, - #[serde(rename = "SW_DATA_EPOCH")] - pub sw_data_epoch: Option, - #[serde(rename = "SW_INTERP_METHOD")] - pub sw_interp_method: Option, - #[serde(rename = "FIXED_GEOMAG_KP")] - pub fixed_geomag_kp: Option, - #[serde(rename = "FIXED_GEOMAG_AP")] - pub fixed_geomag_ap: Option, - #[serde(rename = "FIXED_GEOMAG_DST")] - pub fixed_geomag_dst: Option, - #[serde(rename = "FIXED_F10P7")] - pub fixed_f10p7: Option, - #[serde(rename = "FIXED_F10P7_MEAN")] - pub fixed_f10p7_mean: Option, - #[serde(rename = "FIXED_M10P7")] - pub fixed_m10p7: Option, - #[serde(rename = "FIXED_M10P7_MEAN")] - pub fixed_m10p7_mean: Option, - #[serde(rename = "FIXED_S10P7")] - pub fixed_s10p7: Option, - #[serde(rename = "FIXED_S10P7_MEAN")] - pub fixed_s10p7_mean: Option, - #[serde(rename = "FIXED_Y10P7")] - pub fixed_y10p7: Option, - #[serde(rename = "FIXED_Y10P7_MEAN")] - pub fixed_y10p7_mean: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OcmOdParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OD_ID")] - pub od_id: String, - #[serde(rename = "OD_PREV_ID")] - pub od_prev_id: Option, - #[serde(rename = "OD_METHOD")] - pub od_method: String, - #[serde(rename = "OD_EPOCH")] - pub od_epoch: common::EpochType, - #[serde(rename = "DAYS_SINCE_FIRST_OBS")] - pub days_since_first_obs: Option, - #[serde(rename = "DAYS_SINCE_LAST_OBS")] - pub days_since_last_obs: Option, - #[serde(rename = "RECOMMENDED_OD_SPAN")] - pub recommended_od_span: Option, - #[serde(rename = "ACTUAL_OD_SPAN")] - pub actual_od_span: Option, - #[serde(rename = "OBS_AVAILABLE")] - pub obs_available: Option, - #[serde(rename = "OBS_USED")] - pub obs_used: Option, - #[serde(rename = "TRACKS_AVAILABLE")] - pub tracks_available: Option, - #[serde(rename = "TRACKS_USED")] - pub tracks_used: Option, - #[serde(rename = "MAXIMUM_OBS_GAP")] - pub maximum_obs_gap: Option, - #[serde(rename = "OD_EPOCH_EIGMAJ")] - pub od_epoch_eigmaj: Option, - #[serde(rename = "OD_EPOCH_EIGINT")] - pub od_epoch_eigint: Option, - #[serde(rename = "OD_EPOCH_EIGMIN")] - pub od_epoch_eigmin: Option, - #[serde(rename = "OD_MAX_PRED_EIGMAJ")] - pub od_max_pred_eigmaj: Option, - #[serde(rename = "OD_MIN_PRED_EIGMIN")] - pub od_min_pred_eigmin: Option, - #[serde(rename = "OD_CONFIDENCE")] - pub od_confidence: Option, - #[serde(rename = "GDOP")] - pub gdop: Option, - #[serde(rename = "SOLVE_N")] - pub solve_n: Option, - #[serde(rename = "SOLVE_STATES")] - pub solve_states: Option, - #[serde(rename = "CONSIDER_N")] - pub consider_n: Option, - #[serde(rename = "CONSIDER_PARAMS")] - pub consider_params: Option, - #[serde(rename = "SEDR")] - pub sedr: Option, - #[serde(rename = "SENSORS_N")] - pub sensors_n: Option, - #[serde(rename = "SENSORS")] - pub sensors: Option, - #[serde(rename = "WEIGHTED_RMS")] - pub weighted_rms: Option, - #[serde(rename = "DATA_TYPES")] - pub data_types: Option, -} - -mod test { - use super::*; - - use quick_xml::de::from_str; - - #[test] - fn test_parse_ocm_message() { - let xml = r#" - -
- ODM V.3 Example G-2 - OCM example with space object characteristics and perturbations. - This OCM reflects the latest conditions post-maneuver A67Z - This example shows the specification of multiple comment lines - 1998-11-06T09:23:57 - JAXA - OCM 201113719185 -
- - - - 1998-999A - R. Rabbit - Flight Dynamics Mission Design Lead - (719)555-1234 - Mr. Rodgers - (719)555-1234 - email@email.XXX - UT1 - 1998-12-18T00:00:00.0000 - 36 - .357 - - - - GEOCENTRIC, CARTESIAN, EARTH FIXED - THIS IS MY SECOND COMMENT LINE - PREDICTED - EFG - CARTPVA - 0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070 - - - Spacecraft Physical Characteristics - 100.0 - 0.03123 - 0.78543 - 0.39158 - 0.47832 - 2.0 - 1.0 - 0.5 - 0.15 - 0.3 - 0.5 - - - Perturbations Specification - NRLMSIS00 - EGM-96: 36D 36O - 398600.4415 - MOON, SUN - 12.0 - 105.0 - 120.0 - - - WGS-84 - - - - -
"#; - - let message: OcmType = from_str(xml).unwrap(); - - assert_eq!(message, OcmType { - header: common::OdmHeader { - comment_list: vec![ - "ODM V.3 Example G-2".to_string(), - "OCM example with space object characteristics and perturbations.".to_string(), - "This OCM reflects the latest conditions post-maneuver A67Z".to_string(), - "This example shows the specification of multiple comment lines".to_string(), - ], - classification_list: vec![], - creation_date: common::EpochType( - "1998-11-06T09:23:57".to_string(), - ), - originator: "JAXA".to_string(), - message_id: Some( - "OCM 201113719185".to_string(), - ), - }, - body: OcmBody { - segment: OcmSegment { - metadata: OcmMetadata { - comment_list: vec![], - object_name: None, - international_designator: Some( - "1998-999A".to_string(), - ), - catalog_name: None, - object_designator: None, - alternate_names: None, - originator_poc: Some( - "R. Rabbit".to_string(), - ), - originator_position: Some( - "Flight Dynamics Mission Design Lead".to_string(), - ), - originator_phone: Some( - "(719)555-1234".to_string(), - ), - originator_email: None, - originator_address: None, - tech_org: None, - tech_poc: Some( - "Mr. Rodgers".to_string(), - ), - tech_position: None, - tech_phone: Some( - "(719)555-1234".to_string(), - ), - tech_email: None, - tech_address: Some( - "email@email.XXX".to_string(), - ), - previous_message_id: None, - next_message_id: None, - adm_msg_link: None, - cdm_msg_link: None, - prm_msg_link: None, - rdm_msg_link: None, - tdm_msg_link: None, - operator: None, - owner: None, - country: None, - constellation: None, - object_type: None, - time_system: "UT1".to_string(), - epoch_tzero: common::EpochType( - "1998-12-18T00:00:00.0000".to_string(), - ), - ops_status: None, - orbit_category: None, - ocm_data_elements: None, - sclk_offset_at_epoch: None, - sclk_sec_per_si_sec: None, - previous_message_epoch: None, - next_message_epoch: None, - start_time: None, - stop_time: None, - time_span: None, - taimutc_at_tzero: Some( - common::TimeOffsetType { - base: 36.0, - units: Some( - common::TimeUnits( - "s".to_string(), - ), - ), - }, - ), - next_leap_epoch: None, - next_leap_taimutc: None, - ut1mutc_at_tzero: Some( - common::TimeOffsetType { - base: 0.357, - units: Some( - common::TimeUnits( - "s".to_string(), - ), - ), - }, - ), - eop_source: None, - interp_method_eop: None, - celestial_source: None, - }, - data: OcmData { - traj_list: vec![ - OcmTrajStateType { - comment_list: vec![ - "GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(), - "THIS IS MY SECOND COMMENT LINE".to_string(), - ], - traj_id: None, - traj_prev_id: None, - traj_next_id: None, - traj_basis: Some( - common::TrajBasisType( - "PREDICTED".to_string(), - ), - ), - traj_basis_id: None, - interpolation: None, - interpolation_degree: None, - propagator: None, - center_name: "".to_string(), - traj_ref_frame: "EFG".to_string(), - traj_frame_epoch: None, - useable_start_time: None, - useable_stop_time: None, - orb_revnum: None, - orb_revnum_basis: None, - traj_type: "CARTPVA".to_string(), - orb_averaging: None, - traj_units: None, - traj_line_list: vec![ - "0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070".to_string(), - ], - }, - ], - phys: Some( - OcmPhysicalDescriptionType { - comment_list: vec![ - "Spacecraft Physical Characteristics".to_string(), - ], - manufacturer: None, - bus_model: None, - docked_with: None, - drag_const_area: None, - drag_coeff_nom: None, - drag_uncertainty: None, - initial_wet_mass: None, - wet_mass: Some( - common::MassType { - base: common::NonNegativeDouble( - 100.0, - ), - units: Some( - common::MassUnits( - "kg".to_string(), - ), - ), - }, - ), - dry_mass: None, - oeb_parent_frame: None, - oeb_parent_frame_epoch: None, - oeb_q1: Some( - 0.03123, - ), - oeb_q2: Some( - 0.78543, - ), - oeb_q3: Some( - 0.39158, - ), - oeb_qc: Some( - 0.47832, - ), - oeb_max: Some( - common::OcmLengthType { - base: 2.0, - units: Some( - common::LengthUnits( - "m".to_string(), - ), - ), - }, - ), - oeb_int: Some( - common::OcmLengthType { - base: 1.0, - units: Some( - common::LengthUnits( - "m".to_string(), - ), - ), - }, - ), - oeb_min: Some( - common::OcmLengthType { - base: 0.5, - units: Some( - common::LengthUnits( - "m".to_string(), - ), - ), - }, - ), - area_along_oeb_max: Some( - common::AreaType { - base: common::NonNegativeDouble( - 0.15, - ), - units: Some( - common::AreaUnits( - "m**2".to_string(), - ), - ), - }, - ), - area_along_oeb_int: Some( - common::AreaType { - base: common::NonNegativeDouble( - 0.3, - ), - units: Some( - common::AreaUnits( - "m**2".to_string(), - ), - ), - }, - ), - area_along_oeb_min: Some( - common::AreaType { - base: common::NonNegativeDouble( - 0.5, - ), - units: Some( - common::AreaUnits( - "m**2".to_string(), - ), - ), - }, - ), - area_min_for_pc: None, - area_max_for_pc: None, - area_typ_for_pc: None, - rcs: None, - rcs_min: None, - rcs_max: None, - srp_const_area: None, - solar_rad_coeff: None, - solar_rad_uncertainty: None, - vm_absolute: None, - vm_apparent_min: None, - vm_apparent: None, - vm_apparent_max: None, - reflectance: None, - att_control_mode: None, - att_actuator_type: None, - att_knowledge: None, - att_control: None, - att_pointing: None, - avg_maneuver_freq: None, - max_thrust: None, - dv_bol: None, - dv_remaining: None, - ixx: None, - iyy: None, - izz: None, - ixy: None, - ixz: None, - iyz: None, - }, - ), - cov_list: vec![], - man_list: vec![], - pert: Some( - OcmPerturbationsType { - comment_list: vec![ - "Perturbations Specification".to_string(), - ], - atmospheric_model: Some( - "NRLMSIS00".to_string(), - ), - gravity_model: Some( - "EGM-96: 36D 36O".to_string(), - ), - equatorial_radius: None, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.4415, - ), - units: Some( - common::GmUnits( - "km**3/s**2".to_string(), - ), - ), - }, - ), - n_body_perturbations: Some( - "MOON, SUN".to_string(), - ), - central_body_rotation: None, - oblate_flattening: None, - ocean_tides_model: None, - solid_tides_model: None, - reduction_theory: None, - albedo_model: None, - albedo_grid_size: None, - shadow_model: None, - shadow_bodies: None, - srp_model: None, - sw_data_source: None, - sw_data_epoch: None, - sw_interp_method: None, - fixed_geomag_kp: Some( - common::GeomagType { - base: 12.0, - units: None, - }, - ), - fixed_geomag_ap: None, - fixed_geomag_dst: None, - fixed_f10p7: Some( - common::SolarFluxType { - base: 105.0, - units: None, - }, - ), - fixed_f10p7_mean: Some( - common::SolarFluxType { - base: 120.0, - units: None, - }, - ), - fixed_m10p7: None, - fixed_m10p7_mean: None, - fixed_s10p7: None, - fixed_s10p7_mean: None, - fixed_y10p7: None, - fixed_y10p7_mean: None, - }, - ), - od: None, - user: Some( - common::UserDefinedType { - comment_list: vec![], - user_defined_list: vec![ - common::UserDefinedParameterType { - base: "WGS-84".to_string(), - parameter: "EARTH_MODEL".to_string(), - }, - ], - }, - ), - }, - }, - }, - id: "CCSDS_OCM_VERS".to_string(), - version: "3.0".to_string(), - }); - } -} diff --git a/crates/lox-utils/src/ndm/oem.rs b/crates/lox-utils/src/ndm/oem.rs deleted file mode 100644 index 0158b8ee..00000000 --- a/crates/lox-utils/src/ndm/oem.rs +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use serde; - -use super::common; - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OemBody, - #[serde(rename = "@id")] - pub id: String, - #[serde(rename = "@version")] - pub version: String, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemBody { - #[serde(rename = "segment")] - pub segment_list: Vec, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemSegment { - #[serde(rename = "metadata")] - pub metadata: OemMetadata, - #[serde(rename = "data")] - pub data: OemData, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "START_TIME")] - pub start_time: common::EpochType, - #[serde(rename = "USEABLE_START_TIME")] - pub useable_start_time: Option, - #[serde(rename = "USEABLE_STOP_TIME")] - pub useable_stop_time: Option, - #[serde(rename = "STOP_TIME")] - pub stop_time: common::EpochType, - #[serde(rename = "INTERPOLATION")] - pub interpolation: Option, - #[serde(rename = "INTERPOLATION_DEGREE")] - pub interpolation_degree: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct OemData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "stateVector")] - pub state_vector_list: Vec, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix_list: Vec, -} - -#[cfg(test)] -mod test { - use super::*; - - use quick_xml::de::from_str; - - #[test] - fn test_parse_oem_message1() { - let xml = r#" - - -
- 2004-281T17:26:06 - me -
- - - - Cassini - 1997-061A - Saturn - IAU-Saturn - UTC - 2004-100T00:00:00.000000 - 2004-100T01:00:00.000000 - Hermite - 1 - - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - 2004-100T00:00:00 - 1 - 1 - 1 - 1 - 1 - 1 - - - - -
"#; - - let message: OemType = from_str(xml).unwrap(); - - assert_eq!( - message, - OemType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), - originator: "me".to_string(), - message_id: None, - }, - body: OemBody { - segment_list: vec![OemSegment { - metadata: OemMetadata { - comment_list: vec![], - object_name: "Cassini".to_string(), - object_id: "1997-061A".to_string(), - center_name: "Saturn".to_string(), - ref_frame: "IAU-Saturn".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - start_time: common::EpochType("2004-100T00:00:00.000000".to_string(),), - useable_start_time: None, - useable_stop_time: None, - stop_time: common::EpochType("2004-100T01:00:00.000000".to_string(),), - interpolation: Some("Hermite".to_string(),), - interpolation_degree: Some(1,), - }, - data: OemData { - comment_list: vec![], - state_vector_list: vec![ - common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), - x: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), - }, - z: common::PositionType { - base: 1.0, - units: None, - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - z_dot: common::VelocityType { - base: 1.0, - units: None, - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), - x: common::PositionType { - base: 1.0, - units: None, - }, - y: common::PositionType { - base: 1.0, - units: None, - }, - z: common::PositionType { - base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), - }, - x_dot: common::VelocityType { - base: 1.0, - units: None, - }, - y_dot: common::VelocityType { - base: 1.0, - units: None, - }, - z_dot: common::VelocityType { - base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - x_ddot: None, - y_ddot: None, - z_ddot: None, - }, - ], - covariance_matrix_list: vec![], - }, - },], - }, - id: "CCSDS_OEM_VERS".to_string(), - version: "2.0".to_string(), - } - ); - } - - #[test] - fn test_parse_oem_message2() { - let xml = r#" - - -
- OEM WITH OPTIONAL ACCELERATIONS - 1996-11-04T17:22:31 - NASA/JPL - OEM 201113719185 -
- - - - MARS GLOBAL SURVEYOR - 2000-028A - MARS BARYCENTER - J2000 - UTC - 1996-12-18T12:00:00.331 - 1996-12-18T12:10:00.331 - 1996-12-28T21:23:00.331 - 1996-12-28T21:28:00.331 - HERMITE - 7 - - - Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is - to be used for DSN scheduling purposes only. - - 1996-12-18T12:00:00.331 - 2789.6 - -280.0 - -1746.8 - 4.73 - -2.50 - -1.04 - 0.008 - 0.001 - -0.159 - - - 1996-12-18T12:01:00.331 - 2783.4 - -308.1 - -1877.1 - 5.19 - -2.42 - -2.00 - 0.008 - 0.001 - 0.001 - - - 1996-12-18T12:02:00.331 - 2776.0 - -336.9 - -2008.7 - 5.64 - -2.34 - -1.95 - 0.008 - 0.001 - 0.159 - - - 1996-12-28T21:28:00.331 - -3881.0 - 564.0 - -682.8 - -3.29 - -3.67 - 1.64 - -0.003 - 0.000 - 0.000 - - - blabla - 1996-12-28T22:28:00.331 - ITRF1997 - 0.316 - 0.722 - 0.518 - 0.202 - 0.715 - 0.002 - 0.912 - 0.306 - 0.276 - 0.797 - 0.562 - 0.899 - 0.022 - 0.079 - 0.415 - 0.245 - 0.965 - 0.950 - 0.435 - 0.621 - 0.991 - - - - -
"#; - - let message: OemType = from_str(xml).unwrap(); - - assert_eq!( - message, - OemType { - header: common::OdmHeader { - comment_list: vec!["OEM WITH OPTIONAL ACCELERATIONS".to_string(),], - classification_list: vec![], - creation_date: common::EpochType("1996-11-04T17:22:31".to_string(),), - originator: "NASA/JPL".to_string(), - message_id: Some("OEM 201113719185".to_string(),), - }, - body: OemBody { - segment_list: vec![OemSegment { - metadata: OemMetadata { - comment_list: vec![], - object_name: "MARS GLOBAL SURVEYOR".to_string(), - object_id: "2000-028A".to_string(), - center_name: "MARS BARYCENTER".to_string(), - ref_frame: "J2000".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - start_time: common::EpochType("1996-12-18T12:00:00.331".to_string(),), - useable_start_time: Some(common::EpochType( - "1996-12-18T12:10:00.331".to_string(), - ),), - useable_stop_time: Some(common::EpochType( - "1996-12-28T21:23:00.331".to_string(), - ),), - stop_time: common::EpochType("1996-12-28T21:28:00.331".to_string(),), - interpolation: Some("HERMITE".to_string(),), - interpolation_degree: Some(7,), - }, - data: OemData { - comment_list: vec![ - "Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is" - .to_string(), - "to be used for DSN scheduling purposes only.".to_string(), - ], - state_vector_list: vec![ - common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:00:00.331".to_string(),), - x: common::PositionType { - base: 2789.6, - units: None, - }, - y: common::PositionType { - base: -280.0, - units: None, - }, - z: common::PositionType { - base: -1746.8, - units: None, - }, - x_dot: common::VelocityType { - base: 4.73, - units: None, - }, - y_dot: common::VelocityType { - base: -2.5, - units: None, - }, - z_dot: common::VelocityType { - base: -1.04, - units: None, - }, - x_ddot: Some(common::AccType { - base: 0.008, - units: None, - },), - y_ddot: Some(common::AccType { - base: 0.001, - units: None, - },), - z_ddot: Some(common::AccType { - base: -0.159, - units: None, - },), - }, - common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:01:00.331".to_string(),), - x: common::PositionType { - base: 2783.4, - units: None, - }, - y: common::PositionType { - base: -308.1, - units: None, - }, - z: common::PositionType { - base: -1877.1, - units: None, - }, - x_dot: common::VelocityType { - base: 5.19, - units: None, - }, - y_dot: common::VelocityType { - base: -2.42, - units: None, - }, - z_dot: common::VelocityType { - base: -2.0, - units: None, - }, - x_ddot: Some(common::AccType { - base: 0.008, - units: None, - },), - y_ddot: Some(common::AccType { - base: 0.001, - units: None, - },), - z_ddot: Some(common::AccType { - base: 0.001, - units: None, - },), - }, - common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:02:00.331".to_string(),), - x: common::PositionType { - base: 2776.0, - units: None, - }, - y: common::PositionType { - base: -336.9, - units: None, - }, - z: common::PositionType { - base: -2008.7, - units: None, - }, - x_dot: common::VelocityType { - base: 5.64, - units: None, - }, - y_dot: common::VelocityType { - base: -2.34, - units: None, - }, - z_dot: common::VelocityType { - base: -1.95, - units: None, - }, - x_ddot: Some(common::AccType { - base: 0.008, - units: None, - },), - y_ddot: Some(common::AccType { - base: 0.001, - units: None, - },), - z_ddot: Some(common::AccType { - base: 0.159, - units: None, - },), - }, - common::StateVectorAccType { - epoch: common::EpochType("1996-12-28T21:28:00.331".to_string(),), - x: common::PositionType { - base: -3881.0, - units: None, - }, - y: common::PositionType { - base: 564.0, - units: None, - }, - z: common::PositionType { - base: -682.8, - units: None, - }, - x_dot: common::VelocityType { - base: -3.29, - units: None, - }, - y_dot: common::VelocityType { - base: -3.67, - units: None, - }, - z_dot: common::VelocityType { - base: 1.64, - units: None, - }, - x_ddot: Some(common::AccType { - base: -0.003, - units: None, - },), - y_ddot: Some(common::AccType { - base: 0.0, - units: None, - },), - z_ddot: Some(common::AccType { - base: 0.0, - units: None, - },), - }, - ], - covariance_matrix_list: vec![common::OemCovarianceMatrixType { - comment_list: vec!["blabla".to_string(),], - epoch: common::EpochType("1996-12-28T22:28:00.331".to_string(),), - cov_ref_frame: Some("ITRF1997".to_string(),), - cx_x: common::PositionCovarianceType { - base: 0.316, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.722, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.518, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: 0.202, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: 0.715, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.002, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: 0.912, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: 0.306, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 0.276, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 0.797, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: 0.562, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: 0.899, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 0.022, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 0.079, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 0.415, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: 0.245, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: 0.965, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 0.95, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 0.435, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 0.621, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 0.991, - units: None, - }, - },], - }, - },], - }, - id: "CCSDS_OEM_VERS".to_string(), - version: "3.0".to_string(), - } - ); - } -} diff --git a/crates/lox-utils/src/ndm/omm.rs b/crates/lox-utils/src/ndm/omm.rs deleted file mode 100644 index e7887aba..00000000 --- a/crates/lox-utils/src/ndm/omm.rs +++ /dev/null @@ -1,1697 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use serde; - -use crate::ndm::kvn::parser::KvnDeserializer; - -use super::common; - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct BStarUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct BTermUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct AgomUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ElementSetNoType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct RevUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct DRevUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct DdRevUnits(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct SpacewarnType(#[serde(rename = "$text")] pub String); - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OmmType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OmmBody, - #[serde(rename = "@id")] - pub id: Option, - #[serde(rename = "@version")] - pub version: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OmmBody { - #[serde(rename = "segment")] - pub segment: OmmSegment, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OmmSegment { - #[serde(rename = "metadata")] - pub metadata: OmmMetadata, - #[serde(rename = "data")] - pub data: OmmData, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OmmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, - #[serde(rename = "MEAN_ELEMENT_THEORY")] - pub mean_element_theory: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OmmData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "meanElements")] - pub mean_elements: MeanElementsType, - #[serde(rename = "spacecraftParameters")] - pub spacecraft_parameters: Option, - #[serde(rename = "tleParameters")] - pub tle_parameters: Option, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix: Option, - #[serde(rename = "userDefinedParameters")] - pub user_defined_parameters: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct MeanElementsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPOCH")] - pub epoch: common::EpochType, - #[serde(rename = "SEMI_MAJOR_AXIS")] - pub semi_major_axis: Option, - #[serde(rename = "MEAN_MOTION")] - pub mean_motion: Option, - #[serde(rename = "ECCENTRICITY")] - pub eccentricity: common::NonNegativeDouble, - #[serde(rename = "INCLINATION")] - pub inclination: common::InclinationType, - #[serde(rename = "RA_OF_ASC_NODE")] - pub ra_of_asc_node: common::AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] - pub arg_of_pericenter: common::AngleType, - #[serde(rename = "MEAN_ANOMALY")] - pub mean_anomaly: common::AngleType, - #[serde(rename = "GM")] - pub gm: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct TleParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "EPHEMERIS_TYPE")] - pub ephemeris_type: Option, - #[serde(rename = "CLASSIFICATION_TYPE")] - pub classification_type: Option, - #[serde(rename = "NORAD_CAT_ID")] - pub norad_cat_id: Option, - #[serde(rename = "ELEMENT_SET_NO")] - pub element_set_no: Option, - #[serde(rename = "REV_AT_EPOCH")] - pub rev_at_epoch: Option, - #[serde(rename = "BSTAR")] - pub bstar: Option, - #[serde(rename = "BTERM")] - pub bterm: Option, - #[serde(rename = "MEAN_MOTION_DOT")] - pub mean_motion_dot: DRevType, - #[serde(rename = "MEAN_MOTION_DDOT")] - pub mean_motion_ddot: Option, - #[serde(rename = "AGOM")] - pub agom: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct BStarType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct BTermType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct AgomType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct RevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct DRevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct DdRevType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -mod test { - use super::*; - - use quick_xml::de::from_str; - - #[test] - fn test_parse_omm_message1() { - let xml = r#" - - -
- THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2 - 2007-065T16:00:00 - NOAA/USA -
- - - - GOES-9 - 1995-025A - EARTH - TEME - UTC - TLE - - - USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA - - 2007-064T10:34:41.4264 - 1.00273272 - 0.0005013 - 3.0539 - 81.7939 - 249.2363 - 150.1602 - 398600.8 - - - 23581 - 0925 - 4316 - 0.0001 - -0.00000113 - 0.0 - - - xyz - 9 - xyz - 9 - xyz - 9 - xyz - 9 - xyz - 9 - - - - -
"#; - - let message: OmmType = from_str(xml).unwrap(); - - assert_eq!(message, - OmmType { - header: common::OdmHeader { - comment_list: vec![ - "THIS EXAMPLE CONFORMS TO FIGURE 4-2 IN 502.0-B-2".to_string(), - ], - classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), - originator: "NOAA/USA".to_string(), - message_id: None, - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![], - object_name: "GOES-9".to_string(), - object_id: "1995-025A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "TLE".to_string(), - }, - data: OmmData { - comment_list: vec![ - "USAF SGP4 IS THE ONLY PROPAGATOR THAT SHOULD BE USED FOR THIS DATA".to_string(), - ], - mean_elements: MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2007-064T10:34:41.4264".to_string(), - ), - semi_major_axis: None, - mean_motion: Some( - RevType { - base: 1.00273272, - units: None, - }, - ), - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), - inclination: common::InclinationType { - base: 3.0539, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 81.7939, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 249.2363, - units: None, - }, - mean_anomaly: common::AngleType { - base: 150.1602, - units: None, - }, - gm: Some( - common::GmType { - base: common::PositiveDouble( - 398600.8, - ), - units: None, - }, - ), - }, - spacecraft_parameters: None, - tle_parameters: Some( - TleParametersType { - comment_list: vec![], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some( - 23581, - ), - element_set_no: Some( - ElementSetNoType( - "0925".to_string(), - ), - ), - rev_at_epoch: Some( - 4316, - ), - bstar: Some( - BStarType { - base: 0.0001, - units: None, - }, - ), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: None, - }, - mean_motion_ddot: Some( - DRevType { - base: 0.0, - units: None, - }, - ), - agom: None, - }, - ), - covariance_matrix: None, - user_defined_parameters: Some( - common::UserDefinedType { - comment_list: vec![], - user_defined_list: vec![ - common::UserDefinedParameterType { - base: "xyz".to_string(), - parameter: "ABC0".to_string(), - }, - common::UserDefinedParameterType { - base: "9".to_string(), - parameter: "ABC1".to_string(), - }, - common::UserDefinedParameterType { - base: "xyz".to_string(), - parameter: "ABC2".to_string(), - }, - common::UserDefinedParameterType { - base: "9".to_string(), - parameter: "ABC3".to_string(), - }, - common::UserDefinedParameterType { - base: "xyz".to_string(), - parameter: "ABC4".to_string(), - }, - common::UserDefinedParameterType { - base: "9".to_string(), - parameter: "ABC5".to_string(), - }, - common::UserDefinedParameterType { - base: "xyz".to_string(), - parameter: "ABC6".to_string(), - }, - common::UserDefinedParameterType { - base: "9".to_string(), - parameter: "ABC7".to_string(), - }, - common::UserDefinedParameterType { - base: "xyz".to_string(), - parameter: "ABC8".to_string(), - }, - common::UserDefinedParameterType { - base: "9".to_string(), - parameter: "ABC9".to_string(), - }, - ], - }, - ), - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - }); - } - - #[test] - fn test_parse_omm_message_with_empty_object_id() { - // According to Orekit this should fail to parse due to having an empty object id. However, the XSD type of - // the object id is just xsd:string, which allows empty strings too. - - let xml = r#" - -
- 2021-03-24T23:00:00.000 - CelesTrak -
- - - - STARLETTE - - EARTH - TEME - UTC - SGP4 - - - - 2021-03-22T13:21:09.224928 - 13.82309053 - .0205751 - 49.8237 - 93.8140 - 224.8348 - 133.5761 - - - 0 - U - 7646 - 999 - 32997 - -.47102E-5 - -.147E-5 - 0 - - - - -
"#; - - let message: OmmType = from_str(xml).unwrap(); - - assert_eq!( - message, - OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), - originator: "CelesTrak".to_string(), - message_id: None, - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![], - object_name: "STARLETTE".to_string(), - object_id: "".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: OmmData { - comment_list: vec![], - mean_elements: MeanElementsType { - comment_list: vec![], - epoch: common::EpochType("2021-03-22T13:21:09.224928".to_string(),), - semi_major_axis: None, - mean_motion: Some(RevType { - base: 13.82309053, - units: None, - },), - eccentricity: common::NonNegativeDouble(0.0205751,), - inclination: common::InclinationType { - base: 49.8237, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 93.8140, - - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 224.8348, - units: None, - }, - mean_anomaly: common::AngleType { - base: 133.5761, - units: None, - }, - gm: None, - }, - spacecraft_parameters: None, - tle_parameters: Some(TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0,), - classification_type: Some("U".to_string(),), - norad_cat_id: Some(7646,), - element_set_no: Some(ElementSetNoType("999".to_string(),),), - rev_at_epoch: Some(32997,), - bstar: Some(BStarType { - base: -4.7102e-6, - units: None, - },), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some(DRevType { - base: 0.0, - units: None, - },), - agom: None, - },), - covariance_matrix: None, - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - } - ); - } - - #[test] - fn test_parse_omm_message2() { - let xml = r#" - -
- THIS IS AN XML VERSION OF THE OMM - 2007-065T16:00:00 - NOAA - OMM 201113719185 -
- - - - - GOES-9 - 1995-025A - EARTH - TEME - UTC - SGP/SGP4 - - - - - 2007-064T10:34:41.4264 - 1.00273272 - 0.0005013 - 3.0539 - 81.7939 - 249.2363 - 150.1602 - 398600.8 - - - 23581 - 0925 - 4316 - 0.0001 - -0.00000113 - 0.0 - - - TEME - 3.331349476038534e-04 - 4.618927349220216e-04 - 6.782421679971363e-04 - -3.070007847730449e-04 - -4.221234189514228e-04 - 3.231931992380369e-04 - -3.349365033922630e-07 - -4.686084221046758e-07 - 2.484949578400095e-07 - 4.296022805587290e-10 - -2.211832501084875e-07 - -2.864186892102733e-07 - 1.798098699846038e-07 - 2.608899201686016e-10 - 1.767514756338532e-10 - -3.041346050686871e-07 - -4.989496988610662e-07 - 3.540310904497689e-07 - 1.869263192954590e-10 - 1.008862586240695e-10 - 6.224444338635500e-10 - - - - -
"#; - - let message: OmmType = from_str(xml).unwrap(); - - assert_eq!( - message, - OmmType { - header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], - classification_list: vec![], - creation_date: common::EpochType("2007-065T16:00:00".to_string(),), - originator: "NOAA".to_string(), - message_id: Some("OMM 201113719185".to_string(),), - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![], - object_name: "GOES-9".to_string(), - object_id: "1995-025A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP/SGP4".to_string(), - }, - data: OmmData { - comment_list: vec![], - mean_elements: MeanElementsType { - comment_list: vec![], - epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), - semi_major_axis: None, - mean_motion: Some(RevType { - base: 1.00273272, - units: None, - },), - eccentricity: common::NonNegativeDouble(0.0005013,), - inclination: common::InclinationType { - base: 3.0539, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 81.7939, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 249.2363, - units: None, - }, - mean_anomaly: common::AngleType { - base: 150.1602, - units: None, - }, - gm: Some(common::GmType { - base: common::PositiveDouble(398600.8,), - units: None, - },), - }, - spacecraft_parameters: None, - tle_parameters: Some(TleParametersType { - comment_list: vec![], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some(23581,), - element_set_no: Some(ElementSetNoType("0925".to_string(),),), - rev_at_epoch: Some(4316,), - bstar: Some(BStarType { - base: 0.0001, - units: None, - },), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: None, - }, - mean_motion_ddot: Some(DRevType { - base: 0.0, - units: None, - },), - agom: None, - },), - covariance_matrix: Some(common::OpmCovarianceMatrixType { - comment_list: vec![], - cov_ref_frame: Some("TEME".to_string(),), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, - },), - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "3.0".to_string(), - } - ); - } - - #[test] - fn test_parse_omm_message_with_units() { - let xml = r#" - -
- THIS IS AN XML VERSION OF THE OMM - 2007-065T16:00:00 - NOAA - OMM 201113719185 -
- - - - - GOES-9 - 1995-025A - EARTH - TEME - UTC - SGP/SGP4 - - - - - mean Elements - 2007-064T10:34:41.4264 - 1.00273272 - 0.0005013 - 3.0539 - 81.7939 - 249.2363 - 150.1602 - 398600.8 - - - tle Parameters - 23581 - 0925 - 4316 - 0.0001 - -0.00000113 - 0.0 - - - covariance Matrix - TEME - 3.331349476038534e-04 - 4.618927349220216e-04 - 6.782421679971363e-04 - -3.070007847730449e-04 - -4.221234189514228e-04 - 3.231931992380369e-04 - -3.349365033922630e-07 - -4.686084221046758e-07 - 2.484949578400095e-07 - 4.296022805587290e-10 - -2.211832501084875e-07 - -2.864186892102733e-07 - 1.798098699846038e-07 - 2.608899201686016e-10 - 1.767514756338532e-10 - -3.041346050686871e-07 - -4.989496988610662e-07 - 3.540310904497689e-07 - 1.869263192954590e-10 - 1.008862586240695e-10 - 6.224444338635500e-10 - - - - -
"#; - - let message: OmmType = from_str(xml).unwrap(); - - assert_eq!( - message, - OmmType { - header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], - classification_list: vec![], - creation_date: common::EpochType("2007-065T16:00:00".to_string(),), - originator: "NOAA".to_string(), - message_id: Some("OMM 201113719185".to_string(),), - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![], - object_name: "GOES-9".to_string(), - object_id: "1995-025A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP/SGP4".to_string(), - }, - data: OmmData { - comment_list: vec![], - mean_elements: MeanElementsType { - comment_list: vec!["mean Elements".to_string(),], - epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), - semi_major_axis: None, - mean_motion: Some(RevType { - base: 1.00273272, - units: Some(RevUnits("rev/day".to_string(),),), - },), - eccentricity: common::NonNegativeDouble(0.0005013,), - inclination: common::InclinationType { - base: 3.0539, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - ra_of_asc_node: common::AngleType { - base: 81.7939, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - arg_of_pericenter: common::AngleType { - base: 249.2363, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - mean_anomaly: common::AngleType { - base: 150.1602, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - gm: Some(common::GmType { - base: common::PositiveDouble(398600.8,), - units: None, - },), - }, - spacecraft_parameters: None, - tle_parameters: Some(TleParametersType { - comment_list: vec!["tle Parameters".to_string(),], - ephemeris_type: None, - classification_type: None, - norad_cat_id: Some(23581,), - element_set_no: Some(ElementSetNoType("0925".to_string(),),), - rev_at_epoch: Some(4316,), - bstar: Some(BStarType { - base: 0.0001, - units: Some(BStarUnits("1/ER".to_string(),),), - },), - bterm: None, - mean_motion_dot: DRevType { - base: -1.13e-6, - units: Some(DRevUnits("rev/day**2".to_string(),),), - }, - mean_motion_ddot: Some(DRevType { - base: 0.0, - units: Some(DRevUnits("rev/day**3".to_string(),),), - },), - agom: None, - },), - covariance_matrix: Some(common::OpmCovarianceMatrixType { - comment_list: vec!["covariance Matrix".to_string(),], - cov_ref_frame: Some("TEME".to_string(),), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, - },), - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "3.0".to_string(), - } - ); - } - - #[test] - fn test_parse_omm_message3() { - let xml = r#" - -
- 2021-03-24T23:00:00.000 - CelesTrak -
- - - - STARLETTE - 1975-010A - EARTH - TEME - UTC - SGP4 - - - - 2008-09-20T12:25:40.104192 - 15.72125391 - 0.0006703 - 51.6416 - 247.4627 - 130.5360 - 325.0288 - 398600.8 - - - 0 - U - 7646 - 999 - 32997 - -.47102E-5 - -.147E-5 - 0 - - - foo enters - a bar - - - - -
"#; - - let message: OmmType = from_str(xml).unwrap(); - - assert_eq!( - message, - OmmType { - header: common::OdmHeader { - comment_list: vec![], - classification_list: vec![], - creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), - originator: "CelesTrak".to_string(), - message_id: None, - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![], - object_name: "STARLETTE".to_string(), - object_id: "1975-010A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TEME".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - mean_element_theory: "SGP4".to_string(), - }, - data: OmmData { - comment_list: vec![], - mean_elements: MeanElementsType { - comment_list: vec![], - epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), - semi_major_axis: None, - mean_motion: Some(RevType { - base: 15.72125391, - units: Some(RevUnits("rev/day".to_string(),),), - },), - eccentricity: common::NonNegativeDouble(0.0006703,), - inclination: common::InclinationType { - base: 51.6416, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - ra_of_asc_node: common::AngleType { - base: 247.4627, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - arg_of_pericenter: common::AngleType { - base: 130.536, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - mean_anomaly: common::AngleType { - base: 325.0288, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - gm: Some(common::GmType { - base: common::PositiveDouble(398600.8,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), - },), - }, - spacecraft_parameters: None, - tle_parameters: Some(TleParametersType { - comment_list: vec![], - ephemeris_type: Some(0,), - classification_type: Some("U".to_string(),), - norad_cat_id: Some(7646,), - element_set_no: Some(ElementSetNoType("999".to_string(),),), - rev_at_epoch: Some(32997,), - bstar: Some(BStarType { - base: -4.7102e-6, - units: None, - },), - bterm: None, - mean_motion_dot: DRevType { - base: -1.47e-6, - units: None, - }, - mean_motion_ddot: Some(DRevType { - base: 0.0, - units: None, - },), - agom: None, - },), - covariance_matrix: None, - user_defined_parameters: Some(common::UserDefinedType { - comment_list: vec![], - user_defined_list: vec![ - common::UserDefinedParameterType { - base: "foo enters".to_string(), - parameter: "FOO".to_string(), - }, - common::UserDefinedParameterType { - base: "a bar".to_string(), - parameter: "BAR".to_string(), - }, - ], - },), - }, - }, - }, - id: Some("CCSDS_OMM_VERS".to_string()), - version: "2.0".to_string(), - } - ); - } - - #[test] - fn test_parse_omm_message_spurious() { - let xml = r#" - -
- 2021-03-24T23:00:00.000 - CelesTrak -
- - - - STARLETTE - 1975-010A - EARTH - TEME - UTC - SGP4 - - - second metadata is an error - - - -
"#; - - let message: Result = from_str(xml); - - assert!(message.is_err()); - } - - #[test] - fn test_parse_omm_message_kvn() { - //@TOOD add back user defined stuff - let kvn = r#"CCSDS_OMM_VERS = 3.0 -COMMENT this is a comment -COMMENT here is another one -CREATION_DATE = 2007-065T16:00:00 -ORIGINATOR = NOAA/USA -COMMENT this comment doesn't say much -OBJECT_NAME = GOES 9 -OBJECT_ID = 1995-025A -CENTER_NAME = EARTH -REF_FRAME = TOD -REF_FRAME_EPOCH = 2000-003T10:34:00 -TIME_SYSTEM = MRT -MEAN_ELEMENT_THEORY = SOME THEORY -COMMENT the following data is what we're looking for -EPOCH = 2000-005T10:00:00 -SEMI_MAJOR_AXIS = 6800 -ECCENTRICITY = 0.0005013 -INCLINATION = 3.0539 -RA_OF_ASC_NODE = 81.7939 -ARG_OF_PERICENTER = 249.2363 -MEAN_ANOMALY = 150.1602 -COMMENT spacecraft data -MASS = 300 -SOLAR_RAD_AREA = 5 -SOLAR_RAD_COEFF = 0.001 -DRAG_AREA = 4 -DRAG_COEFF = 0.002 -COMMENT Covariance matrix -COV_REF_FRAME = TNW -CX_X = 3.331349476038534e-04 -CY_X = 4.618927349220216e-04 -CY_Y = 6.782421679971363e-04 -CZ_X = -3.070007847730449e-04 -CZ_Y = -4.221234189514228e-04 -CZ_Z = 3.231931992380369e-04 -CX_DOT_X = -3.349365033922630e-07 -CX_DOT_Y = -4.686084221046758e-07 -CX_DOT_Z = 2.484949578400095e-07 -CX_DOT_X_DOT = 4.296022805587290e-10 -CY_DOT_X = -2.211832501084875e-07 -CY_DOT_Y = -2.864186892102733e-07 -CY_DOT_Z = 1.798098699846038e-07 -CY_DOT_X_DOT = 2.608899201686016e-10 -CY_DOT_Y_DOT = 1.767514756338532e-10 -CZ_DOT_X = -3.041346050686871e-07 -CZ_DOT_Y = -4.989496988610662e-07 -CZ_DOT_Z = 3.540310904497689e-07 -CZ_DOT_X_DOT = 1.869263192954590e-10 -CZ_DOT_Y_DOT = 1.008862586240695e-10 -CZ_DOT_Z_DOT = 6.224444338635500e-10"#; - - assert_eq!(OmmType::deserialize(&mut kvn.lines().peekable()), Ok( - OmmType { - header: common::OdmHeader { - comment_list: vec![ - "this is a comment".to_string(), - "here is another one".to_string(), - ], - classification_list: vec![], - creation_date: common::EpochType( - "2007-065T16:00:00".to_string(), - ), - originator: "NOAA/USA".to_string(), - message_id: None, - }, - body: OmmBody { - segment: OmmSegment { - metadata: OmmMetadata { - comment_list: vec![ - "this comment doesn't say much".to_string(), - ], - object_name: "GOES 9".to_string(), - object_id: "1995-025A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TOD".to_string(), - ref_frame_epoch: Some( - common::EpochType( - "2000-003T10:34:00".to_string(), - ), - ), - time_system: "MRT".to_string(), - mean_element_theory: "SOME THEORY".to_string(), - }, - data: OmmData { - comment_list: vec![ - "the following data is what we're looking for".to_string(), - ], - mean_elements: MeanElementsType { - comment_list: vec![], - epoch: common::EpochType( - "2000-005T10:00:00".to_string(), - ), - semi_major_axis: Some( - common::DistanceType { - base: 6800.0, - units: None, - }, - ), - mean_motion: None, - eccentricity: common::NonNegativeDouble( - 0.0005013, - ), - inclination: common::InclinationType { - base: 3.0539, - units: None, - }, - ra_of_asc_node: common::AngleType { - base: 81.7939, - units: None, - }, - arg_of_pericenter: common::AngleType { - base: 249.2363, - units: None, - }, - mean_anomaly: common::AngleType { - base: 150.1602, - units: None, - }, - gm: None, - }, - spacecraft_parameters: Some( - common::SpacecraftParametersType { - comment_list: vec![ - "spacecraft data".to_string(), - ], - mass: Some( - common::MassType { - base: common::NonNegativeDouble( - 300.0, - ), - units: None, - }, - ), - solar_rad_area: Some( - common::AreaType { - base: common::NonNegativeDouble( - 5.0, - ), - units: None, - }, - ), - solar_rad_coeff: Some( - common::NonNegativeDouble( - 0.001, - ), - ), - drag_area: Some( - common::AreaType { - base: common::NonNegativeDouble( - 4.0, - ), - units: None, - }, - ), - drag_coeff: Some( - common::NonNegativeDouble( - 0.002, - ), - ), - }, - ), - tle_parameters: None, - covariance_matrix: Some( - common::OpmCovarianceMatrixType { - comment_list: vec![], - cov_ref_frame: Some( - "TNW".to_string(), - ), - cx_x: common::PositionCovarianceType { - base: 0.0003331349476038534, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.0004618927349220216, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.0006782421679971363, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: -0.0003070007847730449, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: -0.0004221234189514228, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.0003231931992380369, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: -3.34936503392263e-7, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: -4.686084221046758e-7, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 2.484949578400095e-7, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 4.29602280558729e-10, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: -2.211832501084875e-7, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: -2.864186892102733e-7, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 1.798098699846038e-7, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 2.608899201686016e-10, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 1.767514756338532e-10, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: -3.041346050686871e-7, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: -4.989496988610662e-7, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 3.540310904497689e-7, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 1.86926319295459e-10, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 1.008862586240695e-10, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 6.2244443386355e-10, - units: None, - }, - }, - ), - user_defined_parameters: None, - }, - }, - }, - id: None, - version: "3.0".to_string(), - }, - )); - } -} diff --git a/crates/lox-utils/src/ndm/opm.rs b/crates/lox-utils/src/ndm/opm.rs deleted file mode 100644 index de3b784a..00000000 --- a/crates/lox-utils/src/ndm/opm.rs +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Copyright (c) 2023. Helge Eichhorn and the LOX contributors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - */ - -use serde; - -use super::common; - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OpmBody, - #[serde(rename = "@id")] - // Marked as option for the KVN deserializer - pub id: Option, - #[serde(rename = "@version")] - pub version: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmBody { - #[serde(rename = "segment")] - pub segment: OpmSegment, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmSegment { - #[serde(rename = "metadata")] - pub metadata: OpmMetadata, - #[serde(rename = "data")] - pub data: OpmData, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmMetadata { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "OBJECT_NAME")] - pub object_name: String, - #[serde(rename = "OBJECT_ID")] - pub object_id: String, - #[serde(rename = "CENTER_NAME")] - pub center_name: String, - #[serde(rename = "REF_FRAME")] - pub ref_frame: String, - #[serde(rename = "REF_FRAME_EPOCH")] - pub ref_frame_epoch: Option, - #[serde(rename = "TIME_SYSTEM")] - pub time_system: String, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct OpmData { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "stateVector")] - pub state_vector: common::StateVectorType, - #[serde(rename = "keplerianElements")] - pub keplerian_elements: Option, - #[serde(rename = "spacecraftParameters")] - pub spacecraft_parameters: Option, - #[serde(rename = "covarianceMatrix")] - pub covariance_matrix: Option, - #[serde(rename = "maneuverParameters")] - pub maneuver_parameters_list: Vec, - #[serde(rename = "userDefinedParameters")] - pub user_defined_parameters: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct KeplerianElementsType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "SEMI_MAJOR_AXIS")] - pub semi_major_axis: common::DistanceType, - #[serde(rename = "ECCENTRICITY")] - pub eccentricity: common::NonNegativeDouble, - #[serde(rename = "INCLINATION")] - pub inclination: common::InclinationType, - #[serde(rename = "RA_OF_ASC_NODE")] - pub ra_of_asc_node: common::AngleType, - #[serde(rename = "ARG_OF_PERICENTER")] - pub arg_of_pericenter: common::AngleType, - #[serde(rename = "TRUE_ANOMALY")] - pub true_anomaly: Option, - #[serde(rename = "MEAN_ANOMALY")] - pub mean_anomaly: Option, - #[serde(rename = "GM")] - pub gm: common::GmType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct ManeuverParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "MAN_EPOCH_IGNITION")] - pub man_epoch_ignition: common::EpochType, - #[serde(rename = "MAN_DURATION")] - pub man_duration: common::DurationType, - #[serde(rename = "MAN_DELTA_MASS")] - pub man_delta_mass: common::DeltamassType, - #[serde(rename = "MAN_REF_FRAME")] - pub man_ref_frame: String, - #[serde(rename = "MAN_DV_1")] - pub man_dv_1: common::VelocityType, - #[serde(rename = "MAN_DV_2")] - pub man_dv_2: common::VelocityType, - #[serde(rename = "MAN_DV_3")] - pub man_dv_3: common::VelocityType, -} - -mod test { - use super::*; - - use quick_xml::de::from_str; - - #[test] - fn test_parse_opm_message_xml() { - let xml = r#" - - -
- THIS IS AN XML VERSION OF THE OPM - 2001-11-06T09:23:57 - JAXA - OPM 201113719185 -
- - - - GEOCENTRIC, CARTESIAN, EARTH FIXED - OSPREY 5 - 1998-999A - EARTH - TOD - 1998-12-18T14:28:15.1172 - UTC - - - - 2008-09-20T12:25:40.104192 - 4086.147180 - -994.936814 - 5250.678791 - 2.511071 - 7.255240 - -0.583165 - - - 6730.96 - 0.0006703 - 51.6416 - 247.463 - 130.536 - 324.985 - 398600.9368 - - - 3000.000000 - 18.770000 - 1.000000 - 18.770000 - 2.500000 - - - ITRF1997 - 0.316 - 0.722 - 0.518 - 0.202 - 0.715 - 0.002 - 0.912 - 0.306 - 0.276 - 0.797 - 0.562 - 0.899 - 0.022 - 0.079 - 0.415 - 0.245 - 0.965 - 0.950 - 0.435 - 0.621 - 0.991 - - - Maneuver 1 - 2008-09-20T12:41:09.984493 - 180.000 - -0.001 - RSW - 0.000000 - 0.280000 - 0.000000 - - - 2008-09-20T13:33:11.374985 - 180.000 - -0.001 - RSW - 0.000000 - 0.270000 - 0.000000 - - - - -
"#; - - let message: OpmType = from_str(xml).unwrap(); - - assert_eq!( - message, - OpmType { - header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OPM".to_string(),], - classification_list: vec![], - creation_date: common::EpochType("2001-11-06T09:23:57".to_string(),), - originator: "JAXA".to_string(), - message_id: Some("OPM 201113719185".to_string(),), - }, - body: OpmBody { - segment: OpmSegment { - metadata: OpmMetadata { - comment_list: vec!["GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(),], - object_name: "OSPREY 5".to_string(), - object_id: "1998-999A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TOD".to_string(), - ref_frame_epoch: Some(common::EpochType( - "1998-12-18T14:28:15.1172".to_string(), - ),), - time_system: "UTC".to_string(), - }, - data: OpmData { - comment_list: vec![], - state_vector: common::StateVectorType { - comment_list: vec![], - epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), - x: common::PositionType { - base: 4086.14718, - units: Some(common::PositionUnits("km".to_string(),),), - }, - y: common::PositionType { - base: -994.936814, - units: Some(common::PositionUnits("km".to_string(),),), - }, - z: common::PositionType { - base: 5250.678791, - units: Some(common::PositionUnits("km".to_string(),),), - }, - x_dot: common::VelocityType { - base: 2.511071, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - y_dot: common::VelocityType { - base: 7.25524, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - z_dot: common::VelocityType { - base: -0.583165, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - keplerian_elements: Some(KeplerianElementsType { - comment_list: vec![], - semi_major_axis: common::DistanceType { - base: 6730.96, - units: Some(common::PositionUnits("km".to_string(),),), - }, - eccentricity: common::NonNegativeDouble(0.0006703,), - inclination: common::InclinationType { - base: 51.6416, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - ra_of_asc_node: common::AngleType { - base: 247.463, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - arg_of_pericenter: common::AngleType { - base: 130.536, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - true_anomaly: Some(common::AngleType { - base: 324.985, - units: Some(common::AngleUnits("deg".to_string(),),), - },), - mean_anomaly: None, - gm: common::GmType { - base: common::PositiveDouble(398600.9368,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), - }, - },), - spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec![], - mass: Some(common::MassType { - base: common::NonNegativeDouble(3000.0,), - units: None, - },), - solar_rad_area: Some(common::AreaType { - base: common::NonNegativeDouble(18.77,), - units: None, - },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), - drag_area: Some(common::AreaType { - base: common::NonNegativeDouble(18.77,), - units: None, - },), - drag_coeff: Some(common::NonNegativeDouble(2.5,),), - },), - covariance_matrix: Some(common::OpmCovarianceMatrixType { - comment_list: vec![], - cov_ref_frame: Some("ITRF1997".to_string(),), - cx_x: common::PositionCovarianceType { - base: 0.316, - units: None, - }, - cy_x: common::PositionCovarianceType { - base: 0.722, - units: None, - }, - cy_y: common::PositionCovarianceType { - base: 0.518, - units: None, - }, - cz_x: common::PositionCovarianceType { - base: 0.202, - units: None, - }, - cz_y: common::PositionCovarianceType { - base: 0.715, - units: None, - }, - cz_z: common::PositionCovarianceType { - base: 0.002, - units: None, - }, - cx_dot_x: common::PositionVelocityCovarianceType { - base: 0.912, - units: None, - }, - cx_dot_y: common::PositionVelocityCovarianceType { - base: 0.306, - units: None, - }, - cx_dot_z: common::PositionVelocityCovarianceType { - base: 0.276, - units: None, - }, - cx_dot_x_dot: common::VelocityCovarianceType { - base: 0.797, - units: None, - }, - cy_dot_x: common::PositionVelocityCovarianceType { - base: 0.562, - units: None, - }, - cy_dot_y: common::PositionVelocityCovarianceType { - base: 0.899, - units: None, - }, - cy_dot_z: common::PositionVelocityCovarianceType { - base: 0.022, - units: None, - }, - cy_dot_x_dot: common::VelocityCovarianceType { - base: 0.079, - units: None, - }, - cy_dot_y_dot: common::VelocityCovarianceType { - base: 0.415, - units: None, - }, - cz_dot_x: common::PositionVelocityCovarianceType { - base: 0.245, - units: None, - }, - cz_dot_y: common::PositionVelocityCovarianceType { - base: 0.965, - units: None, - }, - cz_dot_z: common::PositionVelocityCovarianceType { - base: 0.95, - units: None, - }, - cz_dot_x_dot: common::VelocityCovarianceType { - base: 0.435, - units: None, - }, - cz_dot_y_dot: common::VelocityCovarianceType { - base: 0.621, - units: None, - }, - cz_dot_z_dot: common::VelocityCovarianceType { - base: 0.991, - units: None, - }, - },), - maneuver_parameters_list: vec![ - ManeuverParametersType { - comment_list: vec!["Maneuver 1".to_string(),], - man_epoch_ignition: common::EpochType( - "2008-09-20T12:41:09.984493".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(180.0,), - units: Some(common::TimeUnits("s".to_string(),),), - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-0.001,), - units: Some(common::MassUnits("kg".to_string(),),), - }, - man_ref_frame: "RSW".to_string(), - man_dv_1: common::VelocityType { - base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_2: common::VelocityType { - base: 0.28, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_3: common::VelocityType { - base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - ManeuverParametersType { - comment_list: vec![], - man_epoch_ignition: common::EpochType( - "2008-09-20T13:33:11.374985".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(180.0,), - units: Some(common::TimeUnits("s".to_string(),),), - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-0.001,), - units: Some(common::MassUnits("kg".to_string(),),), - }, - man_ref_frame: "RSW".to_string(), - man_dv_1: common::VelocityType { - base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_2: common::VelocityType { - base: 0.27, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_3: common::VelocityType { - base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - ], - user_defined_parameters: None, - }, - }, - }, - id: Some("CCSDS_OPM_VERS".to_string()), - version: "3.0".to_string(), - } - ); - } - - #[test] - fn test_parse_opm_message_spurious() { - let xml = r#" - - -
- THIS IS AN XML VERSION OF THE OPM - 2001-11-06T09:23:57 - JAXA - OPM 201113719185 -
- - - - GEOCENTRIC, CARTESIAN, EARTH FIXED - OSPREY 5 - 1998-999A - EARTH - TOD - 1998-12-18T14:28:15.1172 - UTC - - - second metadata is an error - - - -
"#; - - let message: Result = from_str(xml); - - assert!(message.is_err()); - } - - use crate::ndm::kvn::parser::KvnDeserializer; - - #[test] - fn test_parse_opm_message_kvn() { - //@TOOD add user defined stuff - let kvn = r#"CCSDS_OPM_VERS = 3.0 -COMMENT Generated by GSOC, R. Kiehling -COMMENT Current intermediate orbit IO2 and maneuver planning data -CREATION_DATE = 2021-06-03T05:33:00.123 -ORIGINATOR = GSOC -OBJECT_NAME = EUTELSAT W4 -OBJECT_ID = 2021-028A -CENTER_NAME = EARTH -REF_FRAME = TOD -TIME_SYSTEM = UTC -COMMENT State Vector -EPOCH = 2021-06-03T00:00:00.000 -X = 6655.9942 [km] -Y = -40218.5751 [km] -Z = -82.9177 [km] -X_DOT = 3.11548208 [km/s] -Y_DOT = 0.47042605 [km/s] -Z_DOT = -0.00101495 [km/s] -COMMENT Keplerian elements -SEMI_MAJOR_AXIS = 41399.5123 [km] -ECCENTRICITY = 0.020842611 -INCLINATION = 0.117746 [deg] -RA_OF_ASC_NODE = 17.604721 [deg] -ARG_OF_PERICENTER = 218.242943 [deg] -TRUE_ANOMALY = 41.922339 [deg] -GM = 398600.4415 [km**3/s**2] -COMMENT Spacecraft parameters -MASS = 1913.000 [kg] -SOLAR_RAD_AREA = 10.000 [m**2] -SOLAR_RAD_COEFF = 1.300 -DRAG_AREA = 10.000 [m**2] -DRAG_COEFF = 2.300 -COMMENT 2 planned maneuvers -COMMENT First maneuver: AMF-3 -COMMENT Non-impulsive, thrust direction fixed in inertial frame -MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 -MAN_DURATION = 132.60 [s] -MAN_DELTA_MASS = -18.418 [kg] -MAN_REF_FRAME = EME2000 -MAN_DV_1 = -0.02325700 [km/s] -MAN_DV_2 = 0.01683160 [km/s] -MAN_DV_3 = -0.00893444 [km/s] -COMMENT Second maneuver: first station acquisition maneuver -COMMENT impulsive, thrust direction fixed in RTN frame -MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 -MAN_DURATION = 0.00 [s] -MAN_DELTA_MASS = -1.469 [kg] -MAN_REF_FRAME = RTN -MAN_DV_1 = 0.00101500 [km/s] -MAN_DV_2 = -0.00187300 [km/s] -MAN_DV_3 = 0.00000000 [km/s]"#; - - assert_eq!( - OpmType::deserialize(&mut kvn.lines().peekable()), - Ok(OpmType { - header: common::OdmHeader { - comment_list: vec![ - "Generated by GSOC, R. Kiehling".to_string(), - "Current intermediate orbit IO2 and maneuver planning data".to_string(), - ], - classification_list: vec![], - creation_date: common::EpochType("2021-06-03T05:33:00.123".to_string(),), - originator: "GSOC".to_string(), - message_id: None, - }, - body: OpmBody { - segment: OpmSegment { - metadata: OpmMetadata { - comment_list: vec![], - object_name: "EUTELSAT W4".to_string(), - object_id: "2021-028A".to_string(), - center_name: "EARTH".to_string(), - ref_frame: "TOD".to_string(), - ref_frame_epoch: None, - time_system: "UTC".to_string(), - }, - data: OpmData { - comment_list: vec!["State Vector".to_string(),], - state_vector: common::StateVectorType { - comment_list: vec![], - epoch: common::EpochType("2021-06-03T00:00:00.000".to_string(),), - x: common::PositionType { - base: 6655.9942, - units: Some(common::PositionUnits("km".to_string(),),), - }, - y: common::PositionType { - base: -40218.5751, - units: Some(common::PositionUnits("km".to_string(),),), - }, - z: common::PositionType { - base: -82.9177, - units: Some(common::PositionUnits("km".to_string(),),), - }, - x_dot: common::VelocityType { - base: 3.11548208, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - y_dot: common::VelocityType { - base: 0.47042605, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - z_dot: common::VelocityType { - base: -0.00101495, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - keplerian_elements: Some(KeplerianElementsType { - comment_list: vec!["Keplerian elements".to_string(),], - semi_major_axis: common::DistanceType { - base: 41399.5123, - units: Some(common::PositionUnits("km".to_string(),),), - }, - eccentricity: common::NonNegativeDouble(0.020842611,), - inclination: common::InclinationType { - base: 0.117746, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - ra_of_asc_node: common::AngleType { - base: 17.604721, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - arg_of_pericenter: common::AngleType { - base: 218.242943, - units: Some(common::AngleUnits("deg".to_string(),),), - }, - true_anomaly: Some(common::AngleType { - base: 41.922339, - units: Some(common::AngleUnits("deg".to_string(),),), - },), - mean_anomaly: None, - gm: common::GmType { - base: common::PositiveDouble(398600.4415,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), - }, - },), - spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec!["Spacecraft parameters".to_string(),], - mass: Some(common::MassType { - base: common::NonNegativeDouble(1913.0,), - units: Some(common::MassUnits("kg".to_string(),),), - },), - solar_rad_area: Some(common::AreaType { - base: common::NonNegativeDouble(10.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), - },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.3,),), - drag_area: Some(common::AreaType { - base: common::NonNegativeDouble(10.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), - },), - drag_coeff: Some(common::NonNegativeDouble(2.3,),), - },), - covariance_matrix: None, - maneuver_parameters_list: vec![ - ManeuverParametersType { - comment_list: vec![], - man_epoch_ignition: common::EpochType( - "2021-06-03T09:00:34.1".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(132.6,), - units: Some(common::TimeUnits("s".to_string(),),), - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-18.418,), - units: Some(common::MassUnits("kg".to_string(),),), - }, - man_ref_frame: "EME2000".to_string(), - man_dv_1: common::VelocityType { - base: -0.023257, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_2: common::VelocityType { - base: 0.0168316, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_3: common::VelocityType { - base: -0.00893444, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - ManeuverParametersType { - comment_list: vec![ - "Second maneuver: first station acquisition maneuver" - .to_string(), - "impulsive, thrust direction fixed in RTN frame" - .to_string(), - ], - man_epoch_ignition: common::EpochType( - "2021-06-05T18:59:21.0".to_string(), - ), - man_duration: common::DurationType { - base: common::NonNegativeDouble(0.0,), - units: Some(common::TimeUnits("s".to_string(),),), - }, - man_delta_mass: common::DeltamassType { - base: common::NegativeDouble(-1.469,), - units: Some(common::MassUnits("kg".to_string(),),), - }, - man_ref_frame: "RTN".to_string(), - man_dv_1: common::VelocityType { - base: 0.001015, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_2: common::VelocityType { - base: -0.001873, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - man_dv_3: common::VelocityType { - base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), - }, - }, - ], - user_defined_parameters: None, - }, - }, - }, - id: None, - version: "3.0".to_string(), - },) - ); - } -} diff --git a/crates/lox-utils/src/odm.rs b/crates/lox-utils/src/odm.rs deleted file mode 100644 index ffe48ce3..00000000 --- a/crates/lox-utils/src/odm.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod common; -pub mod ndm; -pub mod ocm; -pub mod oem; -pub mod omm; -pub mod opm; From 6a078406748ae840479f9d637aad09be2fd86c42 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 16:47:21 +0300 Subject: [PATCH 101/150] Move ndm parsing to lox-io --- Cargo.lock | 14 ++++++-------- crates/lox-io/Cargo.toml | 7 +++++++ crates/lox-io/src/lib.rs | 1 + crates/{lox-utils => lox-io}/src/ndm.rs | 0 crates/{lox-utils => lox-io}/src/ndm/json.rs | 0 crates/{lox-utils => lox-io}/src/ndm/json/omm.rs | 0 crates/{lox-utils => lox-io}/src/ndm/kvn.rs | 0 crates/{lox-utils => lox-io}/src/ndm/kvn/parser.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/common.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/ndm.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/ocm.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/oem.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/omm.rs | 0 crates/{lox-utils => lox-io}/src/ndm/xml/opm.rs | 0 crates/lox-utils/Cargo.toml | 8 -------- crates/lox-utils/src/lib.rs | 1 - 17 files changed, 14 insertions(+), 17 deletions(-) rename crates/{lox-utils => lox-io}/src/ndm.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/json.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/json/omm.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/kvn.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/kvn/parser.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/common.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/ndm.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/ocm.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/oem.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/omm.rs (100%) rename crates/{lox-utils => lox-io}/src/ndm/xml/opm.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ceeb1ae0..8faaf9e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -516,10 +516,16 @@ name = "lox-io" version = "0.0.0" dependencies = [ "csv", + "fast-float", + "lox-derive", "lox-utils", "nom", + "quick-xml", + "regex", "rstest", "serde", + "serde-aux", + "serde_json", "thiserror", ] @@ -555,17 +561,9 @@ dependencies = [ name = "lox-utils" version = "0.1.0" dependencies = [ - "fast-float", "fast_polynomial", "float_eq", - "lox-derive", - "nom", - "quick-xml", - "regex", "rstest", - "serde", - "serde-aux", - "serde_json", "thiserror", ] diff --git a/crates/lox-io/Cargo.toml b/crates/lox-io/Cargo.toml index ec073660..72646987 100644 --- a/crates/lox-io/Cargo.toml +++ b/crates/lox-io/Cargo.toml @@ -15,5 +15,12 @@ nom.workspace = true serde.workspace = true thiserror.workspace = true +quick-xml.workspace = true +serde_json.workspace = true +serde-aux.workspace = true +regex.workspace = true +fast-float.workspace = true +lox-derive.workspace = true + [dev-dependencies] rstest.workspace = true diff --git a/crates/lox-io/src/lib.rs b/crates/lox-io/src/lib.rs index 78728fbc..87ec8707 100644 --- a/crates/lox-io/src/lib.rs +++ b/crates/lox-io/src/lib.rs @@ -7,4 +7,5 @@ */ pub mod iers; +pub mod ndm; pub mod spice; diff --git a/crates/lox-utils/src/ndm.rs b/crates/lox-io/src/ndm.rs similarity index 100% rename from crates/lox-utils/src/ndm.rs rename to crates/lox-io/src/ndm.rs diff --git a/crates/lox-utils/src/ndm/json.rs b/crates/lox-io/src/ndm/json.rs similarity index 100% rename from crates/lox-utils/src/ndm/json.rs rename to crates/lox-io/src/ndm/json.rs diff --git a/crates/lox-utils/src/ndm/json/omm.rs b/crates/lox-io/src/ndm/json/omm.rs similarity index 100% rename from crates/lox-utils/src/ndm/json/omm.rs rename to crates/lox-io/src/ndm/json/omm.rs diff --git a/crates/lox-utils/src/ndm/kvn.rs b/crates/lox-io/src/ndm/kvn.rs similarity index 100% rename from crates/lox-utils/src/ndm/kvn.rs rename to crates/lox-io/src/ndm/kvn.rs diff --git a/crates/lox-utils/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs similarity index 100% rename from crates/lox-utils/src/ndm/kvn/parser.rs rename to crates/lox-io/src/ndm/kvn/parser.rs diff --git a/crates/lox-utils/src/ndm/xml.rs b/crates/lox-io/src/ndm/xml.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml.rs rename to crates/lox-io/src/ndm/xml.rs diff --git a/crates/lox-utils/src/ndm/xml/common.rs b/crates/lox-io/src/ndm/xml/common.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/common.rs rename to crates/lox-io/src/ndm/xml/common.rs diff --git a/crates/lox-utils/src/ndm/xml/ndm.rs b/crates/lox-io/src/ndm/xml/ndm.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/ndm.rs rename to crates/lox-io/src/ndm/xml/ndm.rs diff --git a/crates/lox-utils/src/ndm/xml/ocm.rs b/crates/lox-io/src/ndm/xml/ocm.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/ocm.rs rename to crates/lox-io/src/ndm/xml/ocm.rs diff --git a/crates/lox-utils/src/ndm/xml/oem.rs b/crates/lox-io/src/ndm/xml/oem.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/oem.rs rename to crates/lox-io/src/ndm/xml/oem.rs diff --git a/crates/lox-utils/src/ndm/xml/omm.rs b/crates/lox-io/src/ndm/xml/omm.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/omm.rs rename to crates/lox-io/src/ndm/xml/omm.rs diff --git a/crates/lox-utils/src/ndm/xml/opm.rs b/crates/lox-io/src/ndm/xml/opm.rs similarity index 100% rename from crates/lox-utils/src/ndm/xml/opm.rs rename to crates/lox-io/src/ndm/xml/opm.rs diff --git a/crates/lox-utils/Cargo.toml b/crates/lox-utils/Cargo.toml index 4c6c3425..06d785ec 100644 --- a/crates/lox-utils/Cargo.toml +++ b/crates/lox-utils/Cargo.toml @@ -6,14 +6,6 @@ edition = "2021" [dependencies] fast_polynomial.workspace = true thiserror.workspace = true -nom.workspace = true -quick-xml.workspace = true -serde.workspace = true -serde_json.workspace = true -serde-aux.workspace = true -regex.workspace = true -fast-float.workspace = true -lox-derive.workspace = true [dev-dependencies] float_eq.workspace = true diff --git a/crates/lox-utils/src/lib.rs b/crates/lox-utils/src/lib.rs index b623a9a5..474d0f63 100644 --- a/crates/lox-utils/src/lib.rs +++ b/crates/lox-utils/src/lib.rs @@ -10,7 +10,6 @@ pub mod constants; pub mod is_close; pub mod linear_algebra; pub mod math; -pub mod ndm; pub mod series; pub mod slices; pub mod types; From a2dc3fcdec550463c3a66387cfd8d9b87cbb5d5b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 17:05:47 +0300 Subject: [PATCH 102/150] Fix type inference for into --- crates/lox-time/src/subsecond.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/lox-time/src/subsecond.rs b/crates/lox-time/src/subsecond.rs index cd69dfa5..5843b44f 100644 --- a/crates/lox-time/src/subsecond.rs +++ b/crates/lox-time/src/subsecond.rs @@ -189,7 +189,8 @@ mod tests { #[test] fn test_subsecond_into_f64() { let subsecond = Subsecond(0.0); - assert_eq!(0.0, subsecond.into()); + let as_f64: f64 = subsecond.into(); + assert_eq!(0.0, as_f64); } #[test] From 2931bdf2b6d6820ef715549a0a1021c1bcf86978 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Tue, 4 Jun 2024 17:06:23 +0300 Subject: [PATCH 103/150] Remove unused variable --- crates/lox-derive/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 18f9525e..5e2c9edf 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -128,7 +128,7 @@ fn generate_call_to_deserializer_for_kvn_type( }) } - type_value => Ok(quote! { + _ => Ok(quote! { { let has_next_line = lines.peek().is_some(); @@ -182,7 +182,7 @@ fn generate_call_to_deserializer_for_kvn_type_new( Ok(parser) } - type_value => { + _ => { Ok(quote! { { let has_next_line = lines.peek().is_some(); From 66347b0c83f2c35f55433a29c46e3a9660bfb0a0 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 12:54:43 +0300 Subject: [PATCH 104/150] Make clippy happy --- crates/lox-derive/src/lib.rs | 83 ++++++++++++++------------------ crates/lox-io/src/ndm/xml/ndm.rs | 1 + 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 5e2c9edf..7d32437c 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -248,20 +248,18 @@ fn generate_call_to_deserializer_for_option_type( let type_name_new = get_generic_type_argument_new(field).unwrap(); match type_name { - None => { - return Err(syn::Error::new_spanned( - &field, - "Malformed type for `#[derive(KvnDeserialize)]`", - ) - .into_compile_error() - .into()) - } + None => Err(syn::Error::new_spanned( + field, + "Malformed type for `#[derive(KvnDeserialize)]`", + ) + .into_compile_error() + .into()), Some(type_name) => { let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &type_name_new, - &expected_kvn_name, + type_name.as_ref(), + type_name_new, + expected_kvn_name, )?; let condition_shortcut = match type_name.as_str() { @@ -269,7 +267,7 @@ fn generate_call_to_deserializer_for_option_type( _ => quote! { ! #type_name_new::should_check_key_match() || }, }; - return Ok(quote! { + Ok(quote! { match lines.peek() { None => None, Some(next_line) => { @@ -292,7 +290,7 @@ fn generate_call_to_deserializer_for_option_type( } } } - }); + }) } } } @@ -319,9 +317,9 @@ fn generate_call_to_deserializer_for_vec_type( let expected_kvn_name = expected_kvn_name.trim_end_matches("_LIST"); let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( - &type_name.as_ref(), - &bla, - &expected_kvn_name, + type_name.as_ref(), + bla, + expected_kvn_name, )?; let type_ident = syn::Ident::new(&type_name, Span::call_site()); @@ -348,17 +346,17 @@ fn generate_call_to_deserializer_for_vec_type( } } - return Err( - syn::Error::new_spanned(&field, "Malformed type for `#[derive(KvnDeserialize)]`") + Err( + syn::Error::new_spanned(field, "Malformed type for `#[derive(KvnDeserialize)]`") .into_compile_error() .into(), - ); + ) } fn is_value_unit_struct(item: &DeriveInput) -> bool { for attr in item.attrs.iter() { - if attr.path().is_ident("kvn") { - if attr + if attr.path().is_ident("kvn") + && attr .parse_nested_meta(|meta| { if meta.path.is_ident("value_unit_struct") { Ok(()) @@ -367,9 +365,8 @@ fn is_value_unit_struct(item: &DeriveInput) -> bool { } }) .is_ok() - { - return true; - } + { + return true; } } @@ -388,7 +385,7 @@ fn deserializer_for_struct_with_named_fields( fields: &syn::punctuated::Punctuated, is_value_unit_struct: bool, ) -> proc_macro2::TokenStream { - if type_name.to_string() == "UserDefinedType" { + if &type_name.to_string() == "UserDefinedType" { //@TODO return quote! { Ok(Default::default()) @@ -412,11 +409,10 @@ fn deserializer_for_struct_with_named_fields( 0 => { if field_name.as_str() != "base" { return syn::Error::new_spanned( - &field, + field, "The first field in a value unit struct should be called \"base\"", ) - .into_compile_error() - .into(); + .into_compile_error(); } // Unwrap is okay because we expect this span to come from the source code @@ -427,12 +423,12 @@ fn deserializer_for_struct_with_named_fields( .unwrap(); let local_field_type_new = extract_type_path(&field.ty).unwrap(); - let deserializer = match local_field_type.as_str() { + match local_field_type.as_str() { "KvnDateTimeValue" | "String" | "f64" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { match generate_call_to_deserializer_for_kvn_type_new( &local_field_type, - &local_field_type_new, + local_field_type_new, ) { Ok(deserializer_for_kvn_type) => { deserializer = Some(deserializer_for_kvn_type) @@ -443,27 +439,23 @@ fn deserializer_for_struct_with_named_fields( _ => { return syn::Error::new_spanned( - &field, + field, "Unsupported field type for deserializer", ) .into_compile_error() - .into() } }; field_type = Some(local_field_type); field_type_new = Some(local_field_type_new); - - deserializer } 1 => { if field_name.as_str() != "units" && field_name.as_str() != "parameter" { return syn::Error::new_spanned( - &field, + field, "The second field in a value unit struct should be called \"units\" or \"parameter\"", ) - .into_compile_error() - .into(); + .into_compile_error(); } unit_type = get_generic_type_argument(field); @@ -471,11 +463,10 @@ fn deserializer_for_struct_with_named_fields( } _ => { return syn::Error::new_spanned( - &field, + field, "Only two fields are allowed: \"base\" and (\"units\" or \"parameters\"", ) .into_compile_error() - .into() } } } @@ -496,9 +487,8 @@ fn deserializer_for_struct_with_named_fields( }; match deserializer { - None => syn::Error::new_spanned(&fields, "Unable to create deserializer for struct") - .into_compile_error() - .into(), + None => syn::Error::new_spanned(fields, "Unable to create deserializer for struct") + .into_compile_error(), Some(deserializer) => quote! { let kvn_value = #deserializer; Ok(#type_name { @@ -520,11 +510,10 @@ fn deserializer_for_struct_with_named_fields( if !string_type_name.ends_with("Type") { return Err(syn::Error::new_spanned( - &fields, + fields, "Types with \"version\" field should be of the form SomethingType", ) - .into_compile_error() - .into()); + .into_compile_error()); } let message_type_name = string_type_name @@ -594,9 +583,9 @@ fn deserializer_for_struct_with_named_fields( } } "Option" => { - generate_call_to_deserializer_for_option_type(&expected_kvn_name, &field)? + generate_call_to_deserializer_for_option_type(&expected_kvn_name, field)? } - "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, &field)?, + "Vec" => generate_call_to_deserializer_for_vec_type(&expected_kvn_name, field)?, _ => { let condition_shortcut = match field_type.as_str() { diff --git a/crates/lox-io/src/ndm/xml/ndm.rs b/crates/lox-io/src/ndm/xml/ndm.rs index 6dab3dba..39d9357b 100644 --- a/crates/lox-io/src/ndm/xml/ndm.rs +++ b/crates/lox-io/src/ndm/xml/ndm.rs @@ -4,6 +4,7 @@ use super::{ocm, oem, omm, opm}; #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] #[serde()] +#[allow(clippy::large_enum_variant)] pub enum NdmChildChoice { #[serde(rename = "ocm")] Ocm(ocm::OcmType), From da7fe28f35ae344e8960d4cdbf587e0d03f6b8e5 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 13:30:53 +0300 Subject: [PATCH 105/150] Fix unused with_unit --- crates/lox-io/src/ndm/kvn/parser.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index 2bf6e16b..e57bf541 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -277,9 +277,14 @@ where Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; + let regex_pattern = if with_unit { + r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$" + } else { + r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?)(?:\s*)$" + }; + // Modified from Figure F-9: CCSDS 502.0-B-3 - let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$") - .unwrap(); + let re = Regex::new(regex_pattern).unwrap(); let captures = re.captures(input) @@ -329,8 +334,14 @@ pub fn parse_kvn_numeric_line_new( Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; - // Figure F-9: CCSDS 502.0-B-3 - let re = Regex::new(r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?(?:[eE][+-]?(?:\d+))?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$").unwrap(); + let regex_pattern = if with_unit { + // Figure F-9: CCSDS 502.0-B-3 + r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?(?:[eE][+-]?(?:\d+))?)(?:(?:\s*)(?:\[(?[0-9A-Za-z/_*]*)\]?))?(?:\s*)?$" + } else { + r"^(?:\s*)(?[0-9A-Za-z_]*)(?:\s*)=(?:\s*)(?(?:[-+]?)(?:[0-9]+)(?:\.\d*)?(?:[eE][+-]?(?:\d+))?)(?:\s*)?$" + }; + + let re = Regex::new(regex_pattern).unwrap(); let captures = re.captures(input) @@ -678,7 +689,7 @@ mod test { ); assert_eq!( - parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", false), + parse_kvn_integer_line_new("SCLK_OFFSET_AT_EPOCH = 28800 [s]", true), Ok(( "", KvnValue { @@ -688,6 +699,13 @@ mod test { )) ); + assert_eq!( + parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = 28800 [s]", false), + Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { + input: "SCLK_OFFSET_AT_EPOCH = 28800 [s]" + })) + ); + assert_eq!( parse_kvn_integer_line_new::("SCLK_OFFSET_AT_EPOCH = -asd", true), Err(nom::Err::Failure(KvnNumberParserErr::InvalidFormat { From 50f320de7c0dff5a0e208f50b77da43fe1f01da1 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 13:59:37 +0300 Subject: [PATCH 106/150] Ignore proc macro from coverage --- codecov.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 codecov.yaml diff --git a/codecov.yaml b/codecov.yaml new file mode 100644 index 00000000..582cabf0 --- /dev/null +++ b/codecov.yaml @@ -0,0 +1,4 @@ +ignore: + # This code is tested indirectly with high coverage but coverage tools don't + # handle proc macros + - "crates/lox-derive/src/lib.rs" \ No newline at end of file From 08caa539e05b3d16775806793ead667dfeb3bc1d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 14:33:49 +0300 Subject: [PATCH 107/150] Move user-facing classes into the main namespace --- crates/lox-io/src/ndm.rs | 1 - crates/lox-io/src/ndm/{xml => }/common.rs | 0 crates/lox-io/src/ndm/{xml => }/ndm.rs | 0 crates/lox-io/src/ndm/{xml => }/ocm.rs | 0 crates/lox-io/src/ndm/{xml => }/oem.rs | 0 crates/lox-io/src/ndm/{xml => }/omm.rs | 0 crates/lox-io/src/ndm/{xml => }/opm.rs | 0 crates/lox-io/src/ndm/xml.rs | 6 ------ 8 files changed, 7 deletions(-) rename crates/lox-io/src/ndm/{xml => }/common.rs (100%) rename crates/lox-io/src/ndm/{xml => }/ndm.rs (100%) rename crates/lox-io/src/ndm/{xml => }/ocm.rs (100%) rename crates/lox-io/src/ndm/{xml => }/oem.rs (100%) rename crates/lox-io/src/ndm/{xml => }/omm.rs (100%) rename crates/lox-io/src/ndm/{xml => }/opm.rs (100%) delete mode 100644 crates/lox-io/src/ndm/xml.rs diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index 4f8a1dab..4f1f414b 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -1,3 +1,2 @@ pub mod json; pub mod kvn; -pub mod xml; diff --git a/crates/lox-io/src/ndm/xml/common.rs b/crates/lox-io/src/ndm/common.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/common.rs rename to crates/lox-io/src/ndm/common.rs diff --git a/crates/lox-io/src/ndm/xml/ndm.rs b/crates/lox-io/src/ndm/ndm.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/ndm.rs rename to crates/lox-io/src/ndm/ndm.rs diff --git a/crates/lox-io/src/ndm/xml/ocm.rs b/crates/lox-io/src/ndm/ocm.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/ocm.rs rename to crates/lox-io/src/ndm/ocm.rs diff --git a/crates/lox-io/src/ndm/xml/oem.rs b/crates/lox-io/src/ndm/oem.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/oem.rs rename to crates/lox-io/src/ndm/oem.rs diff --git a/crates/lox-io/src/ndm/xml/omm.rs b/crates/lox-io/src/ndm/omm.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/omm.rs rename to crates/lox-io/src/ndm/omm.rs diff --git a/crates/lox-io/src/ndm/xml/opm.rs b/crates/lox-io/src/ndm/opm.rs similarity index 100% rename from crates/lox-io/src/ndm/xml/opm.rs rename to crates/lox-io/src/ndm/opm.rs diff --git a/crates/lox-io/src/ndm/xml.rs b/crates/lox-io/src/ndm/xml.rs deleted file mode 100644 index ffe48ce3..00000000 --- a/crates/lox-io/src/ndm/xml.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod common; -pub mod ndm; -pub mod ocm; -pub mod oem; -pub mod omm; -pub mod opm; From f3b84719b5d07e046647861b3156da9f491602c4 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 14:34:28 +0300 Subject: [PATCH 108/150] Remove superfluous types --- crates/lox-io/src/ndm/kvn/parser.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index e57bf541..909ce5c4 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -14,9 +14,6 @@ use nom::error::{ErrorKind, ParseError}; use nom::sequence as ns; use regex::Regex; -pub type KvnStringValue = KvnValue; -pub type KvnNumericValue = KvnValue; - #[derive(Debug, PartialEq)] pub enum KvnStringParserErr { EmptyKeyword { input: I }, @@ -206,7 +203,7 @@ pub fn kvn_line_matches_key_new<'a>( pub fn parse_kvn_string_line_new( input: &str, -) -> nom::IResult<&str, KvnStringValue, KvnStringParserErr<&str>> { +) -> nom::IResult<&str, KvnValue, KvnStringParserErr<&str>> { if input.trim_start().starts_with("COMMENT") { return Ok(( "", @@ -329,7 +326,7 @@ fn is_empty_value(input: &str) -> bool { pub fn parse_kvn_numeric_line_new( input: &str, with_unit: bool, -) -> nom::IResult<&str, KvnNumericValue, KvnNumberParserErr<&str>> { +) -> nom::IResult<&str, KvnValue, KvnNumberParserErr<&str>> { if is_empty_value(input) { Err(nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }))? }; From d5da926ef2b10985947a8b328f5e49c6fea05676 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 14:51:29 +0300 Subject: [PATCH 109/150] Restructure public interface --- crates/lox-io/src/ndm.rs | 7 +++++ crates/lox-io/src/ndm/kvn.rs | 3 ++- crates/lox-io/src/ndm/kvn/deserializer.rs | 32 +++++++++++++++++++++++ crates/lox-io/src/ndm/kvn/parser.rs | 25 ++---------------- 4 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 crates/lox-io/src/ndm/kvn/deserializer.rs diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index 4f1f414b..7cd474f5 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -1,2 +1,9 @@ pub mod json; pub mod kvn; + +pub mod common; +pub mod ndm; +pub mod ocm; +pub mod oem; +pub mod omm; +pub mod opm; diff --git a/crates/lox-io/src/ndm/kvn.rs b/crates/lox-io/src/ndm/kvn.rs index 67c567fa..4837a11e 100644 --- a/crates/lox-io/src/ndm/kvn.rs +++ b/crates/lox-io/src/ndm/kvn.rs @@ -1 +1,2 @@ -pub mod parser; +pub mod deserializer; +mod parser; diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs new file mode 100644 index 00000000..4eda0f8e --- /dev/null +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use nom::error::ErrorKind; + +pub trait KvnDeserializer { + fn deserialize<'a>( + lines: &mut std::iter::Peekable>, + ) -> Result> + where + Self: Sized; + + fn should_check_key_match() -> bool; +} + +#[derive(PartialEq, Debug)] +pub enum KvnDeserializerErr { + InvalidDateTimeFormat { input: I }, + InvalidNumberFormat { input: I }, + InvalidStringFormat { input: I }, + KeywordNotFound { expected: I }, + UnexpectedKeyword { found: I, expected: I }, + EmptyKeyword { input: I }, + EmptyValue { input: I }, + UnexpectedEndOfInput { keyword: I }, + GeneralParserError(I, ErrorKind), +} diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index 909ce5c4..c5c7661c 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -14,6 +14,8 @@ use nom::error::{ErrorKind, ParseError}; use nom::sequence as ns; use regex::Regex; +use super::deserializer::KvnDeserializerErr; + #[derive(Debug, PartialEq)] pub enum KvnStringParserErr { EmptyKeyword { input: I }, @@ -43,19 +45,6 @@ pub enum KvnDateTimeParserErr { InvalidFormat { input: I }, } -#[derive(PartialEq, Debug)] -pub enum KvnDeserializerErr { - InvalidDateTimeFormat { input: I }, - InvalidNumberFormat { input: I }, - InvalidStringFormat { input: I }, - KeywordNotFound { expected: I }, - UnexpectedKeyword { found: I, expected: I }, - EmptyKeyword { input: I }, - EmptyValue { input: I }, - UnexpectedEndOfInput { keyword: I }, - GeneralParserError(I, ErrorKind), -} - impl From>> for KvnDeserializerErr { fn from(value: nom::Err>) -> Self { match value { @@ -169,16 +158,6 @@ pub struct KvnDateTimeValue { pub full_value: String, } -pub trait KvnDeserializer { - fn deserialize<'a>( - lines: &mut std::iter::Peekable>, - ) -> Result> - where - Self: Sized; - - fn should_check_key_match() -> bool; -} - //@TODO remove _new suffix pub fn kvn_line_matches_key_new<'a>( key: &'a str, From f3991cba7b1c90b949e03c7af373f11da28d0c2f Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 15:16:44 +0300 Subject: [PATCH 110/150] Add submodule rustdoc --- crates/lox-io/src/ndm/ndm.rs | 10 ++++++++++ crates/lox-io/src/ndm/ocm.rs | 10 ++++++++++ crates/lox-io/src/ndm/oem.rs | 10 ++++++++++ crates/lox-io/src/ndm/omm.rs | 10 ++++++++++ crates/lox-io/src/ndm/opm.rs | 10 ++++++++++ 5 files changed, 50 insertions(+) diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index 39d9357b..31c49c66 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -1,3 +1,13 @@ +//! Deserializers for XML CCSDS Navigation Data Message Combined Instantiation +//! +//! To deserialize an XML message: +//! +//! ``` +//! use quick_xml::de::from_str; +//! +//! let message: NdmType = from_str(xml).unwrap(); +//! ``` + use serde; use super::{ocm, oem, omm, opm}; diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index 6acfd948..f860d2eb 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -6,6 +6,16 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Deserializers for XML and KVN CCSDS Orbit Comprehensive Message +//! +//! To deserialize an XML message: +//! +//! ``` +//! use quick_xml::de::from_str; +//! +//! let message: OcmType = from_str(xml).unwrap(); +//! ``` + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 0158b8ee..8df760eb 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -6,6 +6,16 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Deserializers for XML and KVN CCSDS Orbit Ephemeris Message +//! +//! To deserialize an XML message: +//! +//! ``` +//! use quick_xml::de::from_str; +//! +//! let message: OemType = from_str(xml).unwrap(); +//! ``` + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 9f50ba85..911627bc 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -6,6 +6,16 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Deserializers for XML and KVN CCSDS Orbit Mean Elements Message +//! +//! To deserialize an XML message: +//! +//! ``` +//! use quick_xml::de::from_str; +//! +//! let message: OmmType = from_str(xml).unwrap(); +//! ``` + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index b788045c..ee8ef3f5 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -6,6 +6,16 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Deserializers for XML and KVN CCSDS Orbit Parameter Message +//! +//! To deserialize an XML message: +//! +//! ``` +//! use quick_xml::de::from_str; +//! +//! let message: OpmType = from_str(xml).unwrap(); +//! ``` + use serde; use super::common; From c7afe4d569556c546b520d302b7d568810f90da5 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 15:16:56 +0300 Subject: [PATCH 111/150] Add missing copyright header --- crates/lox-io/src/ndm/ndm.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index 31c49c66..c27ed4da 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + //! Deserializers for XML CCSDS Navigation Data Message Combined Instantiation //! //! To deserialize an XML message: From 8d20e70a3e4175a135b0cf6ee5f26df5e1de9c52 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 15:17:07 +0300 Subject: [PATCH 112/150] Remove debug println --- crates/lox-io/src/ndm/ndm.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index c27ed4da..465a9f81 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -387,7 +387,6 @@ mod test { let message: NdmType = from_str(xml).unwrap(); - println!("{:#?}", message); assert_eq!( message, NdmType { From 70f7a30593c47826dd82f968279f9f9a1b4ff411 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 15:39:42 +0300 Subject: [PATCH 113/150] Reexport the KVN deserializer types --- crates/lox-derive/src/lib.rs | 46 ++++++++++++++--------------- crates/lox-io/src/ndm/kvn.rs | 4 ++- crates/lox-io/src/ndm/kvn/parser.rs | 2 ++ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 7d32437c..ad599236 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -21,21 +21,21 @@ fn generate_call_to_deserializer_for_kvn_type( "String" => quote! { crate::ndm::kvn::parser::parse_kvn_string_line_new( next_line - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "f64" => quote! { crate::ndm::kvn::parser::parse_kvn_numeric_line_new( next_line, true, //@TODO - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "i32" | "u64" => quote! { crate::ndm::kvn::parser::parse_kvn_integer_line_new( next_line, true, //@TODO - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, // Assumes the match list here exhaustively matches the one from above @@ -44,7 +44,7 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(quote! { match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { keyword: #expected_kvn_name }), Some(next_line) => { @@ -58,7 +58,7 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(#parser.value) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { found: next_line, expected: #expected_kvn_name, }) @@ -77,7 +77,7 @@ fn generate_call_to_deserializer_for_kvn_type( #expected_kvn_name, next_line, true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "KvnNumericValue" => quote! { @@ -85,7 +85,7 @@ fn generate_call_to_deserializer_for_kvn_type( #expected_kvn_name, next_line, true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "KvnIntegerValue" => quote! { @@ -93,7 +93,7 @@ fn generate_call_to_deserializer_for_kvn_type( #expected_kvn_name, next_line, true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, // Assumes the match list here exhaustively matches the one from above @@ -102,7 +102,7 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(quote! { match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { keyword: #expected_kvn_name }), Some(next_line) => { @@ -116,7 +116,7 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(#parser) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { found: next_line, expected: #expected_kvn_name, }) @@ -135,7 +135,7 @@ fn generate_call_to_deserializer_for_kvn_type( let result = if has_next_line { #type_name_new::deserialize(lines) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { keyword: #expected_kvn_name }) }; @@ -158,7 +158,7 @@ fn generate_call_to_deserializer_for_kvn_type_new( quote! { crate::ndm::kvn::parser::parse_kvn_string_line_new( lines.next().unwrap() - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? } } @@ -166,14 +166,14 @@ fn generate_call_to_deserializer_for_kvn_type_new( crate::ndm::kvn::parser::parse_kvn_numeric_line_new( lines.next().unwrap(), true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, "i32" => quote! { crate::ndm::kvn::parser::parse_kvn_integer_line_new( lines.next().unwrap(), true - ).map_err(|x| crate::ndm::kvn::parser::KvnDeserializerErr::from(x)) + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) .map(|x| x.1)? }, // Assumes the match list here exhaustively matches the one from above @@ -190,7 +190,7 @@ fn generate_call_to_deserializer_for_kvn_type_new( let result = if has_next_line { #type_name_new::deserialize(lines) } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { keyword: "Blala" //@TODO }) }; @@ -281,8 +281,8 @@ fn generate_call_to_deserializer_for_option_type( match result { Ok(item) => Some(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => None, Err(e) => Err(e)?, } } else { @@ -333,8 +333,8 @@ fn generate_call_to_deserializer_for_vec_type( match result { Ok(item) => items.push(item), - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedKeyword { .. }) | - Err(crate::ndm::kvn::parser::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedKeyword { .. }) | + Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { .. }) => break, Err(e) => Err(e)?, } } @@ -595,7 +595,7 @@ fn deserializer_for_struct_with_named_fields( quote! { match lines.peek() { - None => Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { + None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { keyword: #expected_kvn_name })?, Some(next_line) => { @@ -607,7 +607,7 @@ fn deserializer_for_struct_with_named_fields( if #condition_shortcut line_matches { #field_type_new::deserialize(lines)? } else { - Err(crate::ndm::kvn::parser::KvnDeserializerErr::<&str>::UnexpectedKeyword { + Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { found: next_line, expected: #expected_kvn_name, })? @@ -714,11 +714,11 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke let (impl_generics, type_generics, where_clause) = item.generics.split_for_impl(); let struct_deserializer = quote! { - impl #impl_generics crate::ndm::kvn::parser::KvnDeserializer for #type_name #type_generics + impl #impl_generics crate::ndm::kvn::KvnDeserializer for #type_name #type_generics #where_clause { fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) - -> Result<#type_name, crate::ndm::kvn::parser::KvnDeserializerErr<&'a str>> { + -> Result<#type_name, crate::ndm::kvn::KvnDeserializerErr<&'a str>> { #struct_deserializer } diff --git a/crates/lox-io/src/ndm/kvn.rs b/crates/lox-io/src/ndm/kvn.rs index 4837a11e..942de4aa 100644 --- a/crates/lox-io/src/ndm/kvn.rs +++ b/crates/lox-io/src/ndm/kvn.rs @@ -1,2 +1,4 @@ -pub mod deserializer; +mod deserializer; mod parser; + +pub use deserializer::{KvnDeserializer, KvnDeserializerErr}; diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index c5c7661c..bc32aa45 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -975,6 +975,8 @@ mod test { ); } + use super::super::KvnDeserializer; + #[derive(Default, Debug, PartialEq)] pub struct PositionUnits(pub std::string::String); From c17136194d5b637038c4702472ec8f33419e9039 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 6 Jun 2024 15:39:58 +0300 Subject: [PATCH 114/150] Add module docs --- crates/lox-io/src/ndm.rs | 12 ++++++++++++ crates/lox-io/src/ndm/common.rs | 2 ++ crates/lox-io/src/ndm/json.rs | 10 ++++++++++ crates/lox-io/src/ndm/json/omm.rs | 14 ++++++++++++++ crates/lox-io/src/ndm/kvn.rs | 2 ++ crates/lox-io/src/ndm/ndm.rs | 4 +--- crates/lox-io/src/ndm/ocm.rs | 3 +-- crates/lox-io/src/ndm/oem.rs | 4 +--- crates/lox-io/src/ndm/omm.rs | 4 +--- crates/lox-io/src/ndm/opm.rs | 4 +--- 10 files changed, 45 insertions(+), 14 deletions(-) diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index 7cd474f5..a042c01e 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -1,3 +1,15 @@ +//! Parsers for CCSDS +//! [Navigation Data Messages version 3](https://public.ccsds.org/Pubs/502x0b3e1.pdf). +//! +//! The data types used to deserialize XML and KVN are generated from the CCSDS +//! NDM schema description. Some slight alterations have been made on top to +//! improve user friendliness and compatibility. +//! +//! Since Rust XML and JSON deserializers are slightly incompatible, the JSON +//! deserializer is separate. +//! +//! Check the respective submodules for more information. + pub mod json; pub mod kvn; diff --git a/crates/lox-io/src/ndm/common.rs b/crates/lox-io/src/ndm/common.rs index 3aa1997b..1d7947ee 100644 --- a/crates/lox-io/src/ndm/common.rs +++ b/crates/lox-io/src/ndm/common.rs @@ -6,6 +6,8 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Data types shared between different NDM message types + use serde; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] diff --git a/crates/lox-io/src/ndm/json.rs b/crates/lox-io/src/ndm/json.rs index 9e0899c1..9495e33b 100644 --- a/crates/lox-io/src/ndm/json.rs +++ b/crates/lox-io/src/ndm/json.rs @@ -1 +1,11 @@ +//! Deserializers for some JSON message types +//! +//! JSON message types are not fully standardized at CCSDS level. But they are +//! sometimes used in the wild due to the abundant availability of parsers. +//! +//! Only OMM messages were found to be used in the wild, so it is the only one +//! implemented. +//! +//! The data type is manually derived from the XML schema. + pub mod omm; diff --git a/crates/lox-io/src/ndm/json/omm.rs b/crates/lox-io/src/ndm/json/omm.rs index 6312f900..6524135c 100644 --- a/crates/lox-io/src/ndm/json/omm.rs +++ b/crates/lox-io/src/ndm/json/omm.rs @@ -6,6 +6,20 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ +//! Deserializers for JSON CCSDS Orbit Mean Elements Message +//! +//! To deserialize a JSON message: +//! +//! ``` +//! let message: OmmType = serde_json::de::from_str(json).unwrap(); +//! ``` +//! +//! To deserialize a list of JSON messages: +//! +//! ``` +//! let message: Vec = serde_json::de::from_str(json).unwrap(); +//! ``` + use serde_aux::prelude::*; use std::collections::HashMap; diff --git a/crates/lox-io/src/ndm/kvn.rs b/crates/lox-io/src/ndm/kvn.rs index 942de4aa..2b58af9f 100644 --- a/crates/lox-io/src/ndm/kvn.rs +++ b/crates/lox-io/src/ndm/kvn.rs @@ -1,3 +1,5 @@ +//! The public interface for the `KvnDeserializer` type + mod deserializer; mod parser; diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index 465a9f81..00c7e48c 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -11,9 +11,7 @@ //! To deserialize an XML message: //! //! ``` -//! use quick_xml::de::from_str; -//! -//! let message: NdmType = from_str(xml).unwrap(); +//! let message: NdmType = quick_xml::de::from_str(xml).unwrap(); //! ``` use serde; diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index f860d2eb..6ff0e00a 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -11,9 +11,8 @@ //! To deserialize an XML message: //! //! ``` -//! use quick_xml::de::from_str; //! -//! let message: OcmType = from_str(xml).unwrap(); +//! let message: OcmType = quick_xml::de::from_str(xml).unwrap(); //! ``` use serde; diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 8df760eb..5f9e04a8 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -11,9 +11,7 @@ //! To deserialize an XML message: //! //! ``` -//! use quick_xml::de::from_str; -//! -//! let message: OemType = from_str(xml).unwrap(); +//! let message: OemType = quick_xml::de::from_str(xml).unwrap(); //! ``` use serde; diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 911627bc..49a539cc 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -11,9 +11,7 @@ //! To deserialize an XML message: //! //! ``` -//! use quick_xml::de::from_str; -//! -//! let message: OmmType = from_str(xml).unwrap(); +//! let message: OmmType = quick_xml::de::from_str(xml).unwrap(); //! ``` use serde; diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index ee8ef3f5..1d9a5e72 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -11,9 +11,7 @@ //! To deserialize an XML message: //! //! ``` -//! use quick_xml::de::from_str; -//! -//! let message: OpmType = from_str(xml).unwrap(); +//! let message: OpmType = quick_xml::de::from_str(xml).unwrap(); //! ``` use serde; From f9469d77a1b7c708100ccaa27102ffc36ffd7e6c Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:45:54 +0300 Subject: [PATCH 115/150] Clean-up string type Parsing multi-segment type paths with syn in proc macros is annoying. So this simplifies everything a little bit --- crates/lox-io/src/ndm/common.rs | 116 ++++++++++++++++---------------- crates/lox-io/src/ndm/omm.rs | 16 ++--- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/crates/lox-io/src/ndm/common.rs b/crates/lox-io/src/ndm/common.rs index 1d7947ee..02fd15f1 100644 --- a/crates/lox-io/src/ndm/common.rs +++ b/crates/lox-io/src/ndm/common.rs @@ -12,11 +12,11 @@ use serde; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AccUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AccUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -24,11 +24,11 @@ pub struct AngleRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngMomentumUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AngMomentumUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -36,19 +36,19 @@ pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AreaUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AreaUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DayIntervalUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct FrequencyUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GmUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct GmUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -56,47 +56,47 @@ pub struct InclinationRange(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LengthUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct LengthUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MassUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct MassUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct MomentUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct MomentUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct WkgUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct WkgUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub std::string::String); +pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Ms2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Ms2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2sUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2sUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Km2s2Units(#[serde(rename = "$text")] pub std::string::String); +pub struct Km2s2Units(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct VelocityUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq)] pub struct VecDouble { @@ -117,15 +117,15 @@ pub struct Vec9Double(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct EpochType(#[serde(rename = "$text")] pub std::string::String); +pub struct EpochType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct TimeUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TimeSystemType(#[serde(rename = "$text")] pub std::string::String); +pub struct TimeSystemType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -137,11 +137,11 @@ pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NonPositiveDouble(#[serde(rename = "$text")] pub std::string::String); +pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentType(#[serde(rename = "$text")] pub std::string::String); +pub struct PercentType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -149,139 +149,139 @@ pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct Range100Type(#[serde(rename = "$text")] pub std::string::String); +pub struct Range100Type(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ProbabilityType(#[serde(rename = "$text")] pub std::string::String); +pub struct ProbabilityType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PercentageUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PercentageUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct YesNoType(#[serde(rename = "$text")] pub std::string::String); +pub struct YesNoType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TrajBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct TrajBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RevNumBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct RevNumBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct CovBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManBasisType(#[serde(rename = "$text")] pub std::string::String); +pub struct ManBasisType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ManDcType(#[serde(rename = "$text")] pub std::string::String); +pub struct ManDcType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct NumPerYearUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct NumPerYearUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ThrustUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct ThrustUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct CovOrderType(#[serde(rename = "$text")] pub std::string::String); +pub struct CovOrderType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct GeomagUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct GeomagUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct SolarFluxUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct SolarFluxUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub std::string::String); +pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatRange(#[serde(rename = "$text")] pub std::string::String); +pub struct LatRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AltRange(#[serde(rename = "$text")] pub std::string::String); +pub struct AltRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LonRange(#[serde(rename = "$text")] pub std::string::String); +pub struct LonRange(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct LatLonUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct LatLonUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ControlledType(#[serde(rename = "$text")] pub std::string::String); +pub struct ControlledType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DisintegrationType(#[serde(rename = "$text")] pub std::string::String); +pub struct DisintegrationType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub std::string::String); +pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub std::string::String); +pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionComponentType(#[serde(rename = "$text")] pub std::string::String); +pub struct QuaternionComponentType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotDirectionType(#[serde(rename = "$text")] pub std::string::String); +pub struct RotDirectionType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RotseqType(#[serde(rename = "$text")] pub std::string::String); +pub struct RotseqType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleKeywordType(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleKeywordType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub std::string::String); +pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ApmRateFrameType(#[serde(rename = "$text")] pub std::string::String); +pub struct ApmRateFrameType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct TorqueUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct TorqueUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 49a539cc..4edf10c6 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -20,35 +20,35 @@ use super::common; #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BStarUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct BStarUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct BTermUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct BTermUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct AgomUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct AgomUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct ElementSetNoType(#[serde(rename = "$text")] pub std::string::String); +pub struct ElementSetNoType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct RevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct RevUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DRevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DRevUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct DdRevUnits(#[serde(rename = "$text")] pub std::string::String); +pub struct DdRevUnits(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] -pub struct SpacewarnType(#[serde(rename = "$text")] pub std::string::String); +pub struct SpacewarnType(#[serde(rename = "$text")] pub String); #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] From 0a0a5b4c6acdcf388d76d0b46b69ddb618fd2dcd Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:50:44 +0300 Subject: [PATCH 116/150] Derive KVN deserialization code --- crates/lox-io/src/ndm/common.rs | 602 ++++++++++++++++++++++++++++---- crates/lox-io/src/ndm/ocm.rs | 110 +++++- crates/lox-io/src/ndm/omm.rs | 210 +++++++++-- crates/lox-io/src/ndm/opm.rs | 70 +++- 4 files changed, 894 insertions(+), 98 deletions(-) diff --git a/crates/lox-io/src/ndm/common.rs b/crates/lox-io/src/ndm/common.rs index 02fd15f1..00ee4d3b 100644 --- a/crates/lox-io/src/ndm/common.rs +++ b/crates/lox-io/src/ndm/common.rs @@ -38,7 +38,15 @@ pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct AreaUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); @@ -54,7 +62,15 @@ pub struct GmUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct InclinationRange(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct LengthUnits(#[serde(rename = "$text")] pub String); @@ -66,11 +82,27 @@ pub struct MassUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct MomentUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct WkgUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); @@ -103,7 +135,15 @@ pub struct VecDouble { pub items: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct Vec3Double(#[serde(rename = "$text")] pub f64); @@ -115,11 +155,27 @@ pub struct Vec6Double(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct Vec9Double(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct EpochType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TimeUnits(#[serde(rename = "$text")] pub String); @@ -131,7 +187,15 @@ pub struct TimeSystemType(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); @@ -143,19 +207,51 @@ pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct PercentType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PositiveDouble(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct Range100Type(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ProbabilityType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PercentageUnits(#[serde(rename = "$text")] pub String); @@ -163,43 +259,123 @@ pub struct PercentageUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct YesNoType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TrajBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct RevNumBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct CovBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManBasisType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManDcType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct NumPerYearUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ThrustUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct CovOrderType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct GeomagUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SolarFluxUnits(#[serde(rename = "$text")] pub String); @@ -307,7 +483,15 @@ pub struct AdmHeader { pub message_id: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OdmHeader { #[serde(rename = "COMMENT")] @@ -322,8 +506,17 @@ pub struct OdmHeader { pub message_id: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AccType { #[serde(rename = "$text")] pub base: f64, @@ -331,17 +524,35 @@ pub struct AccType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngleType { #[serde(rename = "$text")] - pub base: AngleRange, + pub base: f64, #[serde(rename = "@units")] pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngleRateType { #[serde(rename = "$text")] pub base: f64, @@ -358,8 +569,17 @@ pub struct AngMomentumType { pub units: AngMomentumUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AngVelComponentType { #[serde(rename = "$text")] pub base: f64, @@ -386,7 +606,15 @@ pub struct AngVelStateType { pub angvel_z: AngVelComponentType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct AngVelType { #[serde(rename = "ANGVEL_X")] @@ -397,8 +625,17 @@ pub struct AngVelType { pub angvel_z: AngVelComponentType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct AreaType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -415,7 +652,15 @@ pub struct DayIntervalType { pub units: DayIntervalUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmDayIntervalType { #[serde(rename = "$text")] @@ -424,8 +669,17 @@ pub struct OcmDayIntervalType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DeltamassType { #[serde(rename = "$text")] pub base: NegativeDouble, @@ -451,8 +705,17 @@ pub struct FrequencyType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct GmType { #[serde(rename = "$text")] pub base: PositiveDouble, @@ -460,8 +723,17 @@ pub struct GmType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct InclinationType { #[serde(rename = "$text")] pub base: InclinationRange, @@ -478,7 +750,15 @@ pub struct LengthType { pub units: LengthUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmLengthType { #[serde(rename = "$text")] @@ -487,8 +767,17 @@ pub struct OcmLengthType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct MassType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -496,8 +785,17 @@ pub struct MassType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct MomentType { #[serde(rename = "$text")] pub base: f64, @@ -505,7 +803,15 @@ pub struct MomentType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct WkgType { #[serde(rename = "$text")] @@ -541,7 +847,15 @@ pub struct OdParametersType { pub weighted_rms: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SpacecraftParametersType { #[serde(rename = "COMMENT")] @@ -558,7 +872,15 @@ pub struct SpacecraftParametersType { pub drag_coeff: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct StateVectorType { #[serde(rename = "COMMENT")] @@ -613,8 +935,17 @@ pub struct Ms2Type { pub units: Ms2Units, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2Type { #[serde(rename = "$text")] pub base: f64, @@ -622,8 +953,17 @@ pub struct Km2Type { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2sType { #[serde(rename = "$text")] pub base: f64, @@ -631,8 +971,17 @@ pub struct Km2sType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct Km2s2Type { #[serde(rename = "$text")] pub base: f64, @@ -640,8 +989,17 @@ pub struct Km2s2Type { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DistanceType { #[serde(rename = "$text")] pub base: f64, @@ -649,8 +1007,17 @@ pub struct DistanceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionType { #[serde(rename = "$text")] pub base: f64, @@ -665,8 +1032,17 @@ pub struct RdmPositionType { pub base: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct VelocityType { #[serde(rename = "$text")] pub base: f64, @@ -681,8 +1057,17 @@ pub struct RdmVelocityType { pub base: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct DurationType { #[serde(rename = "$text")] pub base: NonNegativeDouble, @@ -699,7 +1084,15 @@ pub struct RelTimeType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TimeOffsetType { #[serde(rename = "$text")] @@ -708,7 +1101,15 @@ pub struct TimeOffsetType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct PercentageType { #[serde(rename = "$text")] @@ -717,7 +1118,15 @@ pub struct PercentageType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManeuverFreqType { #[serde(rename = "$text")] @@ -726,7 +1135,15 @@ pub struct ManeuverFreqType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ThrustType { #[serde(rename = "$text")] @@ -735,7 +1152,15 @@ pub struct ThrustType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct GeomagType { #[serde(rename = "$text")] @@ -744,7 +1169,15 @@ pub struct GeomagType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SolarFluxType { #[serde(rename = "$text")] @@ -806,7 +1239,15 @@ pub struct OemCovarianceMatrixType { pub cz_dot_z_dot: VelocityCovarianceType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmCovarianceMatrixType { #[serde(rename = "COMMENT")] @@ -857,8 +1298,17 @@ pub struct OpmCovarianceMatrixType { pub cz_dot_z_dot: VelocityCovarianceType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -866,8 +1316,17 @@ pub struct PositionCovarianceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct VelocityCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -875,8 +1334,17 @@ pub struct VelocityCovarianceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] +#[kvn(value_unit_struct)] pub struct PositionVelocityCovarianceType { #[serde(rename = "$text")] pub base: f64, @@ -1037,7 +1505,15 @@ pub struct LonType { pub units: LatLonUnits, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct UserDefinedType { #[serde(rename = "COMMENT")] @@ -1046,7 +1522,15 @@ pub struct UserDefinedType { pub user_defined_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct UserDefinedParameterType { #[serde(rename = "$text")] diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index 6ff0e00a..f2873b20 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -19,7 +19,15 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmType { #[serde(rename = "header")] @@ -32,14 +40,30 @@ pub struct OcmType { pub version: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmBody { #[serde(rename = "segment")] pub segment: OcmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmSegment { #[serde(rename = "metadata")] @@ -48,7 +72,15 @@ pub struct OcmSegment { pub data: OcmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmMetadata { #[serde(rename = "COMMENT")] @@ -149,7 +181,15 @@ pub struct OcmMetadata { pub celestial_source: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmData { #[serde(rename = "traj")] @@ -168,7 +208,15 @@ pub struct OcmData { pub user: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmTrajStateType { #[serde(rename = "COMMENT")] @@ -213,7 +261,15 @@ pub struct OcmTrajStateType { pub traj_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmPhysicalDescriptionType { #[serde(rename = "COMMENT")] @@ -320,7 +376,15 @@ pub struct OcmPhysicalDescriptionType { pub iyz: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmCovarianceMatrixType { #[serde(rename = "COMMENT")] @@ -355,7 +419,15 @@ pub struct OcmCovarianceMatrixType { pub cov_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmManeuverParametersType { #[serde(rename = "COMMENT")] @@ -424,7 +496,15 @@ pub struct OcmManeuverParametersType { pub man_line_list: Vec, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmPerturbationsType { #[serde(rename = "COMMENT")] @@ -489,7 +569,15 @@ pub struct OcmPerturbationsType { pub fixed_y10p7_mean: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OcmOdParametersType { #[serde(rename = "COMMENT")] diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 4edf10c6..1fe0a504 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -18,39 +18,111 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BStarUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BTermUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct AgomUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ElementSetNoType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct RevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DRevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DdRevUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct SpacewarnType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmType { #[serde(rename = "header")] @@ -63,14 +135,30 @@ pub struct OmmType { pub version: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmBody { #[serde(rename = "segment")] pub segment: OmmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmSegment { #[serde(rename = "metadata")] @@ -79,7 +167,15 @@ pub struct OmmSegment { pub data: OmmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmMetadata { #[serde(rename = "COMMENT")] @@ -100,7 +196,15 @@ pub struct OmmMetadata { pub mean_element_theory: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OmmData { #[serde(rename = "COMMENT")] @@ -117,7 +221,15 @@ pub struct OmmData { pub user_defined_parameters: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct MeanElementsType { #[serde(rename = "COMMENT")] @@ -142,7 +254,15 @@ pub struct MeanElementsType { pub gm: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct TleParametersType { #[serde(rename = "COMMENT")] @@ -169,7 +289,15 @@ pub struct TleParametersType { pub agom: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BStarType { #[serde(rename = "$text")] @@ -178,7 +306,15 @@ pub struct BStarType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct BTermType { #[serde(rename = "$text")] @@ -187,7 +323,15 @@ pub struct BTermType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct AgomType { #[serde(rename = "$text")] @@ -196,7 +340,15 @@ pub struct AgomType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct RevType { #[serde(rename = "$text")] @@ -205,7 +357,15 @@ pub struct RevType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DRevType { #[serde(rename = "$text")] @@ -214,7 +374,15 @@ pub struct DRevType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct DdRevType { #[serde(rename = "$text")] diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 1d9a5e72..7f8e9920 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -18,7 +18,15 @@ use serde; use super::common; -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmType { #[serde(rename = "header")] @@ -31,14 +39,30 @@ pub struct OpmType { pub version: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmBody { #[serde(rename = "segment")] pub segment: OpmSegment, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmSegment { #[serde(rename = "metadata")] @@ -47,7 +71,15 @@ pub struct OpmSegment { pub data: OpmData, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmMetadata { #[serde(rename = "COMMENT")] @@ -66,7 +98,15 @@ pub struct OpmMetadata { pub time_system: String, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct OpmData { #[serde(rename = "COMMENT")] @@ -85,7 +125,15 @@ pub struct OpmData { pub user_defined_parameters: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct KeplerianElementsType { #[serde(rename = "COMMENT")] @@ -108,7 +156,15 @@ pub struct KeplerianElementsType { pub gm: common::GmType, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + serde::Deserialize, + serde::Serialize, + lox_derive::KvnDeserialize, +)] #[serde(default)] pub struct ManeuverParametersType { #[serde(rename = "COMMENT")] From b785554bb0680bf57b74ed92915a4a80ed4ac703 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:51:12 +0300 Subject: [PATCH 117/150] Make the parser visible in the crate --- crates/lox-io/src/ndm/kvn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn.rs b/crates/lox-io/src/ndm/kvn.rs index 2b58af9f..848dbdc5 100644 --- a/crates/lox-io/src/ndm/kvn.rs +++ b/crates/lox-io/src/ndm/kvn.rs @@ -1,6 +1,6 @@ //! The public interface for the `KvnDeserializer` type mod deserializer; -mod parser; +pub(crate) mod parser; pub use deserializer::{KvnDeserializer, KvnDeserializerErr}; From 81d0d220517af27a02190626d7b51eafc1c252c1 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:55:07 +0300 Subject: [PATCH 118/150] Simplify the wrapped types It complicates the kvn value unit struct deserialization uncessesarily. --- crates/lox-io/src/ndm/common.rs | 14 ++-------- crates/lox-io/src/ndm/ndm.rs | 48 ++++++++++++++++---------------- crates/lox-io/src/ndm/omm.rs | 49 ++++++++++++++------------------- crates/lox-io/src/ndm/opm.rs | 8 +++--- 4 files changed, 52 insertions(+), 67 deletions(-) diff --git a/crates/lox-io/src/ndm/common.rs b/crates/lox-io/src/ndm/common.rs index 00ee4d3b..9363fb4f 100644 --- a/crates/lox-io/src/ndm/common.rs +++ b/crates/lox-io/src/ndm/common.rs @@ -18,10 +18,6 @@ pub struct AccUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct AngleUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleRange(#[serde(rename = "$text")] pub f64); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); @@ -58,10 +54,6 @@ pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct GmUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct InclinationRange(#[serde(rename = "$text")] pub f64); - #[derive( Clone, Debug, @@ -736,7 +728,7 @@ pub struct GmType { #[kvn(value_unit_struct)] pub struct InclinationType { #[serde(rename = "$text")] - pub base: InclinationRange, + pub base: f64, #[serde(rename = "@units")] pub units: Option, } @@ -1575,14 +1567,14 @@ pub struct RotationAngleComponentTypeold { #[serde(rename = "@angle")] pub angle: AngleKeywordType, #[serde(rename = "@value")] - pub value: AngleRange, + pub value: f64, } #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct RotationAngleComponentType { #[serde(rename = "$text")] - pub base: AngleRange, + pub base: f64, #[serde(rename = "@angle")] pub angle: AngleKeywordType, #[serde(rename = "@units")] diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index 00c7e48c..d03c7a55 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -420,19 +420,19 @@ mod test { mean_motion: None, eccentricity: common::NonNegativeDouble(0.0), inclination: common::InclinationType { - base: common::InclinationRange(0.0), + base: 0.0, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(0.0), + base: 0.0, units: None, }, gm: None, @@ -481,19 +481,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.001178), inclination: common::InclinationType { - base: common::InclinationRange(97.409), + base: 97.409, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(71.7453), + base: 71.7453, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(193.9419), + base: 193.9419, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(272.1492), + base: 272.1492, units: None, }, gm: None, @@ -588,19 +588,19 @@ mod test { }, eccentricity: common::NonNegativeDouble(0.0,), inclination: common::InclinationType { - base: common::InclinationRange(45.0,), + base: 45.0, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(0.0,), + base: 0.0, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(15.0,), + base: 15.0, units: Some(common::AngleUnits("deg".to_string(),),), }, true_anomaly: Some(common::AngleType { - base: common::AngleRange(15.0,), + base: 15.0, units: Some(common::AngleUnits("deg".to_string(),),), },), mean_anomaly: None, @@ -945,19 +945,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009574), inclination: common::InclinationType { - base: common::InclinationRange(97.2663), + base: 97.2663, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.2167), + base: 51.2167, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(149.8567), + base: 149.8567, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(322.5146), + base: 322.5146, units: None, }, gm: None, @@ -1029,19 +1029,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009674), inclination: common::InclinationType { - base: common::InclinationRange(97.2671), + base: 97.2671, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.3486), + base: 51.3486, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(160.8608), + base: 160.8608, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(302.2789), + base: 302.2789, units: None, }, gm: None, @@ -1113,19 +1113,19 @@ mod test { }), eccentricity: common::NonNegativeDouble(0.0009024), inclination: common::InclinationType { - base: common::InclinationRange(97.2666), + base: 97.2666, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(51.2301), + base: 51.2301, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(167.2057), + base: 167.2057, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(304.5569), + base: 304.5569, units: None, }, gm: None, diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 1fe0a504..92c681e2 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -503,27 +503,19 @@ mod test { 0.0005013, ), inclination: common::InclinationType { - base: common::InclinationRange( - 3.0539, - ), + base: 3.0539, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange( - 81.7939, - ), + base: 81.7939, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange( - 249.2363, - ), + base: 249.2363, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange( - 150.1602, - ), + base: 150.1602, units: None, }, gm: Some( @@ -710,19 +702,20 @@ mod test { },), eccentricity: common::NonNegativeDouble(0.0205751,), inclination: common::InclinationType { - base: common::InclinationRange(49.8237,), + base: 49.8237, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(93.8140,), + base: 93.8140, + units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(224.8348,), + base: 224.8348, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(133.5761,), + base: 133.5761, units: None, }, gm: None, @@ -869,19 +862,19 @@ mod test { },), eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { - base: common::InclinationRange(3.0539,), + base: 3.0539, units: None, }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(81.7939,), + base: 81.7939, units: None, }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(249.2363,), + base: 249.2363, units: None, }, mean_anomaly: common::AngleType { - base: common::AngleRange(150.1602,), + base: 150.1602, units: None, }, gm: Some(common::GmType { @@ -1121,19 +1114,19 @@ mod test { },), eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { - base: common::InclinationRange(3.0539,), + base: 3.0539, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(81.7939,), + base: 81.7939, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(249.2363,), + base: 249.2363, units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { - base: common::AngleRange(150.1602,), + base: 150.1602, units: Some(common::AngleUnits("deg".to_string(),),), }, gm: Some(common::GmType { @@ -1346,19 +1339,19 @@ mod test { },), eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { - base: common::InclinationRange(51.6416,), + base: 51.6416, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(247.4627,), + base: 247.4627, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(130.536,), + base: 130.536, units: Some(common::AngleUnits("deg".to_string(),),), }, mean_anomaly: common::AngleType { - base: common::AngleRange(325.0288,), + base: 325.0288, units: Some(common::AngleUnits("deg".to_string(),),), }, gm: Some(common::GmType { diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 7f8e9920..fd4d9ae0 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -352,19 +352,19 @@ mod test { }, eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { - base: common::InclinationRange(51.6416,), + base: 51.6416, units: Some(common::AngleUnits("deg".to_string(),),), }, ra_of_asc_node: common::AngleType { - base: common::AngleRange(247.463,), + base: 247.463, units: Some(common::AngleUnits("deg".to_string(),),), }, arg_of_pericenter: common::AngleType { - base: common::AngleRange(130.536,), + base: 130.536, units: Some(common::AngleUnits("deg".to_string(),),), }, true_anomaly: Some(common::AngleType { - base: common::AngleRange(324.985,), + base: 324.985, units: Some(common::AngleUnits("deg".to_string(),),), },), mean_anomaly: None, From d492e17c9fc2ca32541620e28ce843c3e3766283 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:56:58 +0300 Subject: [PATCH 119/150] Make the id value optional for KVN It seems it's only used in the XML context. --- crates/lox-io/src/ndm/ndm.rs | 14 +++++++------- crates/lox-io/src/ndm/omm.rs | 13 +++++++------ crates/lox-io/src/ndm/opm.rs | 5 +++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index d03c7a55..4906b325 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -444,7 +444,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -528,7 +528,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Opm(opm::OpmType { @@ -658,7 +658,7 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), version: "2.0".to_string(), },), NdmChildChoice::Opm(opm::OpmType { @@ -760,7 +760,7 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), version: "2.0".to_string(), },), NdmChildChoice::Oem(oem::OemType { @@ -992,7 +992,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -1076,7 +1076,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), NdmChildChoice::Omm(omm::OmmType { @@ -1160,7 +1160,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }), ], diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 92c681e2..39f8d0d0 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -130,7 +130,8 @@ pub struct OmmType { #[serde(rename = "body")] pub body: OmmBody, #[serde(rename = "@id")] - pub id: String, + // Marked as option for the KVN deserializer + pub id: Option, #[serde(rename = "@version")] pub version: String, } @@ -615,7 +616,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), }); } @@ -748,7 +749,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), } ); @@ -997,7 +998,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "3.0".to_string(), } ); @@ -1249,7 +1250,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "3.0".to_string(), } ); @@ -1399,7 +1400,7 @@ mod test { }, }, }, - id: "CCSDS_OMM_VERS".to_string(), + id: Some("CCSDS_OMM_VERS".to_string()), version: "2.0".to_string(), } ); diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index fd4d9ae0..a9a02a7e 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -34,7 +34,8 @@ pub struct OpmType { #[serde(rename = "body")] pub body: OpmBody, #[serde(rename = "@id")] - pub id: String, + // Marked as option for the KVN deserializer + pub id: Option, #[serde(rename = "@version")] pub version: String, } @@ -538,7 +539,7 @@ mod test { }, }, }, - id: "CCSDS_OPM_VERS".to_string(), + id: Some("CCSDS_OPM_VERS".to_string()), version: "3.0".to_string(), } ); From 9dc20fe8e18a3f0e8872d45cf5e1539dc1e5797d Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 14:58:24 +0300 Subject: [PATCH 120/150] Add KVN parsing tests --- crates/lox-io/src/ndm/omm.rs | 238 ++++++++++++++++++++++++++++++++++- crates/lox-io/src/ndm/opm.rs | 229 ++++++++++++++++++++++++++++++++- 2 files changed, 461 insertions(+), 6 deletions(-) diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 39f8d0d0..0ac8127a 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -399,7 +399,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_omm_message1() { + fn test_parse_omm_message_xml_1() { let xml = r#"
@@ -1435,4 +1435,232 @@ mod test { assert!(message.is_err()); } + + #[test] + fn test_parse_omm_message_kvn() { + //@TOOD add back user defined stuff + let kvn = r#"CCSDS_OMM_VERS = 3.0 + COMMENT this is a comment + COMMENT here is another one + CREATION_DATE = 2007-065T16:00:00 + ORIGINATOR = NOAA/USA + COMMENT this comment doesn't say much + OBJECT_NAME = GOES 9 + OBJECT_ID = 1995-025A + CENTER_NAME = EARTH + REF_FRAME = TOD + REF_FRAME_EPOCH = 2000-003T10:34:00 + TIME_SYSTEM = MRT + MEAN_ELEMENT_THEORY = SOME THEORY + COMMENT the following data is what we're looking for + EPOCH = 2000-005T10:00:00 + SEMI_MAJOR_AXIS = 6800 + ECCENTRICITY = 0.0005013 + INCLINATION = 3.0539 + RA_OF_ASC_NODE = 81.7939 + ARG_OF_PERICENTER = 249.2363 + MEAN_ANOMALY = 150.1602 + COMMENT spacecraft data + MASS = 300 + SOLAR_RAD_AREA = 5 + SOLAR_RAD_COEFF = 0.001 + DRAG_AREA = 4 + DRAG_COEFF = 0.002 + COMMENT Covariance matrix + COV_REF_FRAME = TNW + CX_X = 3.331349476038534e-04 + CY_X = 4.618927349220216e-04 + CY_Y = 6.782421679971363e-04 + CZ_X = -3.070007847730449e-04 + CZ_Y = -4.221234189514228e-04 + CZ_Z = 3.231931992380369e-04 + CX_DOT_X = -3.349365033922630e-07 + CX_DOT_Y = -4.686084221046758e-07 + CX_DOT_Z = 2.484949578400095e-07 + CX_DOT_X_DOT = 4.296022805587290e-10 + CY_DOT_X = -2.211832501084875e-07 + CY_DOT_Y = -2.864186892102733e-07 + CY_DOT_Z = 1.798098699846038e-07 + CY_DOT_X_DOT = 2.608899201686016e-10 + CY_DOT_Y_DOT = 1.767514756338532e-10 + CZ_DOT_X = -3.041346050686871e-07 + CZ_DOT_Y = -4.989496988610662e-07 + CZ_DOT_Z = 3.540310904497689e-07 + CZ_DOT_X_DOT = 1.869263192954590e-10 + CZ_DOT_Y_DOT = 1.008862586240695e-10 + CZ_DOT_Z_DOT = 6.224444338635500e-10"#; + + assert_eq!( + crate::ndm::kvn::KvnDeserializer::deserialize(&mut kvn.lines().peekable()), + Ok(OmmType { + header: common::OdmHeader { + comment_list: vec![ + "this is a comment".to_string(), + "here is another one".to_string(), + ], + classification_list: vec![], + creation_date: common::EpochType("2007-065T16:00:00".to_string(),), + originator: "NOAA/USA".to_string(), + message_id: None, + }, + body: OmmBody { + segment: OmmSegment { + metadata: OmmMetadata { + comment_list: vec!["this comment doesn't say much".to_string(),], + object_name: "GOES 9".to_string(), + object_id: "1995-025A".to_string(), + center_name: "EARTH".to_string(), + ref_frame: "TOD".to_string(), + ref_frame_epoch: Some(common::EpochType( + "2000-003T10:34:00".to_string(), + ),), + time_system: "MRT".to_string(), + mean_element_theory: "SOME THEORY".to_string(), + }, + data: OmmData { + comment_list: vec![ + "the following data is what we're looking for".to_string(), + ], + mean_elements: MeanElementsType { + comment_list: vec![], + epoch: common::EpochType("2000-005T10:00:00".to_string(),), + semi_major_axis: Some(common::DistanceType { + base: 6800.0, + units: None, + },), + mean_motion: None, + eccentricity: common::NonNegativeDouble(0.0005013,), + inclination: common::InclinationType { + base: 3.0539, + units: None, + }, + ra_of_asc_node: common::AngleType { + base: 81.7939, + units: None, + }, + arg_of_pericenter: common::AngleType { + base: 249.2363, + units: None, + }, + mean_anomaly: common::AngleType { + base: 150.1602, + units: None, + }, + gm: None, + }, + spacecraft_parameters: Some(common::SpacecraftParametersType { + comment_list: vec!["spacecraft data".to_string(),], + mass: Some(common::MassType { + base: common::NonNegativeDouble(300.0,), + units: None, + },), + solar_rad_area: Some(common::AreaType { + base: common::NonNegativeDouble(5.0,), + units: None, + },), + solar_rad_coeff: Some(common::NonNegativeDouble(0.001,),), + drag_area: Some(common::AreaType { + base: common::NonNegativeDouble(4.0,), + units: None, + },), + drag_coeff: Some(common::NonNegativeDouble(0.002,),), + },), + tle_parameters: None, + covariance_matrix: Some(common::OpmCovarianceMatrixType { + comment_list: vec![], + cov_ref_frame: Some("TNW".to_string(),), + cx_x: common::PositionCovarianceType { + base: 0.0003331349476038534, + units: None, + }, + cy_x: common::PositionCovarianceType { + base: 0.0004618927349220216, + units: None, + }, + cy_y: common::PositionCovarianceType { + base: 0.0006782421679971363, + units: None, + }, + cz_x: common::PositionCovarianceType { + base: -0.0003070007847730449, + units: None, + }, + cz_y: common::PositionCovarianceType { + base: -0.0004221234189514228, + units: None, + }, + cz_z: common::PositionCovarianceType { + base: 0.0003231931992380369, + units: None, + }, + cx_dot_x: common::PositionVelocityCovarianceType { + base: -3.34936503392263e-7, + units: None, + }, + cx_dot_y: common::PositionVelocityCovarianceType { + base: -4.686084221046758e-7, + units: None, + }, + cx_dot_z: common::PositionVelocityCovarianceType { + base: 2.484949578400095e-7, + units: None, + }, + cx_dot_x_dot: common::VelocityCovarianceType { + base: 4.29602280558729e-10, + units: None, + }, + cy_dot_x: common::PositionVelocityCovarianceType { + base: -2.211832501084875e-7, + units: None, + }, + cy_dot_y: common::PositionVelocityCovarianceType { + base: -2.864186892102733e-7, + units: None, + }, + cy_dot_z: common::PositionVelocityCovarianceType { + base: 1.798098699846038e-7, + units: None, + }, + cy_dot_x_dot: common::VelocityCovarianceType { + base: 2.608899201686016e-10, + units: None, + }, + cy_dot_y_dot: common::VelocityCovarianceType { + base: 1.767514756338532e-10, + units: None, + }, + cz_dot_x: common::PositionVelocityCovarianceType { + base: -3.041346050686871e-7, + units: None, + }, + cz_dot_y: common::PositionVelocityCovarianceType { + base: -4.989496988610662e-7, + units: None, + }, + cz_dot_z: common::PositionVelocityCovarianceType { + base: 3.540310904497689e-7, + units: None, + }, + cz_dot_x_dot: common::VelocityCovarianceType { + base: 1.86926319295459e-10, + units: None, + }, + cz_dot_y_dot: common::VelocityCovarianceType { + base: 1.008862586240695e-10, + units: None, + }, + cz_dot_z_dot: common::VelocityCovarianceType { + base: 6.2244443386355e-10, + units: None, + }, + },), + user_defined_parameters: None, + }, + }, + }, + id: None, + version: "3.0".to_string(), + },) + ); + } } diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index a9a02a7e..959cdb6b 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -193,7 +193,7 @@ mod test { use quick_xml::de::from_str; #[test] - fn test_parse_opm_message() { + fn test_parse_opm_message_xml() { let xml = r#" Date: Fri, 7 Jun 2024 14:58:42 +0300 Subject: [PATCH 121/150] Simplify parsing imports --- crates/lox-io/src/ndm/kvn/parser.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index bc32aa45..474a0ff2 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -975,8 +975,6 @@ mod test { ); } - use super::super::KvnDeserializer; - #[derive(Default, Debug, PartialEq)] pub struct PositionUnits(pub std::string::String); @@ -1001,7 +999,7 @@ mod test { ASDFG = 12333.5123"#; assert_eq!( - AsdType::deserialize(&mut kvn.lines().peekable()), + crate::ndm::kvn::KvnDeserializer::deserialize(&mut kvn.lines().peekable()), Ok(AsdType { semi_major_axis: DistanceType { base: 41399.5123, From 78c57e3dbfc6b0d4153c46d73d0bb41361997b17 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 15:38:08 +0300 Subject: [PATCH 122/150] Add doc tests --- crates/lox-io/src/ndm/json/omm.rs | 89 +++++++++++++++++ crates/lox-io/src/ndm/ndm.rs | 156 ++++++++++++++++++++++++++++++ crates/lox-io/src/ndm/ocm.rs | 70 ++++++++++++++ crates/lox-io/src/ndm/oem.rs | 57 +++++++++++ crates/lox-io/src/ndm/omm.rs | 48 +++++++++ crates/lox-io/src/ndm/opm.rs | 98 +++++++++++++++++++ 6 files changed, 518 insertions(+) diff --git a/crates/lox-io/src/ndm/json/omm.rs b/crates/lox-io/src/ndm/json/omm.rs index 6524135c..7961c25f 100644 --- a/crates/lox-io/src/ndm/json/omm.rs +++ b/crates/lox-io/src/ndm/json/omm.rs @@ -11,12 +11,101 @@ //! To deserialize a JSON message: //! //! ``` +//! # use lox_io::ndm::json::omm::OmmType; +//! +//! # let json = r#"{ +//! # "CCSDS_OMM_VERS": "2.0", +//! # "COMMENT": "GENERATED VIA SPACE-TRACK.ORG API", +//! # "CREATION_DATE": "2020-12-29T06:26:10", +//! # "ORIGINATOR": "18 SPCS", +//! # "OBJECT_NAME": "NUSAT-8 (MARIE)", +//! # "OBJECT_ID": "2020-003C", +//! # "CENTER_NAME": "EARTH", +//! # "REF_FRAME": "TEME", +//! # "TIME_SYSTEM": "UTC", +//! # "MEAN_ELEMENT_THEORY": "SGP4", +//! # "EPOCH": "2020-12-29T03:57:59.406624", +//! # "MEAN_MOTION": "15.27989249", +//! # "ECCENTRICITY": "0.00133560", +//! # "INCLINATION": "97.2970", +//! # "RA_OF_ASC_NODE": "66.4161", +//! # "ARG_OF_PERICENTER": "110.6345", +//! # "MEAN_ANOMALY": "334.7107", +//! # "EPHEMERIS_TYPE": "0", +//! # "CLASSIFICATION_TYPE": "U", +//! # "NORAD_CAT_ID": "45018", +//! # "ELEMENT_SET_NO": "999", +//! # "REV_AT_EPOCH": "5327", +//! # "BSTAR": "0.00008455300000", +//! # "MEAN_MOTION_DOT": "0.00002241", +//! # "MEAN_MOTION_DDOT": "0.0000000000000", +//! # "SEMIMAJOR_AXIS": "6859.961", +//! # "PERIOD": "94.242", +//! # "APOAPSIS": "490.988", +//! # "PERIAPSIS": "472.664", +//! # "OBJECT_TYPE": "PAYLOAD", +//! # "RCS_SIZE": "MEDIUM", +//! # "COUNTRY_CODE": "ARGN", +//! # "LAUNCH_DATE": "2020-01-15", +//! # "SITE": "TSC", +//! # "DECAY_DATE": null, +//! # "FILE": "2911831", +//! # "GP_ID": "168552672", +//! # "TLE_LINE0": "0 NUSAT-8 (MARIE)", +//! # "TLE_LINE1": "1 45018U 20003C 20364.16527091 .00002241 00000-0 84553-4 0 9997", +//! # "TLE_LINE2": "2 45018 97.2970 66.4161 0013356 110.6345 334.7107 15.27989249 53274" +//! # }"#; +//! # //! let message: OmmType = serde_json::de::from_str(json).unwrap(); //! ``` //! //! To deserialize a list of JSON messages: //! //! ``` +//! # use lox_io::ndm::json::omm::OmmType; +//! # let json = r#"[{ +//! # "CCSDS_OMM_VERS": "2.0", +//! # "COMMENT": "GENERATED VIA SPACE-TRACK.ORG API", +//! # "CREATION_DATE": "2020-12-29T06:26:10", +//! # "ORIGINATOR": "18 SPCS", +//! # "OBJECT_NAME": "NUSAT-8 (MARIE)", +//! # "OBJECT_ID": "2020-003C", +//! # "CENTER_NAME": "EARTH", +//! # "REF_FRAME": "TEME", +//! # "TIME_SYSTEM": "UTC", +//! # "MEAN_ELEMENT_THEORY": "SGP4", +//! # "EPOCH": "2020-12-29T03:57:59.406624", +//! # "MEAN_MOTION": "15.27989249", +//! # "ECCENTRICITY": "0.00133560", +//! # "INCLINATION": "97.2970", +//! # "RA_OF_ASC_NODE": "66.4161", +//! # "ARG_OF_PERICENTER": "110.6345", +//! # "MEAN_ANOMALY": "334.7107", +//! # "EPHEMERIS_TYPE": "0", +//! # "CLASSIFICATION_TYPE": "U", +//! # "NORAD_CAT_ID": "45018", +//! # "ELEMENT_SET_NO": "999", +//! # "REV_AT_EPOCH": "5327", +//! # "BSTAR": "0.00008455300000", +//! # "MEAN_MOTION_DOT": "0.00002241", +//! # "MEAN_MOTION_DDOT": "0.0000000000000", +//! # "SEMIMAJOR_AXIS": "6859.961", +//! # "PERIOD": "94.242", +//! # "APOAPSIS": "490.988", +//! # "PERIAPSIS": "472.664", +//! # "OBJECT_TYPE": "PAYLOAD", +//! # "RCS_SIZE": "MEDIUM", +//! # "COUNTRY_CODE": "ARGN", +//! # "LAUNCH_DATE": "2020-01-15", +//! # "SITE": "TSC", +//! # "DECAY_DATE": null, +//! # "FILE": "2911831", +//! # "GP_ID": "168552672", +//! # "TLE_LINE0": "0 NUSAT-8 (MARIE)", +//! # "TLE_LINE1": "1 45018U 20003C 20364.16527091 .00002241 00000-0 84553-4 0 9997", +//! # "TLE_LINE2": "2 45018 97.2970 66.4161 0013356 110.6345 334.7107 15.27989249 53274" +//! # }]"#; +//! # //! let message: Vec = serde_json::de::from_str(json).unwrap(); //! ``` diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm.rs index 4906b325..7a887d9d 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm.rs @@ -11,6 +11,162 @@ //! To deserialize an XML message: //! //! ``` +//! # let xml = r#" +//! # bla +//! # asdfg +//! # +//! #
+//! # +//! # +//! #
+//! # +//! # +//! # +//! # +//! #
+//! # +//! #
+//! # 2004-281T17:26:06 +//! # me +//! #
+//! # +//! # +//! # +//! # Cassini +//! # 1997-061A +//! # Saturn +//! # IAU-Saturn +//! # UTC +//! # +//! # +//! # +//! # this is a comment +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # This is a COMMENT +//! # 100 +//! # 2 +//! # 1 +//! # 2 +//! # 2.0 +//! # +//! # +//! # This is a COMMENT +//! # 2004-125T00:00:00 +//! # 0 +//! # -1 +//! # GRC +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # +//! # +//! #
+//! # +//! # +//! # +//! #
+//! # 2004-281T17:26:06 +//! # me +//! #
+//! # +//! # +//! # +//! # Cassini +//! # 1997-061A +//! # Saturn +//! # IAU-Saturn +//! # UTC +//! # 2004-100T00:00:00.000000 +//! # 2004-100T01:00:00.000000 +//! # Hermite +//! # 1 +//! # +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # +//! # +//! #
+//! # +//! #
+//! # +//! # +//! #
+//! # +//! # +//! # +//! # NUSAT-13 (EMMY) +//! # 2020-079G +//! # EARTH +//! # TEME +//! # UTC +//! # SGP4 +//! # +//! # +//! # +//! # 2020-12-04T13:30:01.539648 +//! # 15.31433655 +//! # .0009574 +//! # 97.2663 +//! # 51.2167 +//! # 149.8567 +//! # 322.5146 +//! # +//! # +//! # 0 +//! # U +//! # 46833 +//! # 999 +//! # 434 +//! # .14401E-3 +//! # 4.301E-5 +//! # 0 +//! # +//! # +//! # +//! # +//! #
+//! # +//! #
"#; +//! # +//! # use lox_io::ndm::ndm::NdmType; +//! # //! let message: NdmType = quick_xml::de::from_str(xml).unwrap(); //! ``` diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index f2873b20..96b83c3f 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -11,7 +11,77 @@ //! To deserialize an XML message: //! //! ``` +//! # use lox_io::ndm::ocm::OcmType; //! +//! # let xml = r#" +//! # +//! #
+//! # ODM V.3 Example G-2 +//! # OCM example with space object characteristics and perturbations. +//! # This OCM reflects the latest conditions post-maneuver A67Z +//! # This example shows the specification of multiple comment lines +//! # 1998-11-06T09:23:57 +//! # JAXA +//! # OCM 201113719185 +//! #
+//! # +//! # +//! # +//! # 1998-999A +//! # R. Rabbit +//! # Flight Dynamics Mission Design Lead +//! # (719)555-1234 +//! # Mr. Rodgers +//! # (719)555-1234 +//! # email@email.XXX +//! # UT1 +//! # 1998-12-18T00:00:00.0000 +//! # 36 +//! # .357 +//! # +//! # +//! # +//! # GEOCENTRIC, CARTESIAN, EARTH FIXED +//! # THIS IS MY SECOND COMMENT LINE +//! # PREDICTED +//! # EFG +//! # CARTPVA +//! # 0.0 2854.5 -2916.2 -5360.7 5.90 4.86 0.52 0.0037 -0.0038 -0.0070 +//! # +//! # +//! # Spacecraft Physical Characteristics +//! # 100.0 +//! # 0.03123 +//! # 0.78543 +//! # 0.39158 +//! # 0.47832 +//! # 2.0 +//! # 1.0 +//! # 0.5 +//! # 0.15 +//! # 0.3 +//! # 0.5 +//! # +//! # +//! # Perturbations Specification +//! # NRLMSIS00 +//! # EGM-96: 36D 36O +//! # 398600.4415 +//! # MOON, SUN +//! # 12.0 +//! # 105.0 +//! # 120.0 +//! # +//! # +//! # WGS-84 +//! # +//! # +//! # +//! # +//! #
"#; +//! # //! let message: OcmType = quick_xml::de::from_str(xml).unwrap(); //! ``` diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 5f9e04a8..9a8980ce 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -11,6 +11,63 @@ //! To deserialize an XML message: //! //! ``` +//! # let xml = r#" +//! # +//! # +//! #
+//! # 2004-281T17:26:06 +//! # me +//! #
+//! # +//! # +//! # +//! # Cassini +//! # 1997-061A +//! # Saturn +//! # IAU-Saturn +//! # UTC +//! # 2004-100T00:00:00.000000 +//! # 2004-100T01:00:00.000000 +//! # Hermite +//! # 1 +//! # +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # 2004-100T00:00:00 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # 1 +//! # +//! # +//! # +//! # +//! #
"#; +//! # +//! # use lox_io::ndm::oem::OemType; +//! # //! let message: OemType = quick_xml::de::from_str(xml).unwrap(); //! ``` diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 0ac8127a..01898a37 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -11,6 +11,54 @@ //! To deserialize an XML message: //! //! ``` +//! # let xml = r#" +//! # +//! #
+//! # 2021-03-24T23:00:00.000 +//! # CelesTrak +//! #
+//! # +//! # +//! # +//! # STARLETTE +//! # 1975-010A +//! # EARTH +//! # TEME +//! # UTC +//! # SGP4 +//! # +//! # +//! # +//! # 2008-09-20T12:25:40.104192 +//! # 15.72125391 +//! # 0.0006703 +//! # 51.6416 +//! # 247.4627 +//! # 130.5360 +//! # 325.0288 +//! # 398600.8 +//! # +//! # +//! # 0 +//! # U +//! # 7646 +//! # 999 +//! # 32997 +//! # -.47102E-5 +//! # -.147E-5 +//! # 0 +//! # +//! # +//! # foo enters +//! # a bar +//! # +//! # +//! # +//! # +//! #
"#; +//! # +//! # use lox_io::ndm::omm::OmmType; +//! # //! let message: OmmType = quick_xml::de::from_str(xml).unwrap(); //! ``` diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 959cdb6b..07f34d08 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -11,6 +11,104 @@ //! To deserialize an XML message: //! //! ``` +//! # let xml = r#" +//! # +//! # +//! #
+//! # THIS IS AN XML VERSION OF THE OPM +//! # 2001-11-06T09:23:57 +//! # JAXA +//! # OPM 201113719185 +//! #
+//! # +//! # +//! # +//! # GEOCENTRIC, CARTESIAN, EARTH FIXED +//! # OSPREY 5 +//! # 1998-999A +//! # EARTH +//! # TOD +//! # 1998-12-18T14:28:15.1172 +//! # UTC +//! # +//! # +//! # +//! # 2008-09-20T12:25:40.104192 +//! # 4086.147180 +//! # -994.936814 +//! # 5250.678791 +//! # 2.511071 +//! # 7.255240 +//! # -0.583165 +//! # +//! # +//! # 6730.96 +//! # 0.0006703 +//! # 51.6416 +//! # 247.463 +//! # 130.536 +//! # 324.985 +//! # 398600.9368 +//! # +//! # +//! # 3000.000000 +//! # 18.770000 +//! # 1.000000 +//! # 18.770000 +//! # 2.500000 +//! # +//! # +//! # ITRF1997 +//! # 0.316 +//! # 0.722 +//! # 0.518 +//! # 0.202 +//! # 0.715 +//! # 0.002 +//! # 0.912 +//! # 0.306 +//! # 0.276 +//! # 0.797 +//! # 0.562 +//! # 0.899 +//! # 0.022 +//! # 0.079 +//! # 0.415 +//! # 0.245 +//! # 0.965 +//! # 0.950 +//! # 0.435 +//! # 0.621 +//! # 0.991 +//! # +//! # +//! # Maneuver 1 +//! # 2008-09-20T12:41:09.984493 +//! # 180.000 +//! # -0.001 +//! # RSW +//! # 0.000000 +//! # 0.280000 +//! # 0.000000 +//! # +//! # +//! # 2008-09-20T13:33:11.374985 +//! # 180.000 +//! # -0.001 +//! # RSW +//! # 0.000000 +//! # 0.270000 +//! # 0.000000 +//! # +//! # +//! # +//! # +//! #
"#; +//! # +//! # use lox_io::ndm::opm::OpmType; +//! # //! let message: OpmType = quick_xml::de::from_str(xml).unwrap(); //! ``` From b69c7b56403f1b89e5af9086b6dee063c377a2e0 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 15:42:34 +0300 Subject: [PATCH 123/150] Indicate module is for combined instantiation --- crates/lox-io/src/ndm.rs | 2 +- crates/lox-io/src/ndm/{ndm.rs => ndm_ci.rs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename crates/lox-io/src/ndm/{ndm.rs => ndm_ci.rs} (99%) diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index a042c01e..bbf02a84 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -14,7 +14,7 @@ pub mod json; pub mod kvn; pub mod common; -pub mod ndm; +pub mod ndm_ci; pub mod ocm; pub mod oem; pub mod omm; diff --git a/crates/lox-io/src/ndm/ndm.rs b/crates/lox-io/src/ndm/ndm_ci.rs similarity index 99% rename from crates/lox-io/src/ndm/ndm.rs rename to crates/lox-io/src/ndm/ndm_ci.rs index 7a887d9d..42844205 100644 --- a/crates/lox-io/src/ndm/ndm.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -165,7 +165,7 @@ //! # //! # "#; //! # -//! # use lox_io::ndm::ndm::NdmType; +//! # use lox_io::ndm::ndm_ci::NdmType; //! # //! let message: NdmType = quick_xml::de::from_str(xml).unwrap(); //! ``` From 5614ccc82bc94e90ff43b63cfb80b40081e7ed2e Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 15:47:18 +0300 Subject: [PATCH 124/150] Make list order match the nested match --- crates/lox-derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index ad599236..304eb19b 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -152,7 +152,7 @@ fn generate_call_to_deserializer_for_kvn_type_new( type_name_new: &syn::Path, ) -> Result { match type_name { - "f64" | "String" | "i32" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" => { + "String" | "f64" | "NonNegativeDouble" | "NegativeDouble" | "PositiveDouble" | "i32" => { let parser = match type_name { "String" => { quote! { From 5af75bbb65176d6b2ec610c50de80f48f3073018 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 15:49:26 +0300 Subject: [PATCH 125/150] Remove special case the EpochType --- crates/lox-derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 304eb19b..39d12b07 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -571,7 +571,7 @@ fn deserializer_for_struct_with_named_fields( let field_type_new = extract_type_path(&field.ty).unwrap(); let parser = match field_type.as_str() { - "EpochType" | "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { + "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( &field_type, field_type_new, From e370420b741097ed3f87c892ce087e3f5aad742b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:13:51 +0300 Subject: [PATCH 126/150] Simplify version field handling by reodering --- crates/lox-derive/src/lib.rs | 107 ++++++++++++---------------- crates/lox-io/src/ndm/kvn/parser.rs | 2 +- crates/lox-io/src/ndm/omm.rs | 8 +-- crates/lox-io/src/ndm/opm.rs | 8 +-- 4 files changed, 56 insertions(+), 69 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 39d12b07..f1aab125 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -380,6 +380,49 @@ fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> { } } +fn handle_version_field( + type_name: &proc_macro2::Ident, + field: &syn::Field, +) -> Result { + let string_type_name = type_name.to_string(); + + if !string_type_name.ends_with("Type") { + return Err(syn::Error::new_spanned( + type_name, + "Types with \"version\" field should be of the form SomethingType", + ) + .into_compile_error()); + } + + let message_type_name = string_type_name + .trim_end_matches("Type") + .to_owned() + .to_uppercase(); + + let field_name = field.ident.as_ref().unwrap(); + + // 7.4.4 Keywords must be uppercase and must not contain blanks + let expected_kvn_name = format!("CCSDS_{}_VERS", message_type_name); + + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); + + let parser = generate_call_to_deserializer_for_kvn_type( + &field_type, + field_type_new, + &expected_kvn_name, + )?; + + Ok(quote! { + #field_name: #parser?, + }) +} + fn deserializer_for_struct_with_named_fields( type_name: &proc_macro2::Ident, fields: &syn::punctuated::Punctuated, @@ -498,67 +541,8 @@ fn deserializer_for_struct_with_named_fields( }, } } else { - let version_field_deserializers: Result, _> = fields - .iter() - .filter(|field| { - let field_name = field.ident.as_ref().unwrap(); - - field_name == "version" - }) - .map(|field| { - let string_type_name = type_name.to_string(); - - if !string_type_name.ends_with("Type") { - return Err(syn::Error::new_spanned( - fields, - "Types with \"version\" field should be of the form SomethingType", - ) - .into_compile_error()); - } - - let message_type_name = string_type_name - .trim_end_matches("Type") - .to_owned() - .to_uppercase(); - - let field_name = field.ident.as_ref().unwrap(); - - // 7.4.4 Keywords must be uppercase and must not contain blanks - let expected_kvn_name = format!("CCSDS_{}_VERS", message_type_name); - - // Unwrap is okay because we expect this span to come from the source code - let field_type = extract_type_path(&field.ty) - .unwrap() - .span() - .source_text() - .unwrap(); - let field_type_new = extract_type_path(&field.ty).unwrap(); - - let parser = generate_call_to_deserializer_for_kvn_type( - &field_type, - field_type_new, - &expected_kvn_name, - )?; - - Ok(quote! { - #field_name: #parser?, - }) - }) - .collect(); - - if let Err(e) = version_field_deserializers { - return e; - } - - let version_field_deserializers = version_field_deserializers.unwrap(); - let other_field_deserializers: Result, _> = fields .iter() - .filter(|field| { - let field_name = field.ident.as_ref().unwrap(); - - field_name != "version" - }) .map(|field| { let field_name = field.ident.as_ref().unwrap(); @@ -570,6 +554,10 @@ fn deserializer_for_struct_with_named_fields( let field_type = extract_type_path(&field.ty).unwrap().span().source_text().unwrap(); let field_type_new = extract_type_path(&field.ty).unwrap(); + if field_name == "version" { + return handle_version_field(type_name, field); + } + let parser = match field_type.as_str() { "KvnStringValue" | "KvnNumericValue" | "KvnIntegerValue" | "String" | "f64" | "i32" => { let deserializer_for_kvn_type = generate_call_to_deserializer_for_kvn_type( @@ -632,7 +620,6 @@ fn deserializer_for_struct_with_named_fields( quote! { Ok(#type_name { - #(#version_field_deserializers)* #(#other_field_deserializers)* }) } diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index 474a0ff2..9e240f23 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -987,9 +987,9 @@ mod test { #[derive(KvnDeserialize, Default, Debug, PartialEq)] struct AsdType { + pub version: String, pub semi_major_axis: DistanceType, pub asdfg: f64, - pub version: String, } #[test] diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 01898a37..501f2c57 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -173,15 +173,15 @@ pub struct SpacewarnType(#[serde(rename = "$text")] pub String); )] #[serde(default)] pub struct OmmType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OmmBody, #[serde(rename = "@id")] // Marked as option for the KVN deserializer pub id: Option, #[serde(rename = "@version")] pub version: String, + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OmmBody, } #[derive( diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 07f34d08..0da59ae1 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -127,15 +127,15 @@ use super::common; )] #[serde(default)] pub struct OpmType { - #[serde(rename = "header")] - pub header: common::OdmHeader, - #[serde(rename = "body")] - pub body: OpmBody, #[serde(rename = "@id")] // Marked as option for the KVN deserializer pub id: Option, #[serde(rename = "@version")] pub version: String, + #[serde(rename = "header")] + pub header: common::OdmHeader, + #[serde(rename = "body")] + pub body: OpmBody, } #[derive( From a8cb41b00b0770386d841ab5d4bba72fc7391a90 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:14:22 +0300 Subject: [PATCH 127/150] Add whitespace to fix false positives --- crates/lox-io/src/ndm/kvn/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index 9e240f23..c84ac426 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -183,7 +183,7 @@ pub fn kvn_line_matches_key_new<'a>( pub fn parse_kvn_string_line_new( input: &str, ) -> nom::IResult<&str, KvnValue, KvnStringParserErr<&str>> { - if input.trim_start().starts_with("COMMENT") { + if input.trim_start().starts_with("COMMENT ") { return Ok(( "", KvnValue { From 4ff7581032764f4ee14dca28f5246e074a479ce4 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:23:57 +0300 Subject: [PATCH 128/150] Simplify unamed fields handling --- crates/lox-derive/src/lib.rs | 43 ++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index f1aab125..3b781b16 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -630,36 +630,31 @@ fn deserializers_for_struct_with_unnamed_fields( type_name: &proc_macro2::Ident, fields: &syn::punctuated::Punctuated, ) -> proc_macro2::TokenStream { - let field_deserializers: Result, _> = fields - .iter() - .enumerate() - .map(|(_, field)| { - // Unwrap is okay because we expect this span to come from the source code - let field_type = extract_type_path(&field.ty) - .unwrap() - .span() - .source_text() - .unwrap(); - let field_type_new = extract_type_path(&field.ty).unwrap(); - - let deserializer_for_kvn_type = - generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new)?; + let field = fields + .first() + .expect("We expect exactly one item in structs with unnamed fields"); - Ok(quote! { - #deserializer_for_kvn_type.value, - }) - }) - .collect(); + // Unwrap is okay because we expect this span to come from the source code + let field_type = extract_type_path(&field.ty) + .unwrap() + .span() + .source_text() + .unwrap(); + let field_type_new = extract_type_path(&field.ty).unwrap(); - if let Err(e) = field_deserializers { - return e; - } + let deserializer_for_kvn_type = + generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new); - let field_deserializers = field_deserializers.unwrap(); + let deserializer_for_kvn_type = match deserializer_for_kvn_type { + Ok(deserializer_for_kvn_type) => quote! { + #deserializer_for_kvn_type.value, + }, + Err(e) => return e.into(), + }; quote! { Ok(#type_name ( - #(#field_deserializers)* + #deserializer_for_kvn_type )) } } From ecc266924bf1c6541e8f4bacba3d331afada97e6 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:33:42 +0300 Subject: [PATCH 129/150] Fix usage of date time parser --- crates/lox-derive/src/lib.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 3b781b16..c62df098 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -634,6 +634,17 @@ fn deserializers_for_struct_with_unnamed_fields( .first() .expect("We expect exactly one item in structs with unnamed fields"); + if &type_name.to_string() == "EpochType" { + return quote! { + Ok(#type_name ( + crate::ndm::kvn::parser::parse_kvn_datetime_line_new( + lines.next().unwrap() + ).map_err(|x| crate::ndm::kvn::KvnDeserializerErr::from(x)) + .map(|x| x.1)?.full_value + )) + }; + } + // Unwrap is okay because we expect this span to come from the source code let field_type = extract_type_path(&field.ty) .unwrap() @@ -646,15 +657,13 @@ fn deserializers_for_struct_with_unnamed_fields( generate_call_to_deserializer_for_kvn_type_new(&field_type, field_type_new); let deserializer_for_kvn_type = match deserializer_for_kvn_type { - Ok(deserializer_for_kvn_type) => quote! { - #deserializer_for_kvn_type.value, - }, + Ok(deserializer_for_kvn_type) => deserializer_for_kvn_type, Err(e) => return e.into(), }; quote! { Ok(#type_name ( - #deserializer_for_kvn_type + #deserializer_for_kvn_type.value )) } } From ec9c80611a810f3f083da8cfcc57e7fe1dfe25c0 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:44:57 +0300 Subject: [PATCH 130/150] Change date format We don't support ddd format yet --- crates/lox-io/src/ndm/omm.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 501f2c57..9ea9911e 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -1490,18 +1490,18 @@ mod test { let kvn = r#"CCSDS_OMM_VERS = 3.0 COMMENT this is a comment COMMENT here is another one - CREATION_DATE = 2007-065T16:00:00 + CREATION_DATE = 2007-06-05T16:00:00 ORIGINATOR = NOAA/USA COMMENT this comment doesn't say much OBJECT_NAME = GOES 9 OBJECT_ID = 1995-025A CENTER_NAME = EARTH REF_FRAME = TOD - REF_FRAME_EPOCH = 2000-003T10:34:00 + REF_FRAME_EPOCH = 2000-01-03T10:34:00 TIME_SYSTEM = MRT MEAN_ELEMENT_THEORY = SOME THEORY COMMENT the following data is what we're looking for - EPOCH = 2000-005T10:00:00 + EPOCH = 2000-01-05T10:00:00 SEMI_MAJOR_AXIS = 6800 ECCENTRICITY = 0.0005013 INCLINATION = 3.0539 @@ -1547,7 +1547,7 @@ mod test { "here is another one".to_string(), ], classification_list: vec![], - creation_date: common::EpochType("2007-065T16:00:00".to_string(),), + creation_date: common::EpochType("2007-06-05T16:00:00".to_string(),), originator: "NOAA/USA".to_string(), message_id: None, }, @@ -1560,7 +1560,7 @@ mod test { center_name: "EARTH".to_string(), ref_frame: "TOD".to_string(), ref_frame_epoch: Some(common::EpochType( - "2000-003T10:34:00".to_string(), + "2000-01-03T10:34:00".to_string(), ),), time_system: "MRT".to_string(), mean_element_theory: "SOME THEORY".to_string(), @@ -1571,7 +1571,7 @@ mod test { ], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType("2000-005T10:00:00".to_string(),), + epoch: common::EpochType("2000-01-05T10:00:00".to_string(),), semi_major_axis: Some(common::DistanceType { base: 6800.0, units: None, From 9dfe3b2e799dcffa87b492a62068913410bc5eea Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 16:51:12 +0300 Subject: [PATCH 131/150] Document KVN parsers --- crates/lox-io/src/ndm/omm.rs | 59 +++++++++++++++++++++++++++++++++++ crates/lox-io/src/ndm/opm.rs | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 9ea9911e..82892a73 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -61,6 +61,65 @@ //! # //! let message: OmmType = quick_xml::de::from_str(xml).unwrap(); //! ``` +//! +//! To deserialize a KVN message: +//! ``` +//! # let kvn = r#"CCSDS_OMM_VERS = 3.0 +//! # COMMENT this is a comment +//! # COMMENT here is another one +//! # CREATION_DATE = 2007-06-05T16:00:00 +//! # ORIGINATOR = NOAA/USA +//! # COMMENT this comment doesn't say much +//! # OBJECT_NAME = GOES 9 +//! # OBJECT_ID = 1995-025A +//! # CENTER_NAME = EARTH +//! # REF_FRAME = TOD +//! # REF_FRAME_EPOCH = 2000-01-03T10:34:00 +//! # TIME_SYSTEM = MRT +//! # MEAN_ELEMENT_THEORY = SOME THEORY +//! # COMMENT the following data is what we're looking for +//! # EPOCH = 2000-01-05T10:00:00 +//! # SEMI_MAJOR_AXIS = 6800 +//! # ECCENTRICITY = 0.0005013 +//! # INCLINATION = 3.0539 +//! # RA_OF_ASC_NODE = 81.7939 +//! # ARG_OF_PERICENTER = 249.2363 +//! # MEAN_ANOMALY = 150.1602 +//! # COMMENT spacecraft data +//! # MASS = 300 +//! # SOLAR_RAD_AREA = 5 +//! # SOLAR_RAD_COEFF = 0.001 +//! # DRAG_AREA = 4 +//! # DRAG_COEFF = 0.002 +//! # COMMENT Covariance matrix +//! # COV_REF_FRAME = TNW +//! # CX_X = 3.331349476038534e-04 +//! # CY_X = 4.618927349220216e-04 +//! # CY_Y = 6.782421679971363e-04 +//! # CZ_X = -3.070007847730449e-04 +//! # CZ_Y = -4.221234189514228e-04 +//! # CZ_Z = 3.231931992380369e-04 +//! # CX_DOT_X = -3.349365033922630e-07 +//! # CX_DOT_Y = -4.686084221046758e-07 +//! # CX_DOT_Z = 2.484949578400095e-07 +//! # CX_DOT_X_DOT = 4.296022805587290e-10 +//! # CY_DOT_X = -2.211832501084875e-07 +//! # CY_DOT_Y = -2.864186892102733e-07 +//! # CY_DOT_Z = 1.798098699846038e-07 +//! # CY_DOT_X_DOT = 2.608899201686016e-10 +//! # CY_DOT_Y_DOT = 1.767514756338532e-10 +//! # CZ_DOT_X = -3.041346050686871e-07 +//! # CZ_DOT_Y = -4.989496988610662e-07 +//! # CZ_DOT_Z = 3.540310904497689e-07 +//! # CZ_DOT_X_DOT = 1.869263192954590e-10 +//! # CZ_DOT_Y_DOT = 1.008862586240695e-10 +//! # CZ_DOT_Z_DOT = 6.224444338635500e-10"#; +//! # +//! # use lox_io::ndm::kvn::KvnDeserializer; +//! # use lox_io::ndm::omm::OmmType; +//! # +//! let message: OmmType = KvnDeserializer::deserialize(&mut kvn.lines().peekable()).unwrap(); +//! ``` use serde; diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 0da59ae1..c3b65c7e 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -111,6 +111,66 @@ //! # //! let message: OpmType = quick_xml::de::from_str(xml).unwrap(); //! ``` +//! +//! To deserialize a KVN message: +//! ``` +//! # let kvn = r#"CCSDS_OPM_VERS = 3.0 +//! # COMMENT Generated by GSOC, R. Kiehling +//! # COMMENT Current intermediate orbit IO2 and maneuver planning data +//! # CREATION_DATE = 2021-06-03T05:33:00.123 +//! # ORIGINATOR = GSOC +//! # OBJECT_NAME = EUTELSAT W4 +//! # OBJECT_ID = 2021-028A +//! # CENTER_NAME = EARTH +//! # REF_FRAME = TOD +//! # TIME_SYSTEM = UTC +//! # COMMENT State Vector +//! # EPOCH = 2021-06-03T00:00:00.000 +//! # X = 6655.9942 [km] +//! # Y = -40218.5751 [km] +//! # Z = -82.9177 [km] +//! # X_DOT = 3.11548208 [km/s] +//! # Y_DOT = 0.47042605 [km/s] +//! # Z_DOT = -0.00101495 [km/s] +//! # COMMENT Keplerian elements +//! # SEMI_MAJOR_AXIS = 41399.5123 [km] +//! # ECCENTRICITY = 0.020842611 +//! # INCLINATION = 0.117746 [deg] +//! # RA_OF_ASC_NODE = 17.604721 [deg] +//! # ARG_OF_PERICENTER = 218.242943 [deg] +//! # TRUE_ANOMALY = 41.922339 [deg] +//! # GM = 398600.4415 [km**3/s**2] +//! # COMMENT Spacecraft parameters +//! # MASS = 1913.000 [kg] +//! # SOLAR_RAD_AREA = 10.000 [m**2] +//! # SOLAR_RAD_COEFF = 1.300 +//! # DRAG_AREA = 10.000 [m**2] +//! # DRAG_COEFF = 2.300 +//! # COMMENT 2 planned maneuvers +//! # COMMENT First maneuver: AMF-3 +//! # COMMENT Non-impulsive, thrust direction fixed in inertial frame +//! # MAN_EPOCH_IGNITION = 2021-06-03T09:00:34.1 +//! # MAN_DURATION = 132.60 [s] +//! # MAN_DELTA_MASS = -18.418 [kg] +//! # MAN_REF_FRAME = EME2000 +//! # MAN_DV_1 = -0.02325700 [km/s] +//! # MAN_DV_2 = 0.01683160 [km/s] +//! # MAN_DV_3 = -0.00893444 [km/s] +//! # COMMENT Second maneuver: first station acquisition maneuver +//! # COMMENT impulsive, thrust direction fixed in RTN frame +//! # MAN_EPOCH_IGNITION = 2021-06-05T18:59:21.0 +//! # MAN_DURATION = 0.00 [s] +//! # MAN_DELTA_MASS = -1.469 [kg] +//! # MAN_REF_FRAME = RTN +//! # MAN_DV_1 = 0.00101500 [km/s] +//! # MAN_DV_2 = -0.00187300 [km/s] +//! # MAN_DV_3 = 0.00000000 [km/s]"#; +//! # +//! # use lox_io::ndm::kvn::KvnDeserializer; +//! # use lox_io::ndm::opm::OpmType; +//! # +//! let message: OpmType = KvnDeserializer::deserialize(&mut kvn.lines().peekable()).unwrap(); +//! ``` use serde; From b27b60042010956b3d48375bac2be91591487a87 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 17:13:07 +0300 Subject: [PATCH 132/150] Document relaxations and limitations --- crates/lox-io/src/ndm.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index bbf02a84..fea448c8 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -8,6 +8,29 @@ //! Since Rust XML and JSON deserializers are slightly incompatible, the JSON //! deserializer is separate. //! +//! Because there a signficant number of messages out there that do not +//! strictly comply with the specification, the parsers are relaxed in terms of +//! input that they accept. Some relaxations: +//! +//! - The KVN floating point numbers defined in the specification can have only +//! one character in the integer part of the number, but we accept any regular +//! float number. +//! - The KVN strings are defined in the specification as being either only +//! lower-case or only upper-case, but we accept any combination of cases. +//! +//! The XML deserializer does not perform any validation on the schema types +//! defined (e.g. non-positive double, lat-long, angle). The validation only +//! checks if the data can be parsed into the fundamental Rust data types +//! (e.g. f64, u64). +//! +//! The KVN parsing is implemented with a finite-state parser. As such, it is +//! eager and has no backtracking. This is normally okay. But the KVN grammar +//! is ambiguous with regards to its `COMMENT` fields, so in some corner-cases +//! it can lead to some `COMMENT` lines being discarded. This happens when an +//! optional section is ommitted. For example, an OPM message can have an empty +//! covariance matrix section. But this will cause the comments for the +//! following section, the maneuver parameters list, to be discarded. +//! //! Check the respective submodules for more information. pub mod json; From 6f5a9633d996179fb7b05a85035d204190168220 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 7 Jun 2024 17:13:17 +0300 Subject: [PATCH 133/150] Hide doctest line --- crates/lox-io/src/ndm/ocm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index 96b83c3f..3107a263 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -12,7 +12,7 @@ //! //! ``` //! # use lox_io::ndm::ocm::OcmType; -//! +//! # //! # let xml = r#" //! # Date: Sun, 9 Jun 2024 16:06:39 +0300 Subject: [PATCH 134/150] Remove unused types --- crates/lox-io/src/ndm/common.rs | 563 -------------------------------- 1 file changed, 563 deletions(-) diff --git a/crates/lox-io/src/ndm/common.rs b/crates/lox-io/src/ndm/common.rs index 9363fb4f..9d05fcd5 100644 --- a/crates/lox-io/src/ndm/common.rs +++ b/crates/lox-io/src/ndm/common.rs @@ -22,14 +22,6 @@ pub struct AngleUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct AngleRateUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngMomentumUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngVelFrameType(#[serde(rename = "$text")] pub f64); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct AreaUnits(#[serde(rename = "$text")] pub String); @@ -46,10 +38,6 @@ pub struct AreaUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct DayIntervalUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct FrequencyUnits(#[serde(rename = "$text")] pub String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct GmUnits(#[serde(rename = "$text")] pub String); @@ -98,22 +86,6 @@ pub struct WkgUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct ObjectDescriptionType(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Ms2Units(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2Units(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2sUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Km2s2Units(#[serde(rename = "$text")] pub String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct PositionUnits(#[serde(rename = "$text")] pub String); @@ -122,11 +94,6 @@ pub struct PositionUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct VelocityUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq)] -pub struct VecDouble { - pub items: Vec, -} - #[derive( Clone, Debug, @@ -139,14 +106,6 @@ pub struct VecDouble { #[serde(default)] pub struct Vec3Double(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Vec6Double(#[serde(rename = "$text")] pub f64); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Vec9Double(#[serde(rename = "$text")] pub f64); - #[derive( Clone, Debug, @@ -171,10 +130,6 @@ pub struct EpochType(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct TimeUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TimeSystemType(#[serde(rename = "$text")] pub String); - #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); @@ -191,14 +146,6 @@ pub struct NegativeDouble(#[serde(rename = "$text")] pub f64); #[serde(default)] pub struct NonNegativeDouble(#[serde(rename = "$text")] pub f64); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NonPositiveDouble(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct PercentType(#[serde(rename = "$text")] pub String); - #[derive( Clone, Debug, @@ -247,10 +194,6 @@ pub struct ProbabilityType(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct PercentageUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct YesNoType(#[serde(rename = "$text")] pub String); - #[derive( Clone, Debug, @@ -383,98 +326,6 @@ pub struct VelocityCovarianceUnits(#[serde(rename = "$text")] pub String); #[serde(default)] pub struct PositionVelocityCovarianceUnits(#[serde(rename = "$text")] pub String); -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct BallisticCoeffUnitsType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AltRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LonRange(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatLonUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ControlledType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct DisintegrationType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ImpactUncertaintyType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ReentryUncertaintyMethodType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionComponentType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionDotUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotDirectionType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotseqType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleKeywordType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngleRateKeywordType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct ApmRateFrameType(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TorqueUnits(#[serde(rename = "$text")] pub String); - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct NdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AdmHeader { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "CREATION_DATE")] - pub creation_date: EpochType, - #[serde(rename = "ORIGINATOR")] - pub originator: String, - #[serde(rename = "MESSAGE_ID")] - pub message_id: Option, -} - #[derive( Clone, Debug, @@ -552,71 +403,6 @@ pub struct AngleRateType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngMomentumType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: AngMomentumUnits, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct AngVelComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AngVelStateType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "REF_FRAME_A")] - pub ref_frame_a: String, - #[serde(rename = "REF_FRAME_B")] - pub ref_frame_b: String, - #[serde(rename = "ANGVEL_FRAME")] - pub angvel_frame: AngVelFrameType, - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -pub struct AngVelType { - #[serde(rename = "ANGVEL_X")] - pub angvel_x: AngVelComponentType, - #[serde(rename = "ANGVEL_Y")] - pub angvel_y: AngVelComponentType, - #[serde(rename = "ANGVEL_Z")] - pub angvel_z: AngVelComponentType, -} - #[derive( Clone, Debug, @@ -679,24 +465,6 @@ pub struct DeltamassType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct DeltamassTypeZ { - #[serde(rename = "$text")] - pub base: NonPositiveDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct FrequencyType { - #[serde(rename = "$text")] - pub base: PositiveDouble, - #[serde(rename = "@units")] - pub units: Option, -} - #[derive( Clone, Debug, @@ -918,69 +686,6 @@ pub struct StateVectorAccType { pub z_ddot: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct Ms2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Ms2Units, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2sType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive( - Clone, - Debug, - Default, - PartialEq, - serde::Deserialize, - serde::Serialize, - lox_derive::KvnDeserialize, -)] -#[serde(default)] -#[kvn(value_unit_struct)] -pub struct Km2s2Type { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - #[derive( Clone, Debug, @@ -1017,13 +722,6 @@ pub struct PositionType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmPositionType { - #[serde(rename = "$text")] - pub base: String, -} - #[derive( Clone, Debug, @@ -1042,13 +740,6 @@ pub struct VelocityType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmVelocityType { - #[serde(rename = "$text")] - pub base: String, -} - #[derive( Clone, Debug, @@ -1067,15 +758,6 @@ pub struct DurationType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RelTimeType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - #[derive( Clone, Debug, @@ -1344,159 +1026,6 @@ pub struct PositionVelocityCovarianceType { pub units: Option, } -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AtmosphericReentryParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "ORBIT_LIFETIME")] - pub orbit_lifetime: DayIntervalType, - #[serde(rename = "REENTRY_ALTITUDE")] - pub reentry_altitude: PositionType, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_START")] - pub orbit_lifetime_window_start: Option, - #[serde(rename = "ORBIT_LIFETIME_WINDOW_END")] - pub orbit_lifetime_window_end: Option, - #[serde(rename = "NOMINAL_REENTRY_EPOCH")] - pub nominal_reentry_epoch: Option, - #[serde(rename = "REENTRY_WINDOW_START")] - pub reentry_window_start: Option, - #[serde(rename = "REENTRY_WINDOW_END")] - pub reentry_window_end: Option, - #[serde(rename = "ORBIT_LIFETIME_CONFIDENCE_LEVEL")] - pub orbit_lifetime_confidence_level: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct GroundImpactParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "PROBABILITY_OF_IMPACT")] - pub probability_of_impact: Option, - #[serde(rename = "PROBABILITY_OF_BURN_UP")] - pub probability_of_burn_up: Option, - #[serde(rename = "PROBABILITY_OF_BREAK_UP")] - pub probability_of_break_up: Option, - #[serde(rename = "PROBABILITY_OF_LAND_IMPACT")] - pub probability_of_land_impact: Option, - #[serde(rename = "PROBABILITY_OF_CASUALTY")] - pub probability_of_casualty: Option, - #[serde(rename = "NOMINAL_IMPACT_EPOCH")] - pub nominal_impact_epoch: Option, - #[serde(rename = "IMPACT_WINDOW_START")] - pub impact_window_start: Option, - #[serde(rename = "IMPACT_WINDOW_END")] - pub impact_window_end: Option, - #[serde(rename = "IMPACT_REF_FRAME")] - pub impact_ref_frame: Option, - #[serde(rename = "NOMINAL_IMPACT_LON")] - pub nominal_impact_lon: Option, - #[serde(rename = "NOMINAL_IMPACT_LAT")] - pub nominal_impact_lat: Option, - #[serde(rename = "NOMINAL_IMPACT_ALT")] - pub nominal_impact_alt: Option, - #[serde(rename = "IMPACT_1_CONFIDENCE")] - pub impact_1_confidence: Option, - #[serde(rename = "IMPACT_1_START_LON")] - pub impact_1_start_lon: Option, - #[serde(rename = "IMPACT_1_START_LAT")] - pub impact_1_start_lat: Option, - #[serde(rename = "IMPACT_1_STOP_LON")] - pub impact_1_stop_lon: Option, - #[serde(rename = "IMPACT_1_STOP_LAT")] - pub impact_1_stop_lat: Option, - #[serde(rename = "IMPACT_1_CROSS_TRACK")] - pub impact_1_cross_track: Option, - #[serde(rename = "IMPACT_2_CONFIDENCE")] - pub impact_2_confidence: Option, - #[serde(rename = "IMPACT_2_START_LON")] - pub impact_2_start_lon: Option, - #[serde(rename = "IMPACT_2_START_LAT")] - pub impact_2_start_lat: Option, - #[serde(rename = "IMPACT_2_STOP_LON")] - pub impact_2_stop_lon: Option, - #[serde(rename = "IMPACT_2_STOP_LAT")] - pub impact_2_stop_lat: Option, - #[serde(rename = "IMPACT_2_CROSS_TRACK")] - pub impact_2_cross_track: Option, - #[serde(rename = "IMPACT_3_CONFIDENCE")] - pub impact_3_confidence: Option, - #[serde(rename = "IMPACT_3_START_LON")] - pub impact_3_start_lon: Option, - #[serde(rename = "IMPACT_3_START_LAT")] - pub impact_3_start_lat: Option, - #[serde(rename = "IMPACT_3_STOP_LON")] - pub impact_3_stop_lon: Option, - #[serde(rename = "IMPACT_3_STOP_LAT")] - pub impact_3_stop_lat: Option, - #[serde(rename = "IMPACT_3_CROSS_TRACK")] - pub impact_3_cross_track: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RdmSpacecraftParametersType { - #[serde(rename = "COMMENT")] - pub comment_list: Vec, - #[serde(rename = "WET_MASS")] - pub wet_mass: Option, - #[serde(rename = "DRY_MASS")] - pub dry_mass: Option, - #[serde(rename = "HAZARDOUS_SUBSTANCES")] - pub hazardous_substances: Option, - #[serde(rename = "SOLAR_RAD_AREA")] - pub solar_rad_area: Option, - #[serde(rename = "SOLAR_RAD_COEFF")] - pub solar_rad_coeff: Option, - #[serde(rename = "DRAG_AREA")] - pub drag_area: Option, - #[serde(rename = "DRAG_COEFF")] - pub drag_coeff: Option, - #[serde(rename = "RCS")] - pub rcs: Option, - #[serde(rename = "BALLISTIC_COEFF")] - pub ballistic_coeff: Option, - #[serde(rename = "THRUST_ACCELERATION")] - pub thrust_acceleration: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct AltType { - #[serde(rename = "$text")] - pub base: AltRange, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct BallisticCoeffType { - #[serde(rename = "$text")] - pub base: NonNegativeDouble, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LatType { - #[serde(rename = "$text")] - pub base: LatRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct LonType { - #[serde(rename = "$text")] - pub base: LonRange, - #[serde(rename = "@units")] - pub units: LatLonUnits, -} - #[derive( Clone, Debug, @@ -1530,95 +1059,3 @@ pub struct UserDefinedParameterType { #[serde(rename = "@parameter")] pub parameter: String, } - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionType {} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionRateType {} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct QuaternionDotType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleType { - #[serde(rename = "rotation1")] - pub rotation1: RotationAngleComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationAngleComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationAngleComponentType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleComponentTypeold { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@value")] - pub value: f64, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationAngleComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@angle")] - pub angle: AngleKeywordType, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateType { - #[serde(rename = "rotation1")] - pub rotation1: RotationRateComponentType, - #[serde(rename = "rotation2")] - pub rotation2: RotationRateComponentType, - #[serde(rename = "rotation3")] - pub rotation3: RotationRateComponentType, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateComponentTypeOld { - #[serde(rename = "@units")] - pub units: Option, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@value")] - pub value: f64, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct RotationRateComponentType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@rate")] - pub rate: AngleRateKeywordType, - #[serde(rename = "@units")] - pub units: Option, -} - -#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] -#[serde(default)] -pub struct TorqueType { - #[serde(rename = "$text")] - pub base: f64, - #[serde(rename = "@units")] - pub units: Option, -} From 1f34726d8384d01b52a23e581abbf14f9f922d3b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:30:59 +0300 Subject: [PATCH 135/150] Make error payload an owned string --- crates/lox-derive/src/lib.rs | 42 ++++++------ crates/lox-io/src/ndm/kvn/deserializer.rs | 2 +- crates/lox-io/src/ndm/kvn/parser.rs | 82 ++++++++++++++--------- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index c62df098..b72de7ce 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -44,8 +44,8 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(quote! { match lines.peek() { - None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name + None => Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedEndOfInput { + keyword: #expected_kvn_name.to_string() }), Some(next_line) => { let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( @@ -58,9 +58,9 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(#parser.value) } else { - Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, + Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedKeyword { + found: next_line.to_string(), + expected: #expected_kvn_name.to_string(), }) }; @@ -102,8 +102,8 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(quote! { match lines.peek() { - None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name + None => Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedEndOfInput { + keyword: #expected_kvn_name.to_string() }), Some(next_line) => { let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( @@ -116,9 +116,9 @@ fn generate_call_to_deserializer_for_kvn_type( Ok(#parser) } else { - Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, + Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedKeyword { + found: next_line.to_string(), + expected: #expected_kvn_name.to_string(), }) }; @@ -135,8 +135,8 @@ fn generate_call_to_deserializer_for_kvn_type( let result = if has_next_line { #type_name_new::deserialize(lines) } else { - Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: #expected_kvn_name + Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedEndOfInput { + keyword: #expected_kvn_name.to_string() }) }; @@ -190,8 +190,8 @@ fn generate_call_to_deserializer_for_kvn_type_new( let result = if has_next_line { #type_name_new::deserialize(lines) } else { - Err(crate::ndm::kvn::KvnDeserializerErr::UnexpectedEndOfInput { - keyword: "Blala" //@TODO + Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedEndOfInput { + keyword: "Blala"to_string() //@TODO }) }; @@ -396,7 +396,7 @@ fn handle_version_field( let message_type_name = string_type_name .trim_end_matches("Type") - .to_owned() + .to_string() .to_uppercase(); let field_name = field.ident.as_ref().unwrap(); @@ -583,8 +583,8 @@ fn deserializer_for_struct_with_named_fields( quote! { match lines.peek() { - None => Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedEndOfInput { - keyword: #expected_kvn_name + None => Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedEndOfInput { + keyword: #expected_kvn_name.to_string() })?, Some(next_line) => { let line_matches = crate::ndm::kvn::parser::kvn_line_matches_key_new( @@ -595,9 +595,9 @@ fn deserializer_for_struct_with_named_fields( if #condition_shortcut line_matches { #field_type_new::deserialize(lines)? } else { - Err(crate::ndm::kvn::KvnDeserializerErr::<&str>::UnexpectedKeyword { - found: next_line, - expected: #expected_kvn_name, + Err(crate::ndm::kvn::KvnDeserializerErr::::UnexpectedKeyword { + found: next_line.to_string(), + expected: #expected_kvn_name.to_string(), })? } } @@ -709,7 +709,7 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke #where_clause { fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) - -> Result<#type_name, crate::ndm::kvn::KvnDeserializerErr<&'a str>> { + -> Result<#type_name, crate::ndm::kvn::KvnDeserializerErr> { #struct_deserializer } diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs index 4eda0f8e..0a036272 100644 --- a/crates/lox-io/src/ndm/kvn/deserializer.rs +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -11,7 +11,7 @@ use nom::error::ErrorKind; pub trait KvnDeserializer { fn deserialize<'a>( lines: &mut std::iter::Peekable>, - ) -> Result> + ) -> Result> where Self: Sized; diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index c84ac426..a5cd3712 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -45,24 +45,30 @@ pub enum KvnDateTimeParserErr { InvalidFormat { input: I }, } -impl From>> for KvnDeserializerErr { - fn from(value: nom::Err>) -> Self { +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { match value { nom::Err::Error(KvnStringParserErr::EmptyValue { input }) | nom::Err::Failure(KvnStringParserErr::EmptyValue { input }) => { - KvnDeserializerErr::EmptyValue { input } + KvnDeserializerErr::EmptyValue { + input: input.to_string(), + } } nom::Err::Error(KvnStringParserErr::EmptyKeyword { input }) | nom::Err::Failure(KvnStringParserErr::EmptyKeyword { input }) => { - KvnDeserializerErr::EmptyKeyword { input } + KvnDeserializerErr::EmptyKeyword { + input: input.to_string(), + } } nom::Err::Error(KvnStringParserErr::InvalidFormat { input }) | nom::Err::Failure(KvnStringParserErr::InvalidFormat { input }) => { - KvnDeserializerErr::InvalidStringFormat { input } + KvnDeserializerErr::InvalidStringFormat { + input: input.to_string(), + } } nom::Err::Error(KvnStringParserErr::ParserError(i, k)) | nom::Err::Failure(KvnStringParserErr::ParserError(i, k)) => { - KvnDeserializerErr::GeneralParserError(i, k) + KvnDeserializerErr::GeneralParserError(i.to_string(), k) } // We don't use streaming deserialization nom::Err::Incomplete(_) => unimplemented!(), @@ -70,24 +76,30 @@ impl From>> for KvnDeserializerErr { } } -impl From>> for KvnDeserializerErr { - fn from(value: nom::Err>) -> Self { +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { match value { nom::Err::Error(KvnDateTimeParserErr::EmptyValue { input }) | nom::Err::Failure(KvnDateTimeParserErr::EmptyValue { input }) => { - KvnDeserializerErr::EmptyValue { input } + KvnDeserializerErr::EmptyValue { + input: input.to_string(), + } } nom::Err::Error(KvnDateTimeParserErr::EmptyKeyword { input }) | nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { input }) => { - KvnDeserializerErr::EmptyKeyword { input } + KvnDeserializerErr::EmptyKeyword { + input: input.to_string(), + } } nom::Err::Error(KvnDateTimeParserErr::InvalidFormat { input }) | nom::Err::Failure(KvnDateTimeParserErr::InvalidFormat { input }) => { - KvnDeserializerErr::InvalidDateTimeFormat { input } + KvnDeserializerErr::InvalidDateTimeFormat { + input: input.to_string(), + } } nom::Err::Error(KvnDateTimeParserErr::ParserError(i, k)) | nom::Err::Failure(KvnDateTimeParserErr::ParserError(i, k)) => { - KvnDeserializerErr::GeneralParserError(i, k) + KvnDeserializerErr::GeneralParserError(i.to_string(), k) } // We don't use streaming deserialization nom::Err::Incomplete(_) => unimplemented!(), @@ -95,24 +107,30 @@ impl From>> for KvnDeserializerErr { } } -impl From>> for KvnDeserializerErr { - fn from(value: nom::Err>) -> Self { +impl From>> for KvnDeserializerErr { + fn from(value: nom::Err>) -> Self { match value { nom::Err::Error(KvnNumberParserErr::EmptyValue { input }) | nom::Err::Failure(KvnNumberParserErr::EmptyValue { input }) => { - KvnDeserializerErr::EmptyValue { input } + KvnDeserializerErr::EmptyValue { + input: input.to_string(), + } } nom::Err::Error(KvnNumberParserErr::EmptyKeyword { input }) | nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { input }) => { - KvnDeserializerErr::EmptyKeyword { input } + KvnDeserializerErr::EmptyKeyword { + input: input.to_string(), + } } nom::Err::Error(KvnNumberParserErr::InvalidFormat { input }) | nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input }) => { - KvnDeserializerErr::InvalidDateTimeFormat { input } + KvnDeserializerErr::InvalidDateTimeFormat { + input: input.to_string(), + } } nom::Err::Error(KvnNumberParserErr::ParserError(i, k)) | nom::Err::Failure(KvnNumberParserErr::ParserError(i, k)) => { - KvnDeserializerErr::GeneralParserError(i, k) + KvnDeserializerErr::GeneralParserError(i.to_string(), k) } // We don't use streaming deserialization nom::Err::Incomplete(_) => unimplemented!(), @@ -120,12 +138,12 @@ impl From>> for KvnDeserializerErr { } } -impl From> for KvnDeserializerErr { - fn from(value: KvnKeyMatchErr) -> Self { +impl From> for KvnDeserializerErr { + fn from(value: KvnKeyMatchErr<&str>) -> Self { match value { - KvnKeyMatchErr::KeywordNotFound { expected } => { - KvnDeserializerErr::KeywordNotFound { expected } - } + KvnKeyMatchErr::KeywordNotFound { expected } => KvnDeserializerErr::KeywordNotFound { + expected: expected.to_string(), + }, } } } @@ -191,7 +209,7 @@ pub fn parse_kvn_string_line_new( .trim_start() .trim_start_matches("COMMENT") .trim_start() - .to_owned(), + .to_string(), unit: None, }, )); @@ -219,7 +237,7 @@ pub fn parse_kvn_string_line_new( .unwrap() .as_str() .trim_end() - .to_owned(); + .to_string(); if keyword.is_empty() { return Err(nom::Err::Failure(KvnStringParserErr::EmptyKeyword { @@ -233,7 +251,7 @@ pub fn parse_kvn_string_line_new( .unwrap() .as_str() .trim_end() - .to_owned(); + .to_string(); if value.is_empty() { return Err(nom::Err::Failure(KvnStringParserErr::EmptyValue { input })); @@ -274,7 +292,7 @@ where .unwrap() .as_str() .trim_end() - .to_owned(); + .to_string(); if keyword.is_empty() { return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { @@ -284,7 +302,7 @@ where // This unwrap is okay because the value uses * so it will always capture let value = captures.name("value").unwrap().as_str(); - let unit = captures.name("unit").map(|x| x.as_str().to_owned()); + let unit = captures.name("unit").map(|x| x.as_str().to_string()); let value = value .parse::() @@ -331,7 +349,7 @@ pub fn parse_kvn_numeric_line_new( .unwrap() .as_str() .trim_end() - .to_owned(); + .to_string(); if keyword.is_empty() { return Err(nom::Err::Failure(KvnNumberParserErr::EmptyKeyword { @@ -341,7 +359,7 @@ pub fn parse_kvn_numeric_line_new( // This unwrap is okay because the value uses * so it will always capture let value = captures.name("value").unwrap().as_str(); - let unit = captures.name("unit").map(|x| x.as_str().to_owned()); + let unit = captures.name("unit").map(|x| x.as_str().to_string()); let value = fast_float::parse(value) .map_err(|_| nom::Err::Failure(KvnNumberParserErr::InvalidFormat { input }))?; @@ -373,7 +391,7 @@ pub fn parse_kvn_datetime_line_new( .unwrap() .as_str() .trim_end() - .to_owned(); + .to_string(); if keyword.is_empty() { return Err(nom::Err::Failure(KvnDateTimeParserErr::EmptyKeyword { @@ -422,7 +440,7 @@ pub fn parse_kvn_datetime_line_new( let fractional_second = full_second.fract(); - let full_value = captures.name("value").unwrap().as_str().to_owned(); + let full_value = captures.name("value").unwrap().as_str().to_string(); Ok(( "", From 5f21909d4ea371f733978e131b953896cbfcd4ad Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:34:03 +0300 Subject: [PATCH 136/150] Add _list suffix for consistency --- crates/lox-io/src/ndm/json/omm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/lox-io/src/ndm/json/omm.rs b/crates/lox-io/src/ndm/json/omm.rs index 7961c25f..d2e9b044 100644 --- a/crates/lox-io/src/ndm/json/omm.rs +++ b/crates/lox-io/src/ndm/json/omm.rs @@ -336,7 +336,7 @@ pub struct OpmCovarianceMatrixType { #[serde(default)] pub struct OmmMetadata { #[serde(rename = "COMMENT")] - pub comment: Vec, + pub comment_list: Vec, #[serde(rename = "OBJECT_NAME")] pub object_name: String, #[serde(rename = "OBJECT_ID")] @@ -454,7 +454,7 @@ mod test { message_id: None, }, metadata: OmmMetadata { - comment: vec![], + comment_list: vec![], object_name: "NUSAT-8 (MARIE)".to_string(), object_id: "2020-003C".to_string(), center_name: "EARTH".to_string(), From ebb19b288ff294af40d74e57e2812ae08b0c8785 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:36:10 +0300 Subject: [PATCH 137/150] Add new line at end of file --- codecov.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codecov.yaml b/codecov.yaml index 582cabf0..3fb7b97a 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -1,4 +1,5 @@ ignore: # This code is tested indirectly with high coverage but coverage tools don't # handle proc macros - - "crates/lox-derive/src/lib.rs" \ No newline at end of file + - "crates/lox-derive/src/lib.rs" + \ No newline at end of file From ffffd00ef03944014881645f210b92f4a0efedba Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:43:05 +0300 Subject: [PATCH 138/150] Make KvnDeserializerErr cloneable --- crates/lox-io/src/ndm/kvn/deserializer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs index 0a036272..a05ae091 100644 --- a/crates/lox-io/src/ndm/kvn/deserializer.rs +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -18,7 +18,7 @@ pub trait KvnDeserializer { fn should_check_key_match() -> bool; } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Clone, Debug)] pub enum KvnDeserializerErr { InvalidDateTimeFormat { input: I }, InvalidNumberFormat { input: I }, From 02970987d4f6e170188dd3703cae4f0dd94f1f6a Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:45:26 +0300 Subject: [PATCH 139/150] Add Error derive --- crates/lox-io/src/ndm/kvn/deserializer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs index a05ae091..863f85a3 100644 --- a/crates/lox-io/src/ndm/kvn/deserializer.rs +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -18,7 +18,7 @@ pub trait KvnDeserializer { fn should_check_key_match() -> bool; } -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Clone, thiserror::Error, Debug)] pub enum KvnDeserializerErr { InvalidDateTimeFormat { input: I }, InvalidNumberFormat { input: I }, From 5ddb3b2bb2b9881e64acca9f53b00b4d1df60441 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:52:31 +0300 Subject: [PATCH 140/150] Make single-variant enum into struct --- crates/lox-io/src/ndm/kvn/parser.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index a5cd3712..24ac702b 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -25,8 +25,8 @@ pub enum KvnStringParserErr { } #[derive(Debug, PartialEq)] -pub enum KvnKeyMatchErr { - KeywordNotFound { expected: I }, +pub struct KvnKeywordNotFoundErr { + expected: I, } #[derive(PartialEq, Debug)] @@ -138,12 +138,10 @@ impl From>> for KvnDeserializerErr { } } -impl From> for KvnDeserializerErr { - fn from(value: KvnKeyMatchErr<&str>) -> Self { - match value { - KvnKeyMatchErr::KeywordNotFound { expected } => KvnDeserializerErr::KeywordNotFound { - expected: expected.to_string(), - }, +impl From> for KvnDeserializerErr { + fn from(value: KvnKeywordNotFoundErr<&str>) -> Self { + KvnDeserializerErr::KeywordNotFound { + expected: value.expected.to_string(), } } } @@ -180,7 +178,7 @@ pub struct KvnDateTimeValue { pub fn kvn_line_matches_key_new<'a>( key: &'a str, input: &'a str, -) -> Result> { +) -> Result> { if key == "COMMENT" { ns::tuple((nc::space0::<_, nom::error::Error<_>>, nb::tag(key)))(input) .map(|_| true) @@ -189,7 +187,7 @@ pub fn kvn_line_matches_key_new<'a>( let mut equals = ns::tuple((nc::space0::<_, nom::error::Error<_>>, nc::char('='))); if equals(input).is_ok() { - return Err(KvnKeyMatchErr::KeywordNotFound { expected: key }); + return Err(KvnKeywordNotFoundErr { expected: key }); } ns::delimited(nc::space0, nb::tag(key), equals)(input) @@ -477,7 +475,7 @@ mod test { ); assert_eq!( kvn_line_matches_key_new("ASD", "= ASDFG"), - Err(KvnKeyMatchErr::KeywordNotFound { expected: "ASD" }) + Err(KvnKeywordNotFoundErr { expected: "ASD" }) ); } From b6abdbf13d25dff1f8fc9e3f8e750bb8f5eb031b Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Fri, 14 Jun 2024 19:57:43 +0300 Subject: [PATCH 141/150] Fix typo in rustdoc --- crates/lox-io/src/ndm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index fea448c8..26b9efb1 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -8,7 +8,7 @@ //! Since Rust XML and JSON deserializers are slightly incompatible, the JSON //! deserializer is separate. //! -//! Because there a signficant number of messages out there that do not +//! Because there are a signficant number of messages out there that do not //! strictly comply with the specification, the parsers are relaxed in terms of //! input that they accept. Some relaxations: //! From 2be3c31d12e36374d1e5691f3ea65070454b59fa Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 17 Jun 2024 23:09:13 +0300 Subject: [PATCH 142/150] Expand KVN spec comment --- crates/lox-io/src/ndm/kvn/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn/parser.rs b/crates/lox-io/src/ndm/kvn/parser.rs index 24ac702b..fc00c331 100644 --- a/crates/lox-io/src/ndm/kvn/parser.rs +++ b/crates/lox-io/src/ndm/kvn/parser.rs @@ -6,7 +6,8 @@ * file, you can obtain one at https://mozilla.org/MPL/2.0/. */ -// KVN spec section 7.4 of https://public.ccsds.org/Pubs/502x0b3e1.pdf +// This parser handles the Keyword Value Notation (KVN) defined in section +// 7.4 of CCSDS 502.0-B-3 (https://public.ccsds.org/Pubs/502x0b3e1.pdf). use nom::bytes::complete as nb; use nom::character::complete as nc; From 0baf95291b610da6e2ccfd17dd1cde45530fd4aa Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 17 Jun 2024 23:21:06 +0300 Subject: [PATCH 143/150] Clean-up extra commas --- crates/lox-io/src/ndm/json/omm.rs | 2 +- crates/lox-io/src/ndm/ndm_ci.rs | 68 ++++++++-------- crates/lox-io/src/ndm/oem.rs | 56 ++++++------- crates/lox-io/src/ndm/omm.rs | 90 ++++++++++----------- crates/lox-io/src/ndm/opm.rs | 128 +++++++++++++++--------------- 5 files changed, 172 insertions(+), 172 deletions(-) diff --git a/crates/lox-io/src/ndm/json/omm.rs b/crates/lox-io/src/ndm/json/omm.rs index d2e9b044..f345acfe 100644 --- a/crates/lox-io/src/ndm/json/omm.rs +++ b/crates/lox-io/src/ndm/json/omm.rs @@ -483,7 +483,7 @@ mod test { },), tle_parameters: Some(TleParametersType { ephemeris_type: Some(0,), - classification_type: Some("U".to_string(),), + classification_type: Some("U".to_string()), norad_cat_id: Some(45018,), element_set_no: Some(999,), rev_at_epoch: Some(5327,), diff --git a/crates/lox-io/src/ndm/ndm_ci.rs b/crates/lox-io/src/ndm/ndm_ci.rs index 42844205..74fc63ce 100644 --- a/crates/lox-io/src/ndm/ndm_ci.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -707,10 +707,10 @@ mod test { time_system: "UTC".to_string(), }, data: opm::OpmData { - comment_list: vec!["final COMMENT, I think".to_string(),], + comment_list: vec!["final COMMENT, I think".to_string()], state_vector: common::StateVectorType { comment_list: vec![], - epoch: common::EpochType("2004-100T00:00:00Z".to_string(),), + epoch: common::EpochType("2004-100T00:00:00Z".to_string()), x: common::PositionType { base: 1.0, units: None, @@ -740,47 +740,47 @@ mod test { comment_list: vec![], semi_major_axis: common::DistanceType { base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string())), }, eccentricity: common::NonNegativeDouble(0.0,), inclination: common::InclinationType { base: 45.0, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string())), }, ra_of_asc_node: common::AngleType { base: 0.0, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string())), }, arg_of_pericenter: common::AngleType { base: 15.0, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string())), }, true_anomaly: Some(common::AngleType { base: 15.0, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string())), },), mean_anomaly: None, gm: common::GmType { base: common::PositiveDouble(398644.0,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), + units: Some(common::GmUnits("km**3/s**2".to_string())), }, },), spacecraft_parameters: Some(common::SpacecraftParametersType { comment_list: vec![], mass: Some(common::MassType { base: common::NonNegativeDouble(100.0,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string())), },), solar_rad_area: Some(common::AreaType { base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), + units: Some(common::AreaUnits("m**2".to_string())), },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,)), drag_area: Some(common::AreaType { base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), + units: Some(common::AreaUnits("m**2".to_string())), },), - drag_coeff: Some(common::NonNegativeDouble(2.0,),), + drag_coeff: Some(common::NonNegativeDouble(2.0,)), },), covariance_matrix: None, maneuver_parameters_list: vec![opm::ManeuverParametersType { @@ -799,15 +799,15 @@ mod test { man_ref_frame: "GRC".to_string(), man_dv_1: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string())), }, man_dv_2: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string())), }, man_dv_3: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string())), }, },], user_defined_parameters: None, @@ -821,7 +821,7 @@ mod test { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + creation_date: common::EpochType("2004-281T17:26:06".to_string()), originator: "me".to_string(), message_id: None, }, @@ -839,8 +839,8 @@ mod test { data: opm::OpmData { comment_list: vec![], state_vector: common::StateVectorType { - comment_list: vec!["this is a comment".to_string(),], - epoch: common::EpochType("2004-100T00:00:00".to_string(),), + comment_list: vec!["this is a comment".to_string()], + epoch: common::EpochType("2004-100T00:00:00".to_string()), x: common::PositionType { base: 1.0, units: None, @@ -868,7 +868,7 @@ mod test { }, keplerian_elements: None, spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec!["This is a COMMENT".to_string(),], + comment_list: vec!["This is a COMMENT".to_string()], mass: Some(common::MassType { base: common::NonNegativeDouble(100.0,), units: None, @@ -877,26 +877,26 @@ mod test { base: common::NonNegativeDouble(2.0,), units: None, },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,)), drag_area: Some(common::AreaType { base: common::NonNegativeDouble(2.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), + units: Some(common::AreaUnits("m**2".to_string())), },), - drag_coeff: Some(common::NonNegativeDouble(2.0,),), + drag_coeff: Some(common::NonNegativeDouble(2.0,)), },), covariance_matrix: None, maneuver_parameters_list: vec![opm::ManeuverParametersType { - comment_list: vec!["This is a COMMENT".to_string(),], + comment_list: vec!["This is a COMMENT".to_string()], man_epoch_ignition: common::EpochType( "2004-125T00:00:00".to_string(), ), man_duration: common::DurationType { base: common::NonNegativeDouble(0.0,), - units: Some(common::TimeUnits("s".to_string(),),), + units: Some(common::TimeUnits("s".to_string())), }, man_delta_mass: common::DeltamassType { base: common::NegativeDouble(-1.0,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string())), }, man_ref_frame: "GRC".to_string(), man_dv_1: common::VelocityType { @@ -923,7 +923,7 @@ mod test { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + creation_date: common::EpochType("2004-281T17:26:06".to_string()), originator: "me".to_string(), message_id: None, }, @@ -945,7 +945,7 @@ mod test { stop_time: common::EpochType( "2004-100T01:00:00.000000".to_string(), ), - interpolation: Some("Hermite".to_string(),), + interpolation: Some("Hermite".to_string()), interpolation_degree: Some(1,), }, data: oem::OemData { @@ -959,7 +959,7 @@ mod test { base: 1.0, units: Some(common::PositionUnits( "km".to_string(), - ),), + )), }, y: common::PositionType { base: 1.0, @@ -973,7 +973,7 @@ mod test { base: 1.0, units: Some(common::VelocityUnits( "km/s".to_string(), - ),), + )), }, y_dot: common::VelocityType { base: 1.0, @@ -999,7 +999,7 @@ mod test { base: 1.0, units: Some(common::PositionUnits( "km".to_string(), - ),), + )), }, z: common::PositionType { base: 1.0, @@ -1013,7 +1013,7 @@ mod test { base: 1.0, units: Some(common::VelocityUnits( "km/s".to_string(), - ),), + )), }, z_dot: common::VelocityType { base: 1.0, @@ -1039,7 +1039,7 @@ mod test { base: 1.0, units: Some(common::PositionUnits( "km".to_string(), - ),), + )), }, x_dot: common::VelocityType { base: 1.0, @@ -1053,7 +1053,7 @@ mod test { base: 1.0, units: Some(common::VelocityUnits( "km/s".to_string(), - ),), + )), }, x_ddot: None, y_ddot: None, diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 9a8980ce..50409df2 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -217,7 +217,7 @@ mod test { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType("2004-281T17:26:06".to_string(),), + creation_date: common::EpochType("2004-281T17:26:06".to_string()), originator: "me".to_string(), message_id: None, }, @@ -231,21 +231,21 @@ mod test { ref_frame: "IAU-Saturn".to_string(), ref_frame_epoch: None, time_system: "UTC".to_string(), - start_time: common::EpochType("2004-100T00:00:00.000000".to_string(),), + start_time: common::EpochType("2004-100T00:00:00.000000".to_string()), useable_start_time: None, useable_stop_time: None, - stop_time: common::EpochType("2004-100T01:00:00.000000".to_string(),), - interpolation: Some("Hermite".to_string(),), + stop_time: common::EpochType("2004-100T01:00:00.000000".to_string()), + interpolation: Some("Hermite".to_string()), interpolation_degree: Some(1,), }, data: OemData { comment_list: vec![], state_vector_list: vec![ common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), + epoch: common::EpochType("2004-100T00:00:00".to_string()), x: common::PositionType { base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, y: common::PositionType { base: 1.0, @@ -257,7 +257,7 @@ mod test { }, x_dot: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, y_dot: common::VelocityType { base: 1.0, @@ -272,14 +272,14 @@ mod test { z_ddot: None, }, common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), + epoch: common::EpochType("2004-100T00:00:00".to_string()), x: common::PositionType { base: 1.0, units: None, }, y: common::PositionType { base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, z: common::PositionType { base: 1.0, @@ -291,7 +291,7 @@ mod test { }, y_dot: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, z_dot: common::VelocityType { base: 1.0, @@ -302,7 +302,7 @@ mod test { z_ddot: None, }, common::StateVectorAccType { - epoch: common::EpochType("2004-100T00:00:00".to_string(),), + epoch: common::EpochType("2004-100T00:00:00".to_string()), x: common::PositionType { base: 1.0, units: None, @@ -313,7 +313,7 @@ mod test { }, z: common::PositionType { base: 1.0, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, x_dot: common::VelocityType { base: 1.0, @@ -325,7 +325,7 @@ mod test { }, z_dot: common::VelocityType { base: 1.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, x_ddot: None, y_ddot: None, @@ -458,11 +458,11 @@ mod test { message, OemType { header: common::OdmHeader { - comment_list: vec!["OEM WITH OPTIONAL ACCELERATIONS".to_string(),], + comment_list: vec!["OEM WITH OPTIONAL ACCELERATIONS".to_string()], classification_list: vec![], - creation_date: common::EpochType("1996-11-04T17:22:31".to_string(),), + creation_date: common::EpochType("1996-11-04T17:22:31".to_string()), originator: "NASA/JPL".to_string(), - message_id: Some("OEM 201113719185".to_string(),), + message_id: Some("OEM 201113719185".to_string()), }, body: OemBody { segment_list: vec![OemSegment { @@ -474,15 +474,15 @@ mod test { ref_frame: "J2000".to_string(), ref_frame_epoch: None, time_system: "UTC".to_string(), - start_time: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + start_time: common::EpochType("1996-12-18T12:00:00.331".to_string()), useable_start_time: Some(common::EpochType( "1996-12-18T12:10:00.331".to_string(), - ),), + )), useable_stop_time: Some(common::EpochType( "1996-12-28T21:23:00.331".to_string(), - ),), - stop_time: common::EpochType("1996-12-28T21:28:00.331".to_string(),), - interpolation: Some("HERMITE".to_string(),), + )), + stop_time: common::EpochType("1996-12-28T21:28:00.331".to_string()), + interpolation: Some("HERMITE".to_string()), interpolation_degree: Some(7,), }, data: OemData { @@ -493,7 +493,7 @@ mod test { ], state_vector_list: vec![ common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:00:00.331".to_string(),), + epoch: common::EpochType("1996-12-18T12:00:00.331".to_string()), x: common::PositionType { base: 2789.6, units: None, @@ -532,7 +532,7 @@ mod test { },), }, common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:01:00.331".to_string(),), + epoch: common::EpochType("1996-12-18T12:01:00.331".to_string()), x: common::PositionType { base: 2783.4, units: None, @@ -571,7 +571,7 @@ mod test { },), }, common::StateVectorAccType { - epoch: common::EpochType("1996-12-18T12:02:00.331".to_string(),), + epoch: common::EpochType("1996-12-18T12:02:00.331".to_string()), x: common::PositionType { base: 2776.0, units: None, @@ -610,7 +610,7 @@ mod test { },), }, common::StateVectorAccType { - epoch: common::EpochType("1996-12-28T21:28:00.331".to_string(),), + epoch: common::EpochType("1996-12-28T21:28:00.331".to_string()), x: common::PositionType { base: -3881.0, units: None, @@ -650,9 +650,9 @@ mod test { }, ], covariance_matrix_list: vec![common::OemCovarianceMatrixType { - comment_list: vec!["blabla".to_string(),], - epoch: common::EpochType("1996-12-28T22:28:00.331".to_string(),), - cov_ref_frame: Some("ITRF1997".to_string(),), + comment_list: vec!["blabla".to_string()], + epoch: common::EpochType("1996-12-28T22:28:00.331".to_string()), + cov_ref_frame: Some("ITRF1997".to_string()), cx_x: common::PositionCovarianceType { base: 0.316, units: None, diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 82892a73..f830de88 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -782,7 +782,7 @@ mod test { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string()), originator: "CelesTrak".to_string(), message_id: None, }, @@ -802,7 +802,7 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType("2021-03-22T13:21:09.224928".to_string(),), + epoch: common::EpochType("2021-03-22T13:21:09.224928".to_string()), semi_major_axis: None, mean_motion: Some(RevType { base: 13.82309053, @@ -832,9 +832,9 @@ mod test { tle_parameters: Some(TleParametersType { comment_list: vec![], ephemeris_type: Some(0,), - classification_type: Some("U".to_string(),), + classification_type: Some("U".to_string()), norad_cat_id: Some(7646,), - element_set_no: Some(ElementSetNoType("999".to_string(),),), + element_set_no: Some(ElementSetNoType("999".to_string()),), rev_at_epoch: Some(32997,), bstar: Some(BStarType { base: -4.7102e-6, @@ -940,11 +940,11 @@ mod test { message, OmmType { header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string()], classification_list: vec![], - creation_date: common::EpochType("2007-065T16:00:00".to_string(),), + creation_date: common::EpochType("2007-065T16:00:00".to_string()), originator: "NOAA".to_string(), - message_id: Some("OMM 201113719185".to_string(),), + message_id: Some("OMM 201113719185".to_string()), }, body: OmmBody { segment: OmmSegment { @@ -962,7 +962,7 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), + epoch: common::EpochType("2007-064T10:34:41.4264".to_string()), semi_major_axis: None, mean_motion: Some(RevType { base: 1.00273272, @@ -996,7 +996,7 @@ mod test { ephemeris_type: None, classification_type: None, norad_cat_id: Some(23581,), - element_set_no: Some(ElementSetNoType("0925".to_string(),),), + element_set_no: Some(ElementSetNoType("0925".to_string()),), rev_at_epoch: Some(4316,), bstar: Some(BStarType { base: 0.0001, @@ -1015,7 +1015,7 @@ mod test { },), covariance_matrix: Some(common::OpmCovarianceMatrixType { comment_list: vec![], - cov_ref_frame: Some("TEME".to_string(),), + cov_ref_frame: Some("TEME".to_string()), cx_x: common::PositionCovarianceType { base: 0.0003331349476038534, units: None, @@ -1192,11 +1192,11 @@ mod test { message, OmmType { header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string(),], + comment_list: vec!["THIS IS AN XML VERSION OF THE OMM".to_string()], classification_list: vec![], - creation_date: common::EpochType("2007-065T16:00:00".to_string(),), + creation_date: common::EpochType("2007-065T16:00:00".to_string()), originator: "NOAA".to_string(), - message_id: Some("OMM 201113719185".to_string(),), + message_id: Some("OMM 201113719185".to_string()), }, body: OmmBody { segment: OmmSegment { @@ -1213,29 +1213,29 @@ mod test { data: OmmData { comment_list: vec![], mean_elements: MeanElementsType { - comment_list: vec!["mean Elements".to_string(),], - epoch: common::EpochType("2007-064T10:34:41.4264".to_string(),), + comment_list: vec!["mean Elements".to_string()], + epoch: common::EpochType("2007-064T10:34:41.4264".to_string()), semi_major_axis: None, mean_motion: Some(RevType { base: 1.00273272, - units: Some(RevUnits("rev/day".to_string(),),), + units: Some(RevUnits("rev/day".to_string()),), },), eccentricity: common::NonNegativeDouble(0.0005013,), inclination: common::InclinationType { base: 3.0539, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, ra_of_asc_node: common::AngleType { base: 81.7939, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, arg_of_pericenter: common::AngleType { base: 249.2363, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, mean_anomaly: common::AngleType { base: 150.1602, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, gm: Some(common::GmType { base: common::PositiveDouble(398600.8,), @@ -1244,30 +1244,30 @@ mod test { }, spacecraft_parameters: None, tle_parameters: Some(TleParametersType { - comment_list: vec!["tle Parameters".to_string(),], + comment_list: vec!["tle Parameters".to_string()], ephemeris_type: None, classification_type: None, norad_cat_id: Some(23581,), - element_set_no: Some(ElementSetNoType("0925".to_string(),),), + element_set_no: Some(ElementSetNoType("0925".to_string()),), rev_at_epoch: Some(4316,), bstar: Some(BStarType { base: 0.0001, - units: Some(BStarUnits("1/ER".to_string(),),), + units: Some(BStarUnits("1/ER".to_string()),), },), bterm: None, mean_motion_dot: DRevType { base: -1.13e-6, - units: Some(DRevUnits("rev/day**2".to_string(),),), + units: Some(DRevUnits("rev/day**2".to_string()),), }, mean_motion_ddot: Some(DRevType { base: 0.0, - units: Some(DRevUnits("rev/day**3".to_string(),),), + units: Some(DRevUnits("rev/day**3".to_string()),), },), agom: None, },), covariance_matrix: Some(common::OpmCovarianceMatrixType { - comment_list: vec!["covariance Matrix".to_string(),], - cov_ref_frame: Some("TEME".to_string(),), + comment_list: vec!["covariance Matrix".to_string()], + cov_ref_frame: Some("TEME".to_string()), cx_x: common::PositionCovarianceType { base: 0.0003331349476038534, units: None, @@ -1419,7 +1419,7 @@ mod test { header: common::OdmHeader { comment_list: vec![], classification_list: vec![], - creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string(),), + creation_date: common::EpochType("2021-03-24T23:00:00.000".to_string()), originator: "CelesTrak".to_string(), message_id: None, }, @@ -1439,41 +1439,41 @@ mod test { comment_list: vec![], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string()), semi_major_axis: None, mean_motion: Some(RevType { base: 15.72125391, - units: Some(RevUnits("rev/day".to_string(),),), + units: Some(RevUnits("rev/day".to_string()),), },), eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { base: 51.6416, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, ra_of_asc_node: common::AngleType { base: 247.4627, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, arg_of_pericenter: common::AngleType { base: 130.536, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, mean_anomaly: common::AngleType { base: 325.0288, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, gm: Some(common::GmType { base: common::PositiveDouble(398600.8,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), + units: Some(common::GmUnits("km**3/s**2".to_string()),), },), }, spacecraft_parameters: None, tle_parameters: Some(TleParametersType { comment_list: vec![], ephemeris_type: Some(0,), - classification_type: Some("U".to_string(),), + classification_type: Some("U".to_string()), norad_cat_id: Some(7646,), - element_set_no: Some(ElementSetNoType("999".to_string(),),), + element_set_no: Some(ElementSetNoType("999".to_string()),), rev_at_epoch: Some(32997,), bstar: Some(BStarType { base: -4.7102e-6, @@ -1606,21 +1606,21 @@ mod test { "here is another one".to_string(), ], classification_list: vec![], - creation_date: common::EpochType("2007-06-05T16:00:00".to_string(),), + creation_date: common::EpochType("2007-06-05T16:00:00".to_string()), originator: "NOAA/USA".to_string(), message_id: None, }, body: OmmBody { segment: OmmSegment { metadata: OmmMetadata { - comment_list: vec!["this comment doesn't say much".to_string(),], + comment_list: vec!["this comment doesn't say much".to_string()], object_name: "GOES 9".to_string(), object_id: "1995-025A".to_string(), center_name: "EARTH".to_string(), ref_frame: "TOD".to_string(), ref_frame_epoch: Some(common::EpochType( "2000-01-03T10:34:00".to_string(), - ),), + )), time_system: "MRT".to_string(), mean_element_theory: "SOME THEORY".to_string(), }, @@ -1630,7 +1630,7 @@ mod test { ], mean_elements: MeanElementsType { comment_list: vec![], - epoch: common::EpochType("2000-01-05T10:00:00".to_string(),), + epoch: common::EpochType("2000-01-05T10:00:00".to_string()), semi_major_axis: Some(common::DistanceType { base: 6800.0, units: None, @@ -1656,7 +1656,7 @@ mod test { gm: None, }, spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec!["spacecraft data".to_string(),], + comment_list: vec!["spacecraft data".to_string()], mass: Some(common::MassType { base: common::NonNegativeDouble(300.0,), units: None, @@ -1665,17 +1665,17 @@ mod test { base: common::NonNegativeDouble(5.0,), units: None, },), - solar_rad_coeff: Some(common::NonNegativeDouble(0.001,),), + solar_rad_coeff: Some(common::NonNegativeDouble(0.001,)), drag_area: Some(common::AreaType { base: common::NonNegativeDouble(4.0,), units: None, },), - drag_coeff: Some(common::NonNegativeDouble(0.002,),), + drag_coeff: Some(common::NonNegativeDouble(0.002,)), },), tle_parameters: None, covariance_matrix: Some(common::OpmCovarianceMatrixType { comment_list: vec![], - cov_ref_frame: Some("TNW".to_string(),), + cov_ref_frame: Some("TNW".to_string()), cx_x: common::PositionCovarianceType { base: 0.0003331349476038534, units: None, diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index c3b65c7e..e736ea1e 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -454,82 +454,82 @@ mod test { message, OpmType { header: common::OdmHeader { - comment_list: vec!["THIS IS AN XML VERSION OF THE OPM".to_string(),], + comment_list: vec!["THIS IS AN XML VERSION OF THE OPM".to_string()], classification_list: vec![], - creation_date: common::EpochType("2001-11-06T09:23:57".to_string(),), + creation_date: common::EpochType("2001-11-06T09:23:57".to_string()), originator: "JAXA".to_string(), - message_id: Some("OPM 201113719185".to_string(),), + message_id: Some("OPM 201113719185".to_string()), }, body: OpmBody { segment: OpmSegment { metadata: OpmMetadata { - comment_list: vec!["GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string(),], + comment_list: vec!["GEOCENTRIC, CARTESIAN, EARTH FIXED".to_string()], object_name: "OSPREY 5".to_string(), object_id: "1998-999A".to_string(), center_name: "EARTH".to_string(), ref_frame: "TOD".to_string(), ref_frame_epoch: Some(common::EpochType( "1998-12-18T14:28:15.1172".to_string(), - ),), + )), time_system: "UTC".to_string(), }, data: OpmData { comment_list: vec![], state_vector: common::StateVectorType { comment_list: vec![], - epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string(),), + epoch: common::EpochType("2008-09-20T12:25:40.104192".to_string()), x: common::PositionType { base: 4086.14718, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, y: common::PositionType { base: -994.936814, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, z: common::PositionType { base: 5250.678791, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, x_dot: common::VelocityType { base: 2.511071, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, y_dot: common::VelocityType { base: 7.25524, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, z_dot: common::VelocityType { base: -0.583165, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, keplerian_elements: Some(KeplerianElementsType { comment_list: vec![], semi_major_axis: common::DistanceType { base: 6730.96, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, eccentricity: common::NonNegativeDouble(0.0006703,), inclination: common::InclinationType { base: 51.6416, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, ra_of_asc_node: common::AngleType { base: 247.463, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, arg_of_pericenter: common::AngleType { base: 130.536, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, true_anomaly: Some(common::AngleType { base: 324.985, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), },), mean_anomaly: None, gm: common::GmType { base: common::PositiveDouble(398600.9368,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), + units: Some(common::GmUnits("km**3/s**2".to_string()),), }, },), spacecraft_parameters: Some(common::SpacecraftParametersType { @@ -542,16 +542,16 @@ mod test { base: common::NonNegativeDouble(18.77,), units: None, },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.0,),), + solar_rad_coeff: Some(common::NonNegativeDouble(1.0,)), drag_area: Some(common::AreaType { base: common::NonNegativeDouble(18.77,), units: None, },), - drag_coeff: Some(common::NonNegativeDouble(2.5,),), + drag_coeff: Some(common::NonNegativeDouble(2.5,)), },), covariance_matrix: Some(common::OpmCovarianceMatrixType { comment_list: vec![], - cov_ref_frame: Some("ITRF1997".to_string(),), + cov_ref_frame: Some("ITRF1997".to_string()), cx_x: common::PositionCovarianceType { base: 0.316, units: None, @@ -639,30 +639,30 @@ mod test { },), maneuver_parameters_list: vec![ ManeuverParametersType { - comment_list: vec!["Maneuver 1".to_string(),], + comment_list: vec!["Maneuver 1".to_string()], man_epoch_ignition: common::EpochType( "2008-09-20T12:41:09.984493".to_string(), ), man_duration: common::DurationType { base: common::NonNegativeDouble(180.0,), - units: Some(common::TimeUnits("s".to_string(),),), + units: Some(common::TimeUnits("s".to_string()),), }, man_delta_mass: common::DeltamassType { base: common::NegativeDouble(-0.001,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string()),), }, man_ref_frame: "RSW".to_string(), man_dv_1: common::VelocityType { base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_2: common::VelocityType { base: 0.28, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_3: common::VelocityType { base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, ManeuverParametersType { @@ -672,24 +672,24 @@ mod test { ), man_duration: common::DurationType { base: common::NonNegativeDouble(180.0,), - units: Some(common::TimeUnits("s".to_string(),),), + units: Some(common::TimeUnits("s".to_string()),), }, man_delta_mass: common::DeltamassType { base: common::NegativeDouble(-0.001,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string()),), }, man_ref_frame: "RSW".to_string(), man_dv_1: common::VelocityType { base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_2: common::VelocityType { base: 0.27, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_3: common::VelocityType { base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, ], @@ -803,7 +803,7 @@ MAN_DV_3 = 0.00000000 [km/s]"#; "Current intermediate orbit IO2 and maneuver planning data".to_string(), ], classification_list: vec![], - creation_date: common::EpochType("2021-06-03T05:33:00.123".to_string(),), + creation_date: common::EpochType("2021-06-03T05:33:00.123".to_string()), originator: "GSOC".to_string(), message_id: None, }, @@ -819,80 +819,80 @@ MAN_DV_3 = 0.00000000 [km/s]"#; time_system: "UTC".to_string(), }, data: OpmData { - comment_list: vec!["State Vector".to_string(),], + comment_list: vec!["State Vector".to_string()], state_vector: common::StateVectorType { comment_list: vec![], - epoch: common::EpochType("2021-06-03T00:00:00.000".to_string(),), + epoch: common::EpochType("2021-06-03T00:00:00.000".to_string()), x: common::PositionType { base: 6655.9942, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, y: common::PositionType { base: -40218.5751, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, z: common::PositionType { base: -82.9177, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, x_dot: common::VelocityType { base: 3.11548208, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, y_dot: common::VelocityType { base: 0.47042605, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, z_dot: common::VelocityType { base: -0.00101495, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, keplerian_elements: Some(KeplerianElementsType { - comment_list: vec!["Keplerian elements".to_string(),], + comment_list: vec!["Keplerian elements".to_string()], semi_major_axis: common::DistanceType { base: 41399.5123, - units: Some(common::PositionUnits("km".to_string(),),), + units: Some(common::PositionUnits("km".to_string()),), }, eccentricity: common::NonNegativeDouble(0.020842611,), inclination: common::InclinationType { base: 0.117746, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, ra_of_asc_node: common::AngleType { base: 17.604721, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, arg_of_pericenter: common::AngleType { base: 218.242943, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), }, true_anomaly: Some(common::AngleType { base: 41.922339, - units: Some(common::AngleUnits("deg".to_string(),),), + units: Some(common::AngleUnits("deg".to_string()),), },), mean_anomaly: None, gm: common::GmType { base: common::PositiveDouble(398600.4415,), - units: Some(common::GmUnits("km**3/s**2".to_string(),),), + units: Some(common::GmUnits("km**3/s**2".to_string()),), }, },), spacecraft_parameters: Some(common::SpacecraftParametersType { - comment_list: vec!["Spacecraft parameters".to_string(),], + comment_list: vec!["Spacecraft parameters".to_string()], mass: Some(common::MassType { base: common::NonNegativeDouble(1913.0,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string()),), },), solar_rad_area: Some(common::AreaType { base: common::NonNegativeDouble(10.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), + units: Some(common::AreaUnits("m**2".to_string()),), },), - solar_rad_coeff: Some(common::NonNegativeDouble(1.3,),), + solar_rad_coeff: Some(common::NonNegativeDouble(1.3,)), drag_area: Some(common::AreaType { base: common::NonNegativeDouble(10.0,), - units: Some(common::AreaUnits("m**2".to_string(),),), + units: Some(common::AreaUnits("m**2".to_string()),), },), - drag_coeff: Some(common::NonNegativeDouble(2.3,),), + drag_coeff: Some(common::NonNegativeDouble(2.3,)), },), covariance_matrix: None, maneuver_parameters_list: vec![ @@ -903,24 +903,24 @@ MAN_DV_3 = 0.00000000 [km/s]"#; ), man_duration: common::DurationType { base: common::NonNegativeDouble(132.6,), - units: Some(common::TimeUnits("s".to_string(),),), + units: Some(common::TimeUnits("s".to_string()),), }, man_delta_mass: common::DeltamassType { base: common::NegativeDouble(-18.418,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string()),), }, man_ref_frame: "EME2000".to_string(), man_dv_1: common::VelocityType { base: -0.023257, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_2: common::VelocityType { base: 0.0168316, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_3: common::VelocityType { base: -0.00893444, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, ManeuverParametersType { @@ -935,24 +935,24 @@ MAN_DV_3 = 0.00000000 [km/s]"#; ), man_duration: common::DurationType { base: common::NonNegativeDouble(0.0,), - units: Some(common::TimeUnits("s".to_string(),),), + units: Some(common::TimeUnits("s".to_string()),), }, man_delta_mass: common::DeltamassType { base: common::NegativeDouble(-1.469,), - units: Some(common::MassUnits("kg".to_string(),),), + units: Some(common::MassUnits("kg".to_string()),), }, man_ref_frame: "RTN".to_string(), man_dv_1: common::VelocityType { base: 0.001015, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_2: common::VelocityType { base: -0.001873, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, man_dv_3: common::VelocityType { base: 0.0, - units: Some(common::VelocityUnits("km/s".to_string(),),), + units: Some(common::VelocityUnits("km/s".to_string()),), }, }, ], From 08cfc1f7f4e7b1ace3bcc0b1e270bfd32dbeef94 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Mon, 17 Jun 2024 23:47:59 +0300 Subject: [PATCH 144/150] Make the check more idiomatic --- crates/lox-derive/src/lib.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index b72de7ce..8bfd6d43 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -354,8 +354,8 @@ fn generate_call_to_deserializer_for_vec_type( } fn is_value_unit_struct(item: &DeriveInput) -> bool { - for attr in item.attrs.iter() { - if attr.path().is_ident("kvn") + item.attrs.iter().any(|attr| { + attr.path().is_ident("kvn") && attr .parse_nested_meta(|meta| { if meta.path.is_ident("value_unit_struct") { @@ -365,12 +365,7 @@ fn is_value_unit_struct(item: &DeriveInput) -> bool { } }) .is_ok() - { - return true; - } - } - - false + }) } fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> { From eb9a2eac131765a53ec04bca84c649667811f558 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 19 Jun 2024 00:40:11 +0300 Subject: [PATCH 145/150] Fix comment wrap --- crates/lox-io/src/ndm/ndm_ci.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/ndm_ci.rs b/crates/lox-io/src/ndm/ndm_ci.rs index 74fc63ce..f11989a9 100644 --- a/crates/lox-io/src/ndm/ndm_ci.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -191,7 +191,8 @@ pub enum NdmChildChoice { Opm(opm::OpmType), } -/// Combined instantiation type. Currently does not support AEM, APM, CDM, RDM, TDM +/// Combined instantiation type. Currently does not support AEM, APM, CDM, +/// RDM, TDM #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct NdmType { From 15f0ab295ce44d29f9cbbc5345f4d7e6f826fb11 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 19 Jun 2024 01:11:02 +0300 Subject: [PATCH 146/150] Encapsulate the quickxml deserialization --- crates/lox-io/src/ndm.rs | 1 + crates/lox-io/src/ndm/ndm_ci.rs | 17 ++++-- crates/lox-io/src/ndm/ocm.rs | 20 +++++-- crates/lox-io/src/ndm/oem.rs | 19 +++++-- crates/lox-io/src/ndm/omm.rs | 27 ++++++---- crates/lox-io/src/ndm/opm.rs | 17 ++++-- crates/lox-io/src/ndm/xml.rs | 5 ++ crates/lox-io/src/ndm/xml/error.rs | 85 ++++++++++++++++++++++++++++++ 8 files changed, 164 insertions(+), 27 deletions(-) create mode 100644 crates/lox-io/src/ndm/xml.rs create mode 100644 crates/lox-io/src/ndm/xml/error.rs diff --git a/crates/lox-io/src/ndm.rs b/crates/lox-io/src/ndm.rs index 26b9efb1..0c0431f3 100644 --- a/crates/lox-io/src/ndm.rs +++ b/crates/lox-io/src/ndm.rs @@ -35,6 +35,7 @@ pub mod json; pub mod kvn; +pub mod xml; pub mod common; pub mod ndm_ci; diff --git a/crates/lox-io/src/ndm/ndm_ci.rs b/crates/lox-io/src/ndm/ndm_ci.rs index f11989a9..dd2cff9b 100644 --- a/crates/lox-io/src/ndm/ndm_ci.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -166,8 +166,9 @@ //! # "#; //! # //! # use lox_io::ndm::ndm_ci::NdmType; +//! # use std::str::FromStr; //! # -//! let message: NdmType = quick_xml::de::from_str(xml).unwrap(); +//! let message = NdmType::from_str(xml).unwrap(); //! ``` use serde; @@ -205,13 +206,21 @@ pub struct NdmType { pub child_list: Vec, } +impl std::str::FromStr for NdmType { + type Err = super::xml::XmlDeserializationError; + + fn from_str(xml: &str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} + #[cfg(test)] mod test { + use std::str::FromStr; + use super::super::common; use super::*; - use quick_xml::de::from_str; - #[test] fn test_parse_combined_ndm() { let xml = r#" @@ -540,7 +549,7 @@ mod test { "#; - let message: NdmType = from_str(xml).unwrap(); + let message = NdmType::from_str(xml).unwrap(); assert_eq!( message, diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index 3107a263..08d8cfca 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -11,7 +11,6 @@ //! To deserialize an XML message: //! //! ``` -//! # use lox_io::ndm::ocm::OcmType; //! # //! # let xml = r#" //! # //! # "#; //! # -//! let message: OcmType = quick_xml::de::from_str(xml).unwrap(); +//! # use lox_io::ndm::ocm::OcmType; +//! # use std::str::FromStr; +//! # +//! let message = OcmType::from_str(xml).unwrap(); //! ``` use serde; @@ -110,6 +112,14 @@ pub struct OcmType { pub version: String, } +impl std::str::FromStr for OcmType { + type Err = super::xml::XmlDeserializationError; + + fn from_str(xml: &str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} + #[derive( Clone, Debug, @@ -714,9 +724,9 @@ pub struct OcmOdParametersType { #[cfg(test)] mod test { - use super::*; + use std::str::FromStr; - use quick_xml::de::from_str; + use super::*; #[test] fn test_parse_ocm_message() { @@ -789,7 +799,7 @@ mod test { "#; - let message: OcmType = from_str(xml).unwrap(); + let message = OcmType::from_str(xml).unwrap(); assert_eq!(message, OcmType { header: common::OdmHeader { diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 50409df2..71ac3ece 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -67,8 +67,9 @@ //! # "#; //! # //! # use lox_io::ndm::oem::OemType; +//! # use std::str::FromStr; //! # -//! let message: OemType = quick_xml::de::from_str(xml).unwrap(); +//! let message = OemType::from_str(xml).unwrap(); //! ``` use serde; @@ -88,6 +89,14 @@ pub struct OemType { pub version: String, } +impl std::str::FromStr for OemType { + type Err = super::xml::XmlDeserializationError; + + fn from_str(xml: &str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} + #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct OemBody { @@ -148,9 +157,9 @@ pub struct OemData { #[cfg(test)] mod test { - use super::*; + use std::str::FromStr; - use quick_xml::de::from_str; + use super::*; #[test] fn test_parse_oem_message1() { @@ -209,7 +218,7 @@ mod test { "#; - let message: OemType = from_str(xml).unwrap(); + let message = OemType::from_str(xml).unwrap(); assert_eq!( message, @@ -452,7 +461,7 @@ mod test { "#; - let message: OemType = from_str(xml).unwrap(); + let message = OemType::from_str(xml).unwrap(); assert_eq!( message, diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index f830de88..c8c6f013 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -58,8 +58,9 @@ //! # "#; //! # //! # use lox_io::ndm::omm::OmmType; +//! # use std::str::FromStr; //! # -//! let message: OmmType = quick_xml::de::from_str(xml).unwrap(); +//! let message = OmmType::from_str(xml).unwrap(); //! ``` //! //! To deserialize a KVN message: @@ -243,6 +244,14 @@ pub struct OmmType { pub body: OmmBody, } +impl std::str::FromStr for OmmType { + type Err = super::xml::XmlDeserializationError; + + fn from_str(xml: &str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} + #[derive( Clone, Debug, @@ -501,9 +510,9 @@ pub struct DdRevType { #[cfg(test)] mod test { - use super::*; + use std::str::FromStr; - use quick_xml::de::from_str; + use super::*; #[test] fn test_parse_omm_message_xml_1() { @@ -564,7 +573,7 @@ mod test { "#; - let message: OmmType = from_str(xml).unwrap(); + let message = OmmType::from_str(xml).unwrap(); assert_eq!(message, OmmType { @@ -774,7 +783,7 @@ mod test { "#; - let message: OmmType = from_str(xml).unwrap(); + let message = OmmType::from_str(xml).unwrap(); assert_eq!( message, @@ -934,7 +943,7 @@ mod test { "#; - let message: OmmType = from_str(xml).unwrap(); + let message = OmmType::from_str(xml).unwrap(); assert_eq!( message, @@ -1186,7 +1195,7 @@ mod test { "#; - let message: OmmType = from_str(xml).unwrap(); + let message = OmmType::from_str(xml).unwrap(); assert_eq!( message, @@ -1411,7 +1420,7 @@ mod test { "#; - let message: OmmType = from_str(xml).unwrap(); + let message = OmmType::from_str(xml).unwrap(); assert_eq!( message, @@ -1538,7 +1547,7 @@ mod test { "#; - let message: Result = from_str(xml); + let message = OmmType::from_str(xml); assert!(message.is_err()); } diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index e736ea1e..0dcb5acf 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -108,6 +108,7 @@ //! #
"#; //! # //! # use lox_io::ndm::opm::OpmType; +//! # use std::str::FromStr; //! # //! let message: OpmType = quick_xml::de::from_str(xml).unwrap(); //! ``` @@ -198,6 +199,14 @@ pub struct OpmType { pub body: OpmBody, } +impl std::str::FromStr for OpmType { + type Err = super::xml::XmlDeserializationError; + + fn from_str(xml: &str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} + #[derive( Clone, Debug, @@ -346,9 +355,9 @@ pub struct ManeuverParametersType { #[cfg(test)] mod test { - use super::*; + use std::str::FromStr; - use quick_xml::de::from_str; + use super::*; #[test] fn test_parse_opm_message_xml() { @@ -448,7 +457,7 @@ mod test { "#; - let message: OpmType = from_str(xml).unwrap(); + let message = OpmType::from_str(xml).unwrap(); assert_eq!( message, @@ -734,7 +743,7 @@ mod test { "#; - let message: Result = from_str(xml); + let message: Result = OpmType::from_str(xml); assert!(message.is_err()); } diff --git a/crates/lox-io/src/ndm/xml.rs b/crates/lox-io/src/ndm/xml.rs new file mode 100644 index 00000000..69757408 --- /dev/null +++ b/crates/lox-io/src/ndm/xml.rs @@ -0,0 +1,5 @@ +//! The public interface for the XML deserializer type + +pub(crate) mod error; + +pub use error::XmlDeserializationError; diff --git a/crates/lox-io/src/ndm/xml/error.rs b/crates/lox-io/src/ndm/xml/error.rs new file mode 100644 index 00000000..0815ce4e --- /dev/null +++ b/crates/lox-io/src/ndm/xml/error.rs @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +/// Deserialization error. Simple wrapper for +/// quick_xml::errors::serialize::DeError. Check the source class for further +/// documentation. +#[derive(Clone, Debug)] +pub enum XmlDeserializationError { + Custom(String), + InvalidXml(String), + InvalidInt(String), + InvalidFloat(String), + InvalidBoolean(String), + KeyNotRead(String), + UnexpectedStart(String), + UnexpectedEnd(String), + UnexpectedEof(String), + ExpectedStart(String), + Unsupported(String), +} + +impl std::fmt::Display for XmlDeserializationError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + XmlDeserializationError::Custom(s) => write!(f, "{}", s), + XmlDeserializationError::InvalidXml(s) => write!(f, "{}", s), + XmlDeserializationError::InvalidInt(s) => write!(f, "{}", s), + XmlDeserializationError::InvalidFloat(s) => write!(f, "{}", s), + XmlDeserializationError::InvalidBoolean(s) => write!(f, "{}", s), + XmlDeserializationError::KeyNotRead(s) => write!(f, "{}", s), + XmlDeserializationError::UnexpectedStart(s) => write!(f, "{}", s), + XmlDeserializationError::UnexpectedEnd(s) => write!(f, "{}", s), + XmlDeserializationError::UnexpectedEof(s) => write!(f, "{}", s), + XmlDeserializationError::ExpectedStart(s) => write!(f, "{}", s), + XmlDeserializationError::Unsupported(s) => write!(f, "{}", s), + } + } +} + +impl ::std::error::Error for XmlDeserializationError {} + +impl From for XmlDeserializationError { + fn from(value: quick_xml::DeError) -> Self { + let error_description = format!("{:?}", value).to_string(); + + match value { + quick_xml::DeError::Custom(_) => XmlDeserializationError::Custom(error_description), + quick_xml::DeError::InvalidXml(_) => { + XmlDeserializationError::InvalidXml(error_description) + } + quick_xml::DeError::InvalidInt(_) => { + XmlDeserializationError::InvalidInt(error_description) + } + quick_xml::DeError::InvalidFloat(_) => { + XmlDeserializationError::InvalidFloat(error_description) + } + quick_xml::DeError::InvalidBoolean(_) => { + XmlDeserializationError::InvalidBoolean(error_description) + } + quick_xml::DeError::KeyNotRead => { + XmlDeserializationError::KeyNotRead(error_description) + } + quick_xml::DeError::UnexpectedStart(_) => { + XmlDeserializationError::UnexpectedStart(error_description) + } + quick_xml::DeError::UnexpectedEnd(_) => { + XmlDeserializationError::UnexpectedEnd(error_description) + } + quick_xml::DeError::UnexpectedEof => { + XmlDeserializationError::UnexpectedEof(error_description) + } + quick_xml::DeError::ExpectedStart => { + XmlDeserializationError::ExpectedStart(error_description) + } + quick_xml::DeError::Unsupported(_) => { + XmlDeserializationError::Unsupported(error_description) + } + } + } +} From fd160ed89bd815c233f13ae87a391212e881b0c6 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 19 Jun 2024 01:45:08 +0300 Subject: [PATCH 147/150] Add trait for XML deserialization --- crates/lox-io/src/ndm/ndm_ci.rs | 18 +++++---------- crates/lox-io/src/ndm/ocm.rs | 18 +++++---------- crates/lox-io/src/ndm/oem.rs | 20 ++++++---------- crates/lox-io/src/ndm/omm.rs | 28 +++++++++-------------- crates/lox-io/src/ndm/opm.rs | 18 +++++---------- crates/lox-io/src/ndm/xml.rs | 4 ++++ crates/lox-io/src/ndm/xml/deserializer.rs | 14 ++++++++++++ 7 files changed, 54 insertions(+), 66 deletions(-) create mode 100644 crates/lox-io/src/ndm/xml/deserializer.rs diff --git a/crates/lox-io/src/ndm/ndm_ci.rs b/crates/lox-io/src/ndm/ndm_ci.rs index dd2cff9b..96dbdabb 100644 --- a/crates/lox-io/src/ndm/ndm_ci.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -166,9 +166,9 @@ //! # "#; //! # //! # use lox_io::ndm::ndm_ci::NdmType; -//! # use std::str::FromStr; -//! # -//! let message = NdmType::from_str(xml).unwrap(); +//! use lox_io::ndm::xml::FromXmlStr; +//! +//! let message = NdmType::from_xml_str(xml).unwrap(); //! ``` use serde; @@ -206,17 +206,11 @@ pub struct NdmType { pub child_list: Vec, } -impl std::str::FromStr for NdmType { - type Err = super::xml::XmlDeserializationError; - - fn from_str(xml: &str) -> Result { - Ok(quick_xml::de::from_str(xml)?) - } -} +impl crate::ndm::xml::FromXmlStr<'_> for NdmType {} #[cfg(test)] mod test { - use std::str::FromStr; + use crate::ndm::xml::FromXmlStr; use super::super::common; use super::*; @@ -549,7 +543,7 @@ mod test { "#; - let message = NdmType::from_str(xml).unwrap(); + let message = NdmType::from_xml_str(xml).unwrap(); assert_eq!( message, diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index 08d8cfca..eac4f9e1 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -82,9 +82,9 @@ //! # "#; //! # //! # use lox_io::ndm::ocm::OcmType; -//! # use std::str::FromStr; -//! # -//! let message = OcmType::from_str(xml).unwrap(); +//! use lox_io::ndm::xml::FromXmlStr; +//! +//! let message = OcmType::from_xml_str(xml).unwrap(); //! ``` use serde; @@ -112,13 +112,7 @@ pub struct OcmType { pub version: String, } -impl std::str::FromStr for OcmType { - type Err = super::xml::XmlDeserializationError; - - fn from_str(xml: &str) -> Result { - Ok(quick_xml::de::from_str(xml)?) - } -} +impl crate::ndm::xml::FromXmlStr<'_> for OcmType {} #[derive( Clone, @@ -724,7 +718,7 @@ pub struct OcmOdParametersType { #[cfg(test)] mod test { - use std::str::FromStr; + use crate::ndm::xml::FromXmlStr; use super::*; @@ -799,7 +793,7 @@ mod test { "#; - let message = OcmType::from_str(xml).unwrap(); + let message = OcmType::from_xml_str(xml).unwrap(); assert_eq!(message, OcmType { header: common::OdmHeader { diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 71ac3ece..8db773c7 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -67,9 +67,9 @@ //! # "#; //! # //! # use lox_io::ndm::oem::OemType; -//! # use std::str::FromStr; -//! # -//! let message = OemType::from_str(xml).unwrap(); +//! use lox_io::ndm::xml::FromXmlStr; +//! +//! let message = OemType::from_xml_str(xml).unwrap(); //! ``` use serde; @@ -89,13 +89,7 @@ pub struct OemType { pub version: String, } -impl std::str::FromStr for OemType { - type Err = super::xml::XmlDeserializationError; - - fn from_str(xml: &str) -> Result { - Ok(quick_xml::de::from_str(xml)?) - } -} +impl crate::ndm::xml::FromXmlStr<'_> for OemType {} #[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -157,7 +151,7 @@ pub struct OemData { #[cfg(test)] mod test { - use std::str::FromStr; + use crate::ndm::xml::FromXmlStr; use super::*; @@ -218,7 +212,7 @@ mod test { "#; - let message = OemType::from_str(xml).unwrap(); + let message = OemType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -461,7 +455,7 @@ mod test { "#; - let message = OemType::from_str(xml).unwrap(); + let message = OemType::from_xml_str(xml).unwrap(); assert_eq!( message, diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index c8c6f013..c52ffb95 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -58,9 +58,9 @@ //! # "#; //! # //! # use lox_io::ndm::omm::OmmType; -//! # use std::str::FromStr; -//! # -//! let message = OmmType::from_str(xml).unwrap(); +//! use lox_io::ndm::xml::FromXmlStr; +//! +//! let message = OmmType::from_xml_str(xml).unwrap(); //! ``` //! //! To deserialize a KVN message: @@ -244,13 +244,7 @@ pub struct OmmType { pub body: OmmBody, } -impl std::str::FromStr for OmmType { - type Err = super::xml::XmlDeserializationError; - - fn from_str(xml: &str) -> Result { - Ok(quick_xml::de::from_str(xml)?) - } -} +impl crate::ndm::xml::FromXmlStr<'_> for OmmType {} #[derive( Clone, @@ -510,7 +504,7 @@ pub struct DdRevType { #[cfg(test)] mod test { - use std::str::FromStr; + use crate::ndm::xml::FromXmlStr; use super::*; @@ -573,7 +567,7 @@ mod test { "#; - let message = OmmType::from_str(xml).unwrap(); + let message = OmmType::from_xml_str(xml).unwrap(); assert_eq!(message, OmmType { @@ -783,7 +777,7 @@ mod test { "#; - let message = OmmType::from_str(xml).unwrap(); + let message = OmmType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -943,7 +937,7 @@ mod test { "#; - let message = OmmType::from_str(xml).unwrap(); + let message = OmmType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -1195,7 +1189,7 @@ mod test { "#; - let message = OmmType::from_str(xml).unwrap(); + let message = OmmType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -1420,7 +1414,7 @@ mod test { "#; - let message = OmmType::from_str(xml).unwrap(); + let message = OmmType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -1547,7 +1541,7 @@ mod test { "#; - let message = OmmType::from_str(xml); + let message = OmmType::from_xml_str(xml); assert!(message.is_err()); } diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 0dcb5acf..9d5fdc2e 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -108,8 +108,8 @@ //! # "#; //! # //! # use lox_io::ndm::opm::OpmType; -//! # use std::str::FromStr; -//! # +//! use lox_io::ndm::xml::FromXmlStr; +//! //! let message: OpmType = quick_xml::de::from_str(xml).unwrap(); //! ``` //! @@ -199,13 +199,7 @@ pub struct OpmType { pub body: OpmBody, } -impl std::str::FromStr for OpmType { - type Err = super::xml::XmlDeserializationError; - - fn from_str(xml: &str) -> Result { - Ok(quick_xml::de::from_str(xml)?) - } -} +impl crate::ndm::xml::FromXmlStr<'_> for OpmType {} #[derive( Clone, @@ -355,7 +349,7 @@ pub struct ManeuverParametersType { #[cfg(test)] mod test { - use std::str::FromStr; + use crate::ndm::xml::FromXmlStr; use super::*; @@ -457,7 +451,7 @@ mod test { "#; - let message = OpmType::from_str(xml).unwrap(); + let message = OpmType::from_xml_str(xml).unwrap(); assert_eq!( message, @@ -743,7 +737,7 @@ mod test { "#; - let message: Result = OpmType::from_str(xml); + let message: Result = OpmType::from_xml_str(xml); assert!(message.is_err()); } diff --git a/crates/lox-io/src/ndm/xml.rs b/crates/lox-io/src/ndm/xml.rs index 69757408..52dabd49 100644 --- a/crates/lox-io/src/ndm/xml.rs +++ b/crates/lox-io/src/ndm/xml.rs @@ -3,3 +3,7 @@ pub(crate) mod error; pub use error::XmlDeserializationError; + +mod deserializer; + +pub use deserializer::FromXmlStr; diff --git a/crates/lox-io/src/ndm/xml/deserializer.rs b/crates/lox-io/src/ndm/xml/deserializer.rs new file mode 100644 index 00000000..919f0a2a --- /dev/null +++ b/crates/lox-io/src/ndm/xml/deserializer.rs @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023. Helge Eichhorn and the LOX contributors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + */ + +/// Parse an NDM message from a string formatted in XML +pub trait FromXmlStr<'a>: Sized + serde::Deserialize<'a> { + fn from_xml_str(xml: &'a str) -> Result { + Ok(quick_xml::de::from_str(xml)?) + } +} From bd2a675ed00528d89867236e7219eadf3ddd9422 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Wed, 19 Jun 2024 01:57:13 +0300 Subject: [PATCH 148/150] Encapsulate kvn string split --- crates/lox-derive/src/lib.rs | 1 - crates/lox-io/src/ndm/kvn/deserializer.rs | 7 +++++++ crates/lox-io/src/ndm/omm.rs | 8 ++++---- crates/lox-io/src/ndm/opm.rs | 8 ++++---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/lox-derive/src/lib.rs b/crates/lox-derive/src/lib.rs index 8bfd6d43..8d9342a8 100644 --- a/crates/lox-derive/src/lib.rs +++ b/crates/lox-derive/src/lib.rs @@ -705,7 +705,6 @@ pub fn derive_kvn_deserialize(item: proc_macro::TokenStream) -> proc_macro::Toke { fn deserialize<'a>(lines: &mut ::std::iter::Peekable>) -> Result<#type_name, crate::ndm::kvn::KvnDeserializerErr> { - #struct_deserializer } diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs index 863f85a3..b407f65c 100644 --- a/crates/lox-io/src/ndm/kvn/deserializer.rs +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -15,6 +15,13 @@ pub trait KvnDeserializer { where Self: Sized; + fn from_kvn_str<'a>(kvn: &'a str) -> Result> + where + Self: Sized, + { + Self::deserialize(&mut kvn.lines().peekable()) + } + fn should_check_key_match() -> bool; } diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index c52ffb95..0f03f297 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -116,10 +116,10 @@ //! # CZ_DOT_Y_DOT = 1.008862586240695e-10 //! # CZ_DOT_Z_DOT = 6.224444338635500e-10"#; //! # -//! # use lox_io::ndm::kvn::KvnDeserializer; //! # use lox_io::ndm::omm::OmmType; -//! # -//! let message: OmmType = KvnDeserializer::deserialize(&mut kvn.lines().peekable()).unwrap(); +//! use lox_io::ndm::kvn::KvnDeserializer; +//! +//! let message: OmmType = KvnDeserializer::from_kvn_str(&kvn).unwrap(); //! ``` use serde; @@ -1601,7 +1601,7 @@ mod test { CZ_DOT_Z_DOT = 6.224444338635500e-10"#; assert_eq!( - crate::ndm::kvn::KvnDeserializer::deserialize(&mut kvn.lines().peekable()), + crate::ndm::kvn::KvnDeserializer::from_kvn_str(&kvn), Ok(OmmType { header: common::OdmHeader { comment_list: vec![ diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 9d5fdc2e..1a3db552 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -167,10 +167,10 @@ //! # MAN_DV_2 = -0.00187300 [km/s] //! # MAN_DV_3 = 0.00000000 [km/s]"#; //! # -//! # use lox_io::ndm::kvn::KvnDeserializer; //! # use lox_io::ndm::opm::OpmType; -//! # -//! let message: OpmType = KvnDeserializer::deserialize(&mut kvn.lines().peekable()).unwrap(); +//! use lox_io::ndm::kvn::KvnDeserializer; +//! +//! let message: OpmType = KvnDeserializer::from_kvn_str(&kvn).unwrap(); //! ``` use serde; @@ -798,7 +798,7 @@ MAN_DV_2 = -0.00187300 [km/s] MAN_DV_3 = 0.00000000 [km/s]"#; assert_eq!( - crate::ndm::kvn::KvnDeserializer::deserialize(&mut kvn.lines().peekable()), + crate::ndm::kvn::KvnDeserializer::from_kvn_str(&kvn), Ok(OpmType { header: common::OdmHeader { comment_list: vec![ From acaecdb0e09fbc550a6c463ef03631bb8db57408 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 20 Jun 2024 23:09:19 +0300 Subject: [PATCH 149/150] Explain it is generated code --- crates/lox-io/src/ndm/ndm_ci.rs | 4 ++++ crates/lox-io/src/ndm/ocm.rs | 4 ++++ crates/lox-io/src/ndm/oem.rs | 4 ++++ crates/lox-io/src/ndm/omm.rs | 4 ++++ crates/lox-io/src/ndm/opm.rs | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/crates/lox-io/src/ndm/ndm_ci.rs b/crates/lox-io/src/ndm/ndm_ci.rs index 96dbdabb..72af4311 100644 --- a/crates/lox-io/src/ndm/ndm_ci.rs +++ b/crates/lox-io/src/ndm/ndm_ci.rs @@ -171,6 +171,10 @@ //! let message = NdmType::from_xml_str(xml).unwrap(); //! ``` +// This file is partially generated with xml-schema-derive from the XSD schema +// published by CCSDS. Adaptations have been made to simplify the types or +// allow to simplify the implementation of the KVN parser. + use serde; use super::{ocm, oem, omm, opm}; diff --git a/crates/lox-io/src/ndm/ocm.rs b/crates/lox-io/src/ndm/ocm.rs index eac4f9e1..da18269f 100644 --- a/crates/lox-io/src/ndm/ocm.rs +++ b/crates/lox-io/src/ndm/ocm.rs @@ -87,6 +87,10 @@ //! let message = OcmType::from_xml_str(xml).unwrap(); //! ``` +// This file is partially generated with xml-schema-derive from the XSD schema +// published by CCSDS. Adaptations have been made to simplify the types or +// allow to simplify the implementation of the KVN parser. + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/oem.rs b/crates/lox-io/src/ndm/oem.rs index 8db773c7..8f1c3eff 100644 --- a/crates/lox-io/src/ndm/oem.rs +++ b/crates/lox-io/src/ndm/oem.rs @@ -72,6 +72,10 @@ //! let message = OemType::from_xml_str(xml).unwrap(); //! ``` +// This file is partially generated with xml-schema-derive from the XSD schema +// published by CCSDS. Adaptations have been made to simplify the types or +// allow to simplify the implementation of the KVN parser. + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/omm.rs b/crates/lox-io/src/ndm/omm.rs index 0f03f297..6e6f588d 100644 --- a/crates/lox-io/src/ndm/omm.rs +++ b/crates/lox-io/src/ndm/omm.rs @@ -122,6 +122,10 @@ //! let message: OmmType = KvnDeserializer::from_kvn_str(&kvn).unwrap(); //! ``` +// This file is partially generated with xml-schema-derive from the XSD schema +// published by CCSDS. Adaptations have been made to simplify the types or +// allow to simplify the implementation of the KVN parser. + use serde; use super::common; diff --git a/crates/lox-io/src/ndm/opm.rs b/crates/lox-io/src/ndm/opm.rs index 1a3db552..e8a53aff 100644 --- a/crates/lox-io/src/ndm/opm.rs +++ b/crates/lox-io/src/ndm/opm.rs @@ -173,6 +173,10 @@ //! let message: OpmType = KvnDeserializer::from_kvn_str(&kvn).unwrap(); //! ``` +// This file is partially generated with xml-schema-derive from the XSD schema +// published by CCSDS. Adaptations have been made to simplify the types or +// allow to simplify the implementation of the KVN parser. + use serde; use super::common; From 7ca1fb077f48f069080ea1149b307d8a0d2a8ea5 Mon Sep 17 00:00:00 2001 From: Andrei Zisu Date: Thu, 20 Jun 2024 23:14:37 +0300 Subject: [PATCH 150/150] Remove superfluous lifetimes to get clippy happy --- crates/lox-io/src/ndm/kvn/deserializer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lox-io/src/ndm/kvn/deserializer.rs b/crates/lox-io/src/ndm/kvn/deserializer.rs index b407f65c..2268be88 100644 --- a/crates/lox-io/src/ndm/kvn/deserializer.rs +++ b/crates/lox-io/src/ndm/kvn/deserializer.rs @@ -15,7 +15,7 @@ pub trait KvnDeserializer { where Self: Sized; - fn from_kvn_str<'a>(kvn: &'a str) -> Result> + fn from_kvn_str(kvn: &str) -> Result> where Self: Sized, {