use crate::{ActorId, RunEventId, RunId};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RunState {
Working,
Waiting,
Failed,
Interrupted,
Completed,
}
impl RunState {
#[must_use]
pub fn is_terminal(self) -> bool {
matches!(self, Self::Failed | Self::Interrupted | Self::Completed)
}
#[must_use]
pub fn word(self) -> &'static str {
match self {
Self::Working => "working",
Self::Waiting => "waiting",
Self::Failed => "failed",
Self::Interrupted => "interrupted",
Self::Completed => "completed",
}
}
}
impl std::fmt::Display for RunState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.word())
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("unknown run state {0:?}; expected working, waiting, failed, interrupted or completed")]
pub struct RunStateParseError(String);
impl FromStr for RunState {
type Err = RunStateParseError;
fn from_str(word: &str) -> Result<Self, Self::Err> {
[
Self::Working,
Self::Waiting,
Self::Failed,
Self::Interrupted,
Self::Completed,
]
.into_iter()
.find(|state| state.word() == word)
.ok_or_else(|| RunStateParseError(word.into()))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct RunTransition {
pub id: RunEventId,
pub run: RunId,
pub to: RunState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub observed_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LifecycleEvent {
pub id: RunEventId,
pub run: RunId,
pub state: RunState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub observed_at: Option<DateTime<Utc>>,
pub recorded_by: ActorId,
pub recorded_at: DateTime<Utc>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LifecycleEntry {
pub sequence: u64,
#[serde(flatten)]
pub event: LifecycleEvent,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LifecyclePage {
pub entries: Vec<LifecycleEntry>,
pub next_after_sequence: u64,
pub head_sequence: u64,
}