switchyard_libsy/core/
state.rs1use std::collections::BTreeMap;
7
8use serde::{Deserialize, Serialize};
9
10use crate::algorithms::util::tool_signals::ToolSignals;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14#[serde(rename_all = "snake_case")]
15pub enum StateValue {
16 String(String),
18 Count(u32),
20 Bool(bool),
22}
23
24#[derive(Debug, Clone, Default, Serialize, Deserialize)]
26pub struct State {
27 #[serde(skip)]
31 pub tool_signals: Option<ToolSignals>,
32 #[serde(flatten)]
34 pub extra: BTreeMap<String, StateValue>,
35}
36
37impl PartialEq for State {
38 fn eq(&self, other: &Self) -> bool {
39 self.extra == other.extra
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn state_round_trips_through_json_and_compares_extra_only() -> serde_json::Result<()> {
49 let mut state = State::default();
50 state
51 .extra
52 .insert("capable_hold_turns".to_string(), StateValue::Count(2));
53 state.extra.insert(
54 "fall_open".to_string(),
55 StateValue::String("capable".to_string()),
56 );
57 state
58 .extra
59 .insert("vgr_handoff_sent".to_string(), StateValue::Bool(true));
60 let json = serde_json::json!({
61 "capable_hold_turns": {"count": 2},
62 "fall_open": {"string": "capable"},
63 "vgr_handoff_sent": {"bool": true},
64 });
65
66 let with_signals = State {
67 tool_signals: Some(ToolSignals::default()),
68 ..state.clone()
69 };
70 assert_eq!(serde_json::to_value(&with_signals)?, json);
71 assert_eq!(serde_json::from_value::<State>(json)?, state);
72 assert_eq!(with_signals, state);
73 Ok(())
74 }
75}