//! Whether the agent's own harness paused its turn loop, as the agent itself //! reports it. //! //! Part of the turn-state header the agent publishes on //! `swarm_queue_client::agent_state_subject`, beside [`crate::agent_login::Login`]; //! swarm-controller decodes it out of that header with this same type. /// The hive-pause fields of an agent's turn-state header. #[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct HivePause { /// Why the harness paused its own turn loop; present only while that /// pause is in force. An operator's pause (`hivectl pause`, the /// dashboard) is not reported here, and neither is any pause by a harness /// that predates the field, so absence says nothing about `agent_state`. #[serde(default, skip_serializing_if = "Option::is_none")] pub paused_by_hive: Option, } #[cfg(test)] mod tests { use super::HivePause; #[test] fn a_header_without_the_field_decodes_as_not_paused_by_the_hive() { let header = serde_json::json!({ "agent_state": "paused", "needs_login": false }); let decoded: HivePause = serde_json::from_value(header).expect("an old header decodes"); assert_eq!(decoded.paused_by_hive, None); } #[test] fn the_reason_round_trips_and_an_absent_one_is_not_sent() { let sent = HivePause { paused_by_hive: Some("skipped get_loose_ends".to_owned()), }; let value = serde_json::to_value(&sent).expect("serialises"); assert_eq!(value["paused_by_hive"], "skipped get_loose_ends"); let decoded: HivePause = serde_json::from_value(value).expect("decodes"); assert_eq!(decoded, sent); let none = serde_json::to_value(HivePause::default()).expect("serialises"); assert!(none.as_object().expect("an object").is_empty()); } }