use std::time::Duration;
use serde::{
Deserialize,
Serialize,
};
use super::{
ProgressCounter,
ProgressEventBuilder,
ProgressMetric,
ProgressMetricSnapshot,
ProgressPhase,
ProgressSchema,
ProgressStage,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ProgressEvent {
schema: ProgressSchema,
phase: ProgressPhase,
#[serde(skip_serializing_if = "Option::is_none")]
stage: Option<ProgressStage>,
counters: Vec<ProgressCounter>,
#[serde(with = "qubit_serde::serde::duration_with_unit")]
elapsed: Duration,
}
impl ProgressEvent {
#[inline]
pub fn builder(schema: ProgressSchema) -> ProgressEventBuilder {
ProgressEventBuilder::new(schema)
}
#[inline]
pub fn new(builder: ProgressEventBuilder) -> Self {
Self {
schema: builder.schema,
phase: builder.phase,
stage: builder.stage,
counters: builder.counters,
elapsed: builder.elapsed,
}
}
#[inline]
pub fn from_phase(
schema: ProgressSchema,
phase: ProgressPhase,
counters: Vec<ProgressCounter>,
elapsed: Duration,
) -> Self {
Self::builder(schema)
.phase(phase)
.counters(counters)
.elapsed(elapsed)
.build()
}
#[inline]
pub fn started(schema: ProgressSchema, counters: Vec<ProgressCounter>, elapsed: Duration) -> Self {
Self::from_phase(schema, ProgressPhase::Started, counters, elapsed)
}
#[inline]
pub fn running(schema: ProgressSchema, counters: Vec<ProgressCounter>, elapsed: Duration) -> Self {
Self::from_phase(schema, ProgressPhase::Running, counters, elapsed)
}
#[inline]
pub fn finished(schema: ProgressSchema, counters: Vec<ProgressCounter>, elapsed: Duration) -> Self {
Self::from_phase(schema, ProgressPhase::Finished, counters, elapsed)
}
#[inline]
pub fn failed(schema: ProgressSchema, counters: Vec<ProgressCounter>, elapsed: Duration) -> Self {
Self::from_phase(schema, ProgressPhase::Failed, counters, elapsed)
}
#[inline]
pub fn canceled(schema: ProgressSchema, counters: Vec<ProgressCounter>, elapsed: Duration) -> Self {
Self::from_phase(schema, ProgressPhase::Canceled, counters, elapsed)
}
#[inline]
#[must_use]
pub fn with_stage(mut self, stage: ProgressStage) -> Self {
self.stage = Some(stage);
self
}
#[inline]
pub const fn schema(&self) -> &ProgressSchema {
&self.schema
}
#[inline]
pub const fn phase(&self) -> ProgressPhase {
self.phase
}
#[inline]
pub const fn stage(&self) -> Option<&ProgressStage> {
self.stage.as_ref()
}
#[inline]
pub fn counters(&self) -> &[ProgressCounter] {
self.counters.as_slice()
}
#[inline]
pub fn counter(&self, metric_id: &str) -> Option<&ProgressCounter> {
self.counters.iter().find(|counter| counter.metric_id() == metric_id)
}
pub fn metric_snapshots(&self) -> Vec<ProgressMetricSnapshot> {
self.counters
.iter()
.map(|counter| {
let metric = self
.schema
.metric(counter.metric_id())
.cloned()
.unwrap_or_else(|| ProgressMetric::new(counter.metric_id(), counter.metric_id()));
ProgressMetricSnapshot::new(metric, self.phase, self.stage.clone(), counter, self.elapsed)
})
.collect()
}
#[inline]
pub const fn elapsed(&self) -> Duration {
self.elapsed
}
}