use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ControlKind {
Pipeline,
Branch {
condition: BranchCondition,
},
Loop {
max_iterations: usize,
},
FanOut {
parallelism: usize,
},
FanIn {
strategy: MergeStrategy,
},
Race,
Retry {
max_attempts: usize,
},
Subgraph,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BranchCondition {
OnSuccess,
OnFailure,
OnGoalAchieved,
OnGoalNotAchieved,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MergeStrategy {
First,
All,
Best,
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn control_kind_should_serialize_roundtrip() {
let kinds = [
ControlKind::Pipeline,
ControlKind::Branch {
condition: BranchCondition::OnSuccess,
},
ControlKind::Loop { max_iterations: 10 },
ControlKind::FanOut { parallelism: 4 },
ControlKind::FanIn {
strategy: MergeStrategy::All,
},
ControlKind::Race,
ControlKind::Retry { max_attempts: 3 },
ControlKind::Subgraph,
];
for kind in &kinds {
let json = serde_json::to_string(kind).unwrap();
let deserialized: ControlKind = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, *kind);
}
}
#[test]
fn branch_condition_variants() {
assert_ne!(BranchCondition::OnSuccess, BranchCondition::OnFailure);
assert_ne!(
BranchCondition::OnGoalAchieved,
BranchCondition::OnGoalNotAchieved
);
}
#[test]
fn merge_strategy_variants() {
assert_ne!(MergeStrategy::First, MergeStrategy::All);
assert_ne!(MergeStrategy::All, MergeStrategy::Best);
}
}