use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use ironflow_store::entities::RunStatus;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubWorkflowOutput {
run_id: Uuid,
workflow_name: String,
status: RunStatus,
cost_usd: Decimal,
duration_ms: u64,
}
impl SubWorkflowOutput {
pub fn new(
run_id: Uuid,
workflow_name: &str,
status: RunStatus,
cost_usd: Decimal,
duration_ms: u64,
) -> Self {
Self {
run_id,
workflow_name: workflow_name.to_string(),
status,
cost_usd,
duration_ms,
}
}
pub fn run_id(&self) -> Uuid {
self.run_id
}
pub fn workflow_name(&self) -> &str {
&self.workflow_name
}
pub fn status(&self) -> RunStatus {
self.status
}
pub fn cost_usd(&self) -> Decimal {
self.cost_usd
}
pub fn duration_ms(&self) -> u64 {
self.duration_ms
}
}
#[cfg(test)]
mod tests {
use serde_json::{from_value, json, to_value};
use super::*;
#[test]
fn serializes_to_the_persisted_step_output() {
let run_id = Uuid::now_v7();
let output = SubWorkflowOutput::new(
run_id,
"collect",
RunStatus::Warning,
Decimal::new(25, 2),
1200,
);
assert_eq!(
to_value(&output).expect("serialize"),
json!({
"run_id": run_id,
"workflow_name": "collect",
"status": "warning",
"cost_usd": 0.25,
"duration_ms": 1200,
})
);
}
#[test]
fn a_persisted_step_output_reads_back() {
let run_id = Uuid::now_v7();
let stored = json!({
"run_id": run_id,
"workflow_name": "collect",
"status": "completed",
"cost_usd": 0,
"duration_ms": 7,
});
let output: SubWorkflowOutput = from_value(stored).expect("deserialize");
assert_eq!(output.run_id(), run_id);
assert_eq!(output.status(), RunStatus::Completed);
assert_eq!(output.cost_usd(), Decimal::ZERO);
assert_eq!(output.duration_ms(), 7);
}
#[test]
fn an_output_without_run_id_is_refused() {
let result = from_value::<SubWorkflowOutput>(json!({
"workflow_name": "collect",
"status": "completed",
"cost_usd": 0,
"duration_ms": 0,
}));
assert!(result.is_err());
}
}