diff --git a/src/output/emitter.rs b/src/output/emitter.rs index 9bfd8bd..01752dc 100644 --- a/src/output/emitter.rs +++ b/src/output/emitter.rs @@ -98,15 +98,15 @@ impl JsonEmitter { } } - fn serialize_artifact(&self, object: &spec::RootArtifact) -> serde_json::Value { + fn serialize_artifact(&self, object: &spec::RootImpl) -> serde_json::Value { let now = chrono::Local::now(); let now_tz = now.with_timezone(&self.timezone); - let out_artifact = spec::Root { + let root = spec::Root { artifact: object.clone(), timestamp: now_tz, seqno: self.next_sequence_no(), }; - serde_json::json!(out_artifact) + serde_json::json!(root) } fn next_sequence_no(&self) -> u64 { @@ -114,7 +114,7 @@ impl JsonEmitter { self.seqno.load(atomic::Ordering::SeqCst) } - pub async fn emit(&self, object: &spec::RootArtifact) -> Result<(), WriterError> { + pub async fn emit(&self, object: &spec::RootImpl) -> Result<(), WriterError> { let serialized = self.serialize_artifact(object); match self.writer { WriterType::File(ref file) => file.write(&serialized.to_string()).await?, @@ -132,8 +132,6 @@ mod tests { use serde_json::json; use super::*; - use crate::output as tv; - use tv::run::SchemaVersion; #[tokio::test] async fn test_emit_using_buffer_writer() -> Result<()> { @@ -149,8 +147,11 @@ mod tests { let writer = BufferWriter::new(buffer.clone()); let emitter = JsonEmitter::new(chrono_tz::UTC, WriterType::Buffer(writer)); - let version = SchemaVersion::new(); - emitter.emit(&version.to_artifact()).await?; + emitter + .emit(&spec::RootImpl::SchemaVersion( + spec::SchemaVersion::default(), + )) + .await?; let deserialized = serde_json::from_str::( buffer.lock().await.first().ok_or(anyhow!("no outputs"))?, @@ -180,9 +181,10 @@ mod tests { let buffer = Arc::new(Mutex::new(vec![])); let writer = BufferWriter::new(buffer.clone()); let emitter = JsonEmitter::new(chrono_tz::UTC, WriterType::Buffer(writer)); - let version = SchemaVersion::new(); - emitter.emit(&version.to_artifact()).await?; - emitter.emit(&version.to_artifact()).await?; + + let version = spec::RootImpl::SchemaVersion(spec::SchemaVersion::default()); + emitter.emit(&version).await?; + emitter.emit(&version).await?; let deserialized = serde_json::from_str::( buffer.lock().await.first().ok_or(anyhow!("no outputs"))?, diff --git a/src/output/measurement.rs b/src/output/measure.rs similarity index 90% rename from src/output/measurement.rs rename to src/output/measure.rs index a874bd9..152af80 100644 --- a/src/output/measurement.rs +++ b/src/output/measure.rs @@ -8,7 +8,6 @@ use std::future::Future; use std::sync::atomic; use std::sync::Arc; -use chrono::DateTime; use serde_json::Map; use serde_json::Value; use tokio::sync::Mutex; @@ -82,7 +81,7 @@ impl<'a> MeasurementSeries<'a> { /// ``` pub async fn start(&self) -> Result<(), emitter::WriterError> { self.emitter - .emit(&spec::TestStepArtifactDescendant::MeasurementSeriesStart( + .emit(&spec::TestStepArtifactImpl::MeasurementSeriesStart( self.start.to_artifact(), )) .await?; @@ -110,12 +109,13 @@ impl<'a> MeasurementSeries<'a> { /// # }); /// ``` pub async fn end(&self) -> Result<(), emitter::WriterError> { - let end = - MeasurementSeriesEnd::new(self.start.get_series_id(), self.current_sequence_no().await); + let end = spec::MeasurementSeriesEnd { + series_id: self.start.series_id.clone(), + total_count: self.current_sequence_no().await, + }; + self.emitter - .emit(&spec::TestStepArtifactDescendant::MeasurementSeriesEnd( - end.to_artifact(), - )) + .emit(&spec::TestStepArtifactImpl::MeasurementSeriesEnd(end)) .await?; Ok(()) @@ -142,17 +142,18 @@ impl<'a> MeasurementSeries<'a> { /// # }); /// ``` pub async fn add_measurement(&self, value: Value) -> Result<(), emitter::WriterError> { - let element = MeasurementSeriesElement::new( - self.current_sequence_no().await, - value, - &self.start, - None, - ); + let element = spec::MeasurementSeriesElement { + index: self.current_sequence_no().await, + value: value.clone(), + timestamp: chrono::Local::now().with_timezone(&chrono_tz::Tz::UTC), + series_id: self.start.series_id.clone(), + metadata: None, + }; self.increment_sequence_no().await; self.emitter - .emit(&spec::TestStepArtifactDescendant::MeasurementSeriesElement( - element.to_artifact(), + .emit(&spec::TestStepArtifactImpl::MeasurementSeriesElement( + element, )) .await?; @@ -185,19 +186,20 @@ impl<'a> MeasurementSeries<'a> { value: Value, metadata: Vec<(&str, Value)>, ) -> Result<(), emitter::WriterError> { - let element = MeasurementSeriesElement::new( - self.current_sequence_no().await, - value, - &self.start, - Some(Map::from_iter( + let element = spec::MeasurementSeriesElement { + index: self.current_sequence_no().await, + value: value.clone(), + timestamp: chrono::Local::now().with_timezone(&chrono_tz::Tz::UTC), + series_id: self.start.series_id.clone(), + metadata: Some(Map::from_iter( metadata.iter().map(|(k, v)| (k.to_string(), v.clone())), )), - ); + }; self.increment_sequence_no().await; self.emitter - .emit(&spec::TestStepArtifactDescendant::MeasurementSeriesElement( - element.to_artifact(), + .emit(&spec::TestStepArtifactImpl::MeasurementSeriesElement( + element, )) .await?; @@ -656,10 +658,6 @@ impl MeasurementSeriesStart { metadata: self.metadata.clone(), } } - - pub fn get_series_id(&self) -> &str { - &self.series_id - } } pub struct MeasurementSeriesStartBuilder { @@ -744,62 +742,6 @@ impl MeasurementSeriesStartBuilder { } } -pub struct MeasurementSeriesEnd { - series_id: String, - total_count: u64, -} - -impl MeasurementSeriesEnd { - pub(crate) fn new(series_id: &str, total_count: u64) -> MeasurementSeriesEnd { - MeasurementSeriesEnd { - series_id: series_id.to_string(), - total_count, - } - } - - pub fn to_artifact(&self) -> spec::MeasurementSeriesEnd { - spec::MeasurementSeriesEnd { - series_id: self.series_id.clone(), - total_count: self.total_count, - } - } -} - -pub struct MeasurementSeriesElement { - index: u64, - value: Value, - timestamp: DateTime, - series_id: String, - metadata: Option>, -} - -impl MeasurementSeriesElement { - pub(crate) fn new( - index: u64, - value: Value, - series: &MeasurementSeriesStart, - metadata: Option>, - ) -> MeasurementSeriesElement { - MeasurementSeriesElement { - index, - value: value.clone(), - timestamp: chrono::Local::now().with_timezone(&chrono_tz::Tz::UTC), - series_id: series.series_id.to_string(), - metadata, - } - } - - pub fn to_artifact(&self) -> spec::MeasurementSeriesElement { - spec::MeasurementSeriesElement { - index: self.index, - value: self.value.clone(), - timestamp: self.timestamp, - series_id: self.series_id.clone(), - metadata: self.metadata.clone(), - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -937,23 +879,6 @@ mod tests { Ok(()) } - #[test] - fn test_measurement_series_end_to_artifact() -> Result<()> { - let series_id = "series_id".to_owned(); - let series = MeasurementSeriesEnd::new(&series_id, 1); - - let artifact = series.to_artifact(); - assert_eq!( - artifact, - spec::MeasurementSeriesEnd { - series_id: series_id.to_string(), - total_count: 1, - } - ); - - Ok(()) - } - #[test] fn test_validator() -> Result<()> { let validator = Validator::builder(ValidatorType::Equal, 30.into()) diff --git a/src/output/mod.rs b/src/output/mod.rs index 17cd5f4..e7b1e5c 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -10,7 +10,7 @@ mod emitter; mod error; mod log; mod macros; -mod measurement; +mod measure; mod run; mod state; mod step; @@ -25,7 +25,7 @@ pub use dut::*; pub use emitter::*; pub use error::*; pub use log::*; -pub use measurement::*; +pub use measure::*; pub use run::*; pub use step::*; diff --git a/src/output/run.rs b/src/output/run.rs index d468d9f..77e7b77 100644 --- a/src/output/run.rs +++ b/src/output/run.rs @@ -16,7 +16,7 @@ use tokio::sync::Mutex; use crate::output as tv; use crate::spec; use tv::step::TestStep; -use tv::{config, dut, emitter, error, log, run, state}; +use tv::{config, dut, emitter, error, log, state}; /// The outcome of a TestRun. /// It's returned when the scope method of the [`TestRun`] object is used. @@ -33,10 +33,10 @@ pub struct TestRunOutcome { pub struct TestRun { name: String, version: String, - parameters: Map, + parameters: Map, dut: dut::DutInfo, command_line: String, - metadata: Option>, + metadata: Option>, state: Arc>, } @@ -87,35 +87,28 @@ impl TestRun { /// # }); /// ``` pub async fn start(self) -> Result { - let version = SchemaVersion::new(); + // TODO: this likely will go into the emitter since it's not the run's job to emit the schema version self.state .lock() .await .emitter - .emit(&version.to_artifact()) + .emit(&spec::RootImpl::SchemaVersion( + spec::SchemaVersion::default(), + )) .await?; - let mut builder = run::TestRunStart::builder( - &self.name, - &self.version, - &self.command_line, - &self.parameters, - &self.dut, - ); - - if let Some(m) = &self.metadata { - for m in m { - builder = builder.add_metadata(m.0, m.1.clone()) - } - } + let start = spec::RootImpl::TestRunArtifact(spec::TestRunArtifact { + artifact: spec::TestRunArtifactImpl::TestRunStart(spec::TestRunStart { + name: self.name.clone(), + version: self.version.clone(), + command_line: self.command_line.clone(), + parameters: self.parameters.clone(), + metadata: self.metadata.clone(), + dut_info: self.dut.to_spec(), + }), + }); - let start = builder.build(); - self.state - .lock() - .await - .emitter - .emit(&start.to_artifact()) - .await?; + self.state.lock().await.emitter.emit(&start).await?; Ok(StartedTestRun::new(self)) } @@ -317,14 +310,13 @@ impl StartedTestRun { status: spec::TestStatus, result: spec::TestResult, ) -> Result<(), emitter::WriterError> { - let end = run::TestRunEnd::builder() - .status(status) - .result(result) - .build(); + let end = spec::RootImpl::TestRunArtifact(spec::TestRunArtifact { + artifact: spec::TestRunArtifactImpl::TestRunEnd(spec::TestRunEnd { status, result }), + }); let emitter = &self.run.state.lock().await.emitter; - emitter.emit(&end.to_artifact()).await?; + emitter.emit(&end).await?; Ok(()) } @@ -360,10 +352,10 @@ impl StartedTestRun { let emitter = &self.run.state.lock().await.emitter; let artifact = spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::Log(log.to_artifact()), + artifact: spec::TestRunArtifactImpl::Log(log.to_artifact()), }; emitter - .emit(&spec::RootArtifact::TestRunArtifact(artifact)) + .emit(&spec::RootImpl::TestRunArtifact(artifact)) .await?; Ok(()) @@ -396,10 +388,10 @@ impl StartedTestRun { let emitter = &self.run.state.lock().await.emitter; let artifact = spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::Log(log.to_artifact()), + artifact: spec::TestRunArtifactImpl::Log(log.to_artifact()), }; emitter - .emit(&spec::RootArtifact::TestRunArtifact(artifact)) + .emit(&spec::RootImpl::TestRunArtifact(artifact)) .await?; Ok(()) @@ -428,10 +420,10 @@ impl StartedTestRun { let emitter = &self.run.state.lock().await.emitter; let artifact = spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::Error(error.to_artifact()), + artifact: spec::TestRunArtifactImpl::Error(error.to_artifact()), }; emitter - .emit(&spec::RootArtifact::TestRunArtifact(artifact)) + .emit(&spec::RootImpl::TestRunArtifact(artifact)) .await?; Ok(()) @@ -465,10 +457,10 @@ impl StartedTestRun { let emitter = &self.run.state.lock().await.emitter; let artifact = spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::Error(error.to_artifact()), + artifact: spec::TestRunArtifactImpl::Error(error.to_artifact()), }; emitter - .emit(&spec::RootArtifact::TestRunArtifact(artifact)) + .emit(&spec::RootImpl::TestRunArtifact(artifact)) .await?; Ok(()) @@ -505,10 +497,10 @@ impl StartedTestRun { let emitter = &self.run.state.lock().await.emitter; let artifact = spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::Error(error.to_artifact()), + artifact: spec::TestRunArtifactImpl::Error(error.to_artifact()), }; emitter - .emit(&spec::RootArtifact::TestRunArtifact(artifact)) + .emit(&spec::RootImpl::TestRunArtifact(artifact)) .await?; Ok(()) @@ -519,182 +511,3 @@ impl StartedTestRun { TestStep::new(&step_id, name, self.run.state.clone()) } } - -pub struct TestRunStart { - name: String, - version: String, - command_line: String, - parameters: Map, - metadata: Option>, - dut_info: dut::DutInfo, -} - -impl TestRunStart { - pub fn builder( - name: &str, - version: &str, - command_line: &str, - parameters: &Map, - dut_info: &dut::DutInfo, - ) -> TestRunStartBuilder { - TestRunStartBuilder::new(name, version, command_line, parameters, dut_info) - } - - pub fn to_artifact(&self) -> spec::RootArtifact { - spec::RootArtifact::TestRunArtifact(spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::TestRunStart(spec::TestRunStart { - name: self.name.clone(), - version: self.version.clone(), - command_line: self.command_line.clone(), - parameters: self.parameters.clone(), - metadata: self.metadata.clone(), - dut_info: self.dut_info.to_spec(), - }), - }) - } -} - -pub struct TestRunStartBuilder { - name: String, - version: String, - command_line: String, - parameters: Map, - metadata: Option>, - dut_info: dut::DutInfo, -} - -impl TestRunStartBuilder { - pub fn new( - name: &str, - version: &str, - command_line: &str, - parameters: &Map, - dut_info: &dut::DutInfo, - ) -> TestRunStartBuilder { - TestRunStartBuilder { - name: name.to_string(), - version: version.to_string(), - command_line: command_line.to_string(), - parameters: parameters.clone(), - metadata: None, - dut_info: dut_info.clone(), - } - } - - pub fn add_metadata(mut self, key: &str, value: Value) -> TestRunStartBuilder { - self.metadata = match self.metadata { - Some(mut metadata) => { - metadata.insert(key.to_string(), value.clone()); - Some(metadata) - } - None => { - let mut metadata = Map::new(); - metadata.insert(key.to_string(), value.clone()); - Some(metadata) - } - }; - self - } - - pub fn build(self) -> TestRunStart { - TestRunStart { - name: self.name, - version: self.version, - command_line: self.command_line, - parameters: self.parameters, - metadata: self.metadata, - dut_info: self.dut_info, - } - } -} - -pub struct TestRunEnd { - status: spec::TestStatus, - result: spec::TestResult, -} - -impl TestRunEnd { - pub fn builder() -> TestRunEndBuilder { - TestRunEndBuilder::new() - } - - pub fn to_artifact(&self) -> spec::RootArtifact { - spec::RootArtifact::TestRunArtifact(spec::TestRunArtifact { - artifact: spec::TestRunArtifactDescendant::TestRunEnd(spec::TestRunEnd { - status: self.status.clone(), - result: self.result.clone(), - }), - }) - } -} - -#[derive(Debug)] -pub struct TestRunEndBuilder { - status: spec::TestStatus, - result: spec::TestResult, -} - -#[allow(clippy::new_without_default)] -impl TestRunEndBuilder { - pub fn new() -> TestRunEndBuilder { - TestRunEndBuilder { - status: spec::TestStatus::Complete, - result: spec::TestResult::Pass, - } - } - pub fn status(mut self, value: spec::TestStatus) -> TestRunEndBuilder { - self.status = value; - self - } - - pub fn result(mut self, value: spec::TestResult) -> TestRunEndBuilder { - self.result = value; - self - } - - pub fn build(self) -> TestRunEnd { - TestRunEnd { - status: self.status, - result: self.result, - } - } -} - -// TODO: this likely will go into the emitter since it's not the run's job to emit the schema version -pub struct SchemaVersion { - major: i8, - minor: i8, -} - -#[allow(clippy::new_without_default)] -impl SchemaVersion { - pub fn new() -> SchemaVersion { - SchemaVersion { - major: spec::SPEC_VERSION.0, - minor: spec::SPEC_VERSION.1, - } - } - - pub fn to_artifact(&self) -> spec::RootArtifact { - spec::RootArtifact::SchemaVersion(spec::SchemaVersion { - major: self.major, - minor: self.minor, - }) - } -} - -#[cfg(test)] -mod tests { - use anyhow::Result; - - use super::*; - use crate::spec; - - #[test] - fn test_schema_creation_from_builder() -> Result<()> { - let version = SchemaVersion::new(); - assert_eq!(version.major, spec::SPEC_VERSION.0); - assert_eq!(version.minor, spec::SPEC_VERSION.1); - Ok(()) - } -} diff --git a/src/output/step.rs b/src/output/step.rs index 6b9fa36..e754dd6 100644 --- a/src/output/step.rs +++ b/src/output/step.rs @@ -10,9 +10,10 @@ use std::sync::Arc; use tokio::sync::Mutex; use crate::output as tv; -use crate::spec; -use tv::measurement::MeasurementSeries; -use tv::{emitter, error, log, measurement, state}; +use crate::spec::TestStepStart; +use crate::spec::{self, TestStepArtifactImpl}; +use tv::measure::MeasurementSeries; +use tv::{emitter, error, log, measure, state}; use super::WriterError; @@ -53,8 +54,11 @@ impl TestStep { /// # }); /// ``` pub async fn start(self) -> Result { - let start = TestStepStart::new(&self.name); - self.emitter.emit(&start.to_artifact()).await?; + self.emitter + .emit(&TestStepArtifactImpl::TestStepStart(TestStepStart { + name: self.name.clone(), + })) + .await?; Ok(StartedTestStep { step: self, @@ -126,12 +130,13 @@ impl StartedTestStep { /// # }); /// ``` pub async fn end(&self, status: spec::TestStatus) -> Result<(), emitter::WriterError> { - let end = TestStepEnd::new(status); - self.step.emitter.emit(&end.to_artifact()).await?; + let end = TestStepArtifactImpl::TestStepEnd(spec::TestStepEnd { status }); + + self.step.emitter.emit(&end).await?; Ok(()) } - /// Eemits Log message. + /// Emits Log message. /// This method accepts a [`models::LogSeverity`] to define the severity /// and a [`std::string::String`] for the message. /// @@ -181,7 +186,7 @@ impl StartedTestStep { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Log(log.to_artifact())) + .emit(&TestStepArtifactImpl::Log(log.to_artifact())) .await?; Ok(()) @@ -215,7 +220,7 @@ impl StartedTestStep { pub async fn log_with_details(&self, log: &log::Log) -> Result<(), emitter::WriterError> { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Log(log.to_artifact())) + .emit(&TestStepArtifactImpl::Log(log.to_artifact())) .await?; Ok(()) @@ -264,9 +269,7 @@ impl StartedTestStep { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Error( - error.to_artifact(), - )) + .emit(&TestStepArtifactImpl::Error(error.to_artifact())) .await?; Ok(()) @@ -320,9 +323,7 @@ impl StartedTestStep { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Error( - error.to_artifact(), - )) + .emit(&TestStepArtifactImpl::Error(error.to_artifact())) .await?; Ok(()) @@ -360,9 +361,7 @@ impl StartedTestStep { ) -> Result<(), emitter::WriterError> { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Error( - error.to_artifact(), - )) + .emit(&TestStepArtifactImpl::Error(error.to_artifact())) .await?; Ok(()) @@ -392,11 +391,11 @@ impl StartedTestStep { name: &str, value: Value, ) -> Result<(), emitter::WriterError> { - let measurement = measurement::Measurement::new(name, value); + let measurement = measure::Measurement::new(name, value); self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Measurement( + .emit(&TestStepArtifactImpl::Measurement( measurement.to_artifact(), )) .await?; @@ -433,11 +432,11 @@ impl StartedTestStep { /// ``` pub async fn add_measurement_with_details( &self, - measurement: &measurement::Measurement, + measurement: &measure::Measurement, ) -> Result<(), emitter::WriterError> { self.step .emitter - .emit(&spec::TestStepArtifactDescendant::Measurement( + .emit(&spec::TestStepArtifactImpl::Measurement( measurement.to_artifact(), )) .await?; @@ -496,46 +495,12 @@ impl StartedTestStep { /// ``` pub fn measurement_series_with_details( &self, - start: measurement::MeasurementSeriesStart, + start: measure::MeasurementSeriesStart, ) -> MeasurementSeries { MeasurementSeries::new_with_details(start, &self.step.emitter) } } -pub struct TestStepStart { - name: String, -} - -impl TestStepStart { - pub fn new(name: &str) -> TestStepStart { - TestStepStart { - name: name.to_string(), - } - } - - pub fn to_artifact(&self) -> spec::TestStepArtifactDescendant { - spec::TestStepArtifactDescendant::TestStepStart(spec::TestStepStart { - name: self.name.clone(), - }) - } -} - -pub struct TestStepEnd { - status: spec::TestStatus, -} - -impl TestStepEnd { - pub fn new(status: spec::TestStatus) -> TestStepEnd { - TestStepEnd { status } - } - - pub fn to_artifact(&self) -> spec::TestStepArtifactDescendant { - spec::TestStepArtifactDescendant::TestStepEnd(spec::TestStepEnd { - status: self.status.clone(), - }) - } -} - // TODO: move this away from here; extract trait Emitter, dont rely on json // it will be used in measurement series pub struct StepEmitter { @@ -545,17 +510,14 @@ pub struct StepEmitter { } impl StepEmitter { - pub async fn emit(&self, object: &spec::TestStepArtifactDescendant) -> Result<(), WriterError> { - let root = spec::RootArtifact::TestStepArtifact(spec::TestStepArtifact { + pub async fn emit(&self, object: &spec::TestStepArtifactImpl) -> Result<(), WriterError> { + let root = spec::RootImpl::TestStepArtifact(spec::TestStepArtifact { id: self.step_id.clone(), // TODO: can these copies be avoided? - descendant: object.clone(), + artifact: object.clone(), }); self.state.lock().await.emitter.emit(&root).await?; Ok(()) } } - -#[cfg(test)] -mod tests {} diff --git a/src/spec.rs b/src/spec.rs index 0161cb8..545d306 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -38,70 +38,6 @@ mod rfc3339_format { } } -#[derive(Debug, Serialize, PartialEq, Clone)] -pub enum TestRunArtifactDescendant { - #[serde(rename = "testRunStart")] - TestRunStart(TestRunStart), - - #[serde(rename = "testRunEnd")] - TestRunEnd(TestRunEnd), - - #[serde(rename = "log")] - Log(Log), - - #[serde(rename = "error")] - Error(Error), -} - -#[derive(Debug, Serialize, PartialEq, Clone)] -pub enum RootArtifact { - #[serde(rename = "schemaVersion")] - SchemaVersion(SchemaVersion), - - #[serde(rename = "testRunArtifact")] - TestRunArtifact(TestRunArtifact), - - #[serde(rename = "testStepArtifact")] - TestStepArtifact(TestStepArtifact), -} - -#[allow(clippy::large_enum_variant)] -#[derive(Debug, Serialize, PartialEq, Clone)] -pub enum TestStepArtifactDescendant { - #[serde(rename = "testStepStart")] - TestStepStart(TestStepStart), - - #[serde(rename = "testStepEnd")] - TestStepEnd(TestStepEnd), - - #[serde(rename = "measurement")] - Measurement(Measurement), - - #[serde(rename = "measurementSeriesStart")] - MeasurementSeriesStart(MeasurementSeriesStart), - - #[serde(rename = "measurementSeriesEnd")] - MeasurementSeriesEnd(MeasurementSeriesEnd), - - #[serde(rename = "measurementSeriesElement")] - MeasurementSeriesElement(MeasurementSeriesElement), - - #[serde(rename = "diagnosis")] - Diagnosis(Diagnosis), - - #[serde(rename = "log")] - Log(Log), - - #[serde(rename = "error")] - Error(Error), - - #[serde(rename = "file")] - File(File), - - #[serde(rename = "extension")] - Extension(Extension), -} - #[derive(Debug, Serialize, Clone, PartialEq)] #[non_exhaustive] pub enum ValidatorType { @@ -241,7 +177,7 @@ pub enum SoftwareType { #[derive(Debug, Serialize, Clone)] pub struct Root { #[serde(flatten)] - pub artifact: RootArtifact, + pub artifact: RootImpl, // TODO : manage different timezones #[serde(rename = "timestamp")] @@ -252,6 +188,18 @@ pub struct Root { pub seqno: u64, } +#[derive(Debug, Serialize, PartialEq, Clone)] +pub enum RootImpl { + #[serde(rename = "schemaVersion")] + SchemaVersion(SchemaVersion), + + #[serde(rename = "testRunArtifact")] + TestRunArtifact(TestRunArtifact), + + #[serde(rename = "testStepArtifact")] + TestStepArtifact(TestStepArtifact), +} + /// Low-level model for the `schemaVersion` spec object. /// Specifies the version that should be used to interpret following json outputs. /// ref: https://github.com/opencomputeproject/ocp-diag-core/tree/main/json_spec#schemaversion @@ -267,6 +215,15 @@ pub struct SchemaVersion { pub minor: i8, } +impl Default for SchemaVersion { + fn default() -> Self { + SchemaVersion { + major: SPEC_VERSION.0, + minor: SPEC_VERSION.1, + } + } +} + /// Low-level model for the `testRunArtifact` spec object. /// Container for the run level artifacts. /// ref: https://github.com/opencomputeproject/ocp-diag-core/tree/main/json_spec#test-run-artifacts @@ -275,7 +232,22 @@ pub struct SchemaVersion { #[derive(Debug, Serialize, PartialEq, Clone)] pub struct TestRunArtifact { #[serde(flatten)] - pub artifact: TestRunArtifactDescendant, + pub artifact: TestRunArtifactImpl, +} + +#[derive(Debug, Serialize, PartialEq, Clone)] +pub enum TestRunArtifactImpl { + #[serde(rename = "testRunStart")] + TestRunStart(TestRunStart), + + #[serde(rename = "testRunEnd")] + TestRunEnd(TestRunEnd), + + #[serde(rename = "log")] + Log(Log), + + #[serde(rename = "error")] + Error(Error), } /// Low-level model for the `testRunStart` spec object. @@ -498,7 +470,44 @@ pub struct TestStepArtifact { pub id: String, #[serde(flatten)] - pub descendant: TestStepArtifactDescendant, + pub artifact: TestStepArtifactImpl, +} + +#[allow(clippy::large_enum_variant)] +#[derive(Debug, Serialize, PartialEq, Clone)] +pub enum TestStepArtifactImpl { + #[serde(rename = "testStepStart")] + TestStepStart(TestStepStart), + + #[serde(rename = "testStepEnd")] + TestStepEnd(TestStepEnd), + + #[serde(rename = "measurement")] + Measurement(Measurement), + + #[serde(rename = "measurementSeriesStart")] + MeasurementSeriesStart(MeasurementSeriesStart), + + #[serde(rename = "measurementSeriesEnd")] + MeasurementSeriesEnd(MeasurementSeriesEnd), + + #[serde(rename = "measurementSeriesElement")] + MeasurementSeriesElement(MeasurementSeriesElement), + + #[serde(rename = "diagnosis")] + Diagnosis(Diagnosis), + + #[serde(rename = "log")] + Log(Log), + + #[serde(rename = "error")] + Error(Error), + + #[serde(rename = "file")] + File(File), + + #[serde(rename = "extension")] + Extension(Extension), } /// Low-level model for the `testStepStart` spec object.