use crate::intelligent_behavior::rules::StateMachine;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SubScenario {
pub id: String,
pub name: String,
pub state_machine: StateMachine,
#[serde(default)]
pub input_mapping: HashMap<String, String>,
#[serde(default)]
pub output_mapping: HashMap<String, String>,
pub description: Option<String>,
}
impl SubScenario {
pub fn new(
id: impl Into<String>,
name: impl Into<String>,
state_machine: StateMachine,
) -> Self {
Self {
id: id.into(),
name: name.into(),
state_machine,
input_mapping: HashMap::new(),
output_mapping: HashMap::new(),
description: None,
}
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
pub fn with_input_mapping(
mut self,
parent_var: impl Into<String>,
sub_var: impl Into<String>,
) -> Self {
self.input_mapping.insert(parent_var.into(), sub_var.into());
self
}
pub fn with_output_mapping(
mut self,
sub_var: impl Into<String>,
parent_var: impl Into<String>,
) -> Self {
self.output_mapping.insert(sub_var.into(), parent_var.into());
self
}
pub fn state_machine(&self) -> &StateMachine {
&self.state_machine
}
pub fn state_machine_mut(&mut self) -> &mut StateMachine {
&mut self.state_machine
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::intelligent_behavior::rules::{StateMachine, StateTransition};
#[test]
fn test_sub_scenario_creation() {
let nested_machine = StateMachine::new(
"sub_resource",
vec!["start".to_string(), "end".to_string()],
"start",
);
let sub_scenario = SubScenario::new("sub1", "Test Sub-Scenario", nested_machine)
.with_description("A test sub-scenario")
.with_input_mapping("parent.status", "sub.input.status")
.with_output_mapping("sub.output.result", "parent.result");
assert_eq!(sub_scenario.id, "sub1");
assert_eq!(sub_scenario.name, "Test Sub-Scenario");
assert_eq!(sub_scenario.input_mapping.len(), 1);
assert_eq!(sub_scenario.output_mapping.len(), 1);
assert_eq!(
sub_scenario.input_mapping.get("parent.status"),
Some(&"sub.input.status".to_string())
);
}
#[test]
fn test_sub_scenario_serialization() {
let nested_machine = StateMachine::new(
"sub_resource",
vec!["start".to_string(), "end".to_string()],
"start",
)
.add_transition(StateTransition::new("start", "end"));
let sub_scenario = SubScenario::new("sub1", "Test", nested_machine)
.with_input_mapping("parent.x", "sub.x");
let json = serde_json::to_string(&sub_scenario).unwrap();
let deserialized: SubScenario = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.id, "sub1");
assert_eq!(deserialized.input_mapping.len(), 1);
}
}