use crate::base::{Error, WorkflowIx};
use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};
#[derive(Debug)]
#[non_exhaustive]
pub enum RunStatus {
Completed,
CompletedWithErrors,
Stopped(Error),
TimedOut,
Cancelled,
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Selection {
Ran,
SkippedByCondition,
ConditionFailed(Error),
SkippedByRollout,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum WorkflowExit {
Completed,
Halted,
Failed,
Stopped,
}
#[derive(Debug)]
#[non_exhaustive]
pub struct WorkflowRecord<'r> {
pub id: &'r str,
pub index: WorkflowIx,
pub selection: &'r Selection,
pub sweeps: u32,
pub exit: Option<WorkflowExit>,
}
impl Serialize for RunStatus {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(match self {
Self::Completed => "completed",
Self::CompletedWithErrors => "completed_with_errors",
Self::Stopped(_) => "stopped",
Self::TimedOut => "timed_out",
Self::Cancelled => "cancelled",
})
}
}
impl Serialize for Selection {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(match self {
Self::Ran => "ran",
Self::SkippedByCondition => "skipped_by_condition",
Self::ConditionFailed(_) => "condition_failed",
Self::SkippedByRollout => "skipped_by_rollout",
})
}
}
impl Serialize for WorkflowExit {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(match self {
Self::Completed => "completed",
Self::Halted => "halted",
Self::Failed => "failed",
Self::Stopped => "stopped",
})
}
}
impl Serialize for WorkflowRecord<'_> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let error = match self.selection {
Selection::ConditionFailed(e) => Some(e),
_ => None,
};
let mut o = s.serialize_struct("WorkflowRecord", 6)?;
o.serialize_field("id", self.id)?;
o.serialize_field("index", &self.index)?;
o.serialize_field("selection", self.selection)?;
match error {
Some(e) => o.serialize_field("error", e)?,
None => o.skip_field("error")?,
}
o.serialize_field("sweeps", &self.sweeps)?;
o.serialize_field("exit", &self.exit)?;
o.end()
}
}
#[cfg(feature = "ts")]
crate::base::ts::ts_decl!(
RunStatus,
"RunStatus",
[" How a run ended: a stopped run's error is its `error`."],
|_cfg| crate::base::ts::literals([
"completed",
"completed_with_errors",
"stopped",
"timed_out",
"cancelled",
])
);
#[cfg(feature = "ts")]
crate::base::ts::ts_decl!(
Selection,
"Selection",
[
" Why a workflow did or did not run: a failed condition's error is its",
" record's `error`.",
],
|_cfg| crate::base::ts::literals([
"ran",
"skipped_by_condition",
"condition_failed",
"skipped_by_rollout",
])
);
#[cfg(feature = "ts")]
crate::base::ts::ts_decl!(
WorkflowExit,
"WorkflowExit",
[" How a workflow that ran ended."],
|_cfg| crate::base::ts::literals(["completed", "halted", "failed", "stopped"])
);
#[cfg(feature = "ts")]
crate::base::ts::ts_decl!(
WorkflowRecord<'_>,
"WorkflowRecord",
[" One workflow's part in a run."],
|cfg| {
use crate::base::ts::{Prop, object};
object(&[
Prop::new("id", "string", &[" The workflow's id."]),
Prop::new(
"index",
WorkflowIx::name(cfg),
&[" The workflow's position in the program."],
),
Prop::new(
"selection",
Selection::name(cfg),
&[" Whether it was selected."],
),
Prop::optional(
"error",
Error::name(cfg),
&[
" Why its condition failed to evaluate; present only when `selection` is",
" `condition_failed`.",
],
),
Prop::new(
"sweeps",
"number",
&[
" The sweeps begun: one for a workflow without a loop that ran, and for",
" a loop each sweep its condition admitted.",
],
),
Prop::new(
"exit",
Option::<WorkflowExit>::name(cfg),
&[" How it ended; `null` when it did not run."],
),
])
}
);