use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct JobReturnValue(serde_json::Value);
impl JobReturnValue {
pub fn into_inner(self) -> serde_json::Value {
self.0
}
pub fn as_value(&self) -> &serde_json::Value {
&self.0
}
pub fn deserialize<T: serde::de::DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
serde_json::from_value(self.0.clone())
}
pub fn try_from<T: Serialize>(value: &T) -> Result<Self, serde_json::Error> {
serde_json::to_value(value).map(Self)
}
}
#[derive(Debug, Clone)]
pub struct JobOutcome {
state: JobTerminalState,
result: Option<JobReturnValue>,
}
impl JobOutcome {
pub(crate) fn new(state: JobTerminalState, result: Option<JobReturnValue>) -> Self {
Self { state, result }
}
pub fn state(&self) -> JobTerminalState {
self.state
}
pub fn result<T: serde::de::DeserializeOwned>(&self) -> Result<Option<T>, serde_json::Error> {
match &self.result {
Some(r) => r.deserialize().map(Some),
None => Ok(None),
}
}
pub fn is_completed(&self) -> bool {
matches!(self.state, JobTerminalState::Completed)
}
pub fn is_errored(&self) -> bool {
matches!(self.state, JobTerminalState::Errored)
}
}
pub trait JobOutcomes {
fn failed_count(&self) -> usize;
fn all_succeeded(&self) -> bool;
}
impl JobOutcomes for Vec<JobOutcome> {
fn failed_count(&self) -> usize {
self.iter().filter(|r| r.is_errored()).count()
}
fn all_succeeded(&self) -> bool {
self.iter().all(|r| r.is_completed())
}
}
impl JobOutcomes for [JobOutcome] {
fn failed_count(&self) -> usize {
self.iter().filter(|r| r.is_errored()).count()
}
fn all_succeeded(&self) -> bool {
self.iter().all(|r| r.is_completed())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum JobTerminalState {
Completed,
Errored,
}