use std::ops::Not;
use ironflow_core::retry::RetryPolicy;
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowStepConfig {
pub workflow_name: String,
pub payload: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub retry: Option<RetryPolicy>,
#[serde(default, skip_serializing_if = "Not::not")]
pub allow_failure: bool,
}
impl WorkflowStepConfig {
pub fn new(workflow_name: &str, payload: Value) -> Self {
Self {
workflow_name: workflow_name.to_string(),
payload,
retry: None,
allow_failure: false,
}
}
pub fn retry_policy(mut self, policy: RetryPolicy) -> Self {
self.retry = Some(policy);
self
}
pub fn allow_failure(mut self) -> Self {
self.allow_failure = true;
self
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct WorkflowOptions {
pub allow_failure: bool,
}
impl WorkflowOptions {
pub fn new() -> Self {
Self::default()
}
pub fn allow_failure(mut self) -> Self {
self.allow_failure = true;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn new_sets_fields() {
let config = WorkflowStepConfig::new("build", json!({"key": "val"}));
assert_eq!(config.workflow_name, "build");
assert_eq!(config.payload["key"], "val");
}
#[test]
fn serde_roundtrip() {
let config = WorkflowStepConfig::new("deploy", json!({"env": "prod"}));
let json = serde_json::to_string(&config).unwrap();
let back: WorkflowStepConfig = serde_json::from_str(&json).unwrap();
assert_eq!(back.workflow_name, "deploy");
assert_eq!(back.payload["env"], "prod");
}
#[test]
fn a_config_predating_retry_still_deserializes() {
let config: WorkflowStepConfig =
serde_json::from_str(r#"{"workflow_name":"build","payload":{"key":"val"}}"#)
.expect("deserialize");
assert!(config.retry.is_none());
}
#[test]
fn allow_failure_defaults_to_false() {
let config = WorkflowStepConfig::new("build", json!({}));
assert!(!config.allow_failure);
}
#[test]
fn allow_failure_is_omitted_from_json_when_false() {
let config = WorkflowStepConfig::new("build", json!({}));
let value = serde_json::to_value(&config).expect("serialize");
assert!(value.get("allow_failure").is_none());
}
#[test]
fn allow_failure_roundtrip() {
let config = WorkflowStepConfig::new("build", json!({})).allow_failure();
let json = serde_json::to_string(&config).expect("serialize");
let back: WorkflowStepConfig = serde_json::from_str(&json).expect("deserialize");
assert!(back.allow_failure);
}
#[test]
fn options_builder_sets_allow_failure() {
assert!(!WorkflowOptions::new().allow_failure);
assert!(WorkflowOptions::new().allow_failure().allow_failure);
}
#[test]
fn retry_policy_roundtrip() {
let config = WorkflowStepConfig::new("deploy", json!({})).retry_policy(RetryPolicy::new(3));
let json = serde_json::to_string(&config).expect("serialize");
let back: WorkflowStepConfig = serde_json::from_str(&json).expect("deserialize");
assert_eq!(back.retry.as_ref().unwrap().max_retries(), 3);
}
}