use serde::{Deserialize, Serialize};
use crate::InstanceId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum ControlRole {
#[default]
Neutral,
Controller,
Controllee,
}
impl ControlRole {
pub fn can_command(&self) -> bool {
matches!(self, ControlRole::Controller)
}
pub fn responds_to_commands(&self) -> bool {
matches!(self, ControlRole::Controllee)
}
pub fn is_neutral(&self) -> bool {
matches!(self, ControlRole::Neutral)
}
pub fn opposite(&self) -> ControlRole {
match self {
ControlRole::Controller => ControlRole::Controllee,
ControlRole::Controllee => ControlRole::Controller,
ControlRole::Neutral => ControlRole::Neutral,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum AttachmentState {
#[default]
Unattached,
Attached { peer: InstanceId },
}
impl AttachmentState {
pub fn is_attached(&self) -> bool {
matches!(self, AttachmentState::Attached { .. })
}
pub fn peer(&self) -> Option<InstanceId> {
match self {
AttachmentState::Attached { peer } => Some(*peer),
AttachmentState::Unattached => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum SessionPhase {
#[default]
Searching,
Holding,
Staging,
Ready,
Complete,
Failed,
}
impl SessionPhase {
pub fn is_terminal(&self) -> bool {
matches!(self, SessionPhase::Complete | SessionPhase::Failed)
}
pub fn is_active(&self) -> bool {
!self.is_terminal()
}
pub fn is_ready(&self) -> bool {
matches!(self, SessionPhase::Ready)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_control_role_transitions() {
let role = ControlRole::Neutral;
assert!(role.is_neutral());
assert!(!role.can_command());
assert!(!role.responds_to_commands());
let role = ControlRole::Controller;
assert!(!role.is_neutral());
assert!(role.can_command());
assert!(!role.responds_to_commands());
let role = ControlRole::Controllee;
assert!(!role.is_neutral());
assert!(!role.can_command());
assert!(role.responds_to_commands());
}
#[test]
fn test_attachment_state() {
let state = AttachmentState::Unattached;
assert!(!state.is_attached());
assert!(state.peer().is_none());
let peer_id = InstanceId::new_v4();
let state = AttachmentState::Attached { peer: peer_id };
assert!(state.is_attached());
assert_eq!(state.peer(), Some(peer_id));
}
#[test]
fn test_session_phase() {
assert!(!SessionPhase::Searching.is_terminal());
assert!(!SessionPhase::Holding.is_terminal());
assert!(!SessionPhase::Staging.is_terminal());
assert!(!SessionPhase::Ready.is_terminal());
assert!(SessionPhase::Complete.is_terminal());
assert!(SessionPhase::Failed.is_terminal());
assert!(SessionPhase::Ready.is_ready());
assert!(!SessionPhase::Staging.is_ready());
}
}