Skip to main content

netget/state/
easy.rs

1//! Easy protocol instance management
2
3use crate::utils::clock::Instant;
4use tokio::task::JoinHandle;
5
6use super::client::ClientId;
7use super::server::ServerId;
8
9/// Unique identifier for an easy protocol instance
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct EasyId(u32);
12
13impl EasyId {
14    /// Create a new easy ID from a u32
15    pub fn new(id: u32) -> Self {
16        Self(id)
17    }
18
19    /// Get the raw ID value
20    pub fn as_u32(&self) -> u32 {
21        self.0
22    }
23
24    /// Parse from string (expects format "easy-123" or just "123")
25    pub fn from_string(s: &str) -> Option<Self> {
26        let s = s.trim();
27        let id_str = s.strip_prefix("easy-").unwrap_or(s);
28        id_str.parse::<u32>().ok().map(Self)
29    }
30}
31
32impl std::fmt::Display for EasyId {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        write!(f, "easy-{}", self.0)
35    }
36}
37
38/// Status of an easy protocol instance
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum EasyStatus {
41    /// Easy protocol is starting up (creating underlying server/client)
42    Starting,
43    /// Easy protocol is running (underlying server/client active)
44    Running,
45    /// Easy protocol has been stopped
46    Stopped,
47    /// Easy protocol encountered an error
48    Error(String),
49}
50
51impl EasyStatus {
52    pub fn as_str(&self) -> &str {
53        match self {
54            Self::Starting => "Starting",
55            Self::Running => "Running",
56            Self::Stopped => "Stopped",
57            Self::Error(_) => "Error",
58        }
59    }
60}
61
62impl std::fmt::Display for EasyStatus {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        match self {
65            Self::Starting => write!(f, "Starting"),
66            Self::Running => write!(f, "Running"),
67            Self::Stopped => write!(f, "Stopped"),
68            Self::Error(msg) => write!(f, "Error: {}", msg),
69        }
70    }
71}
72
73/// An easy protocol instance that wraps an underlying server or client
74#[derive(Debug)]
75pub struct EasyInstance {
76    /// Unique easy protocol ID
77    pub id: EasyId,
78    /// Easy protocol name (e.g., "http-easy")
79    pub protocol_name: String,
80    /// Underlying protocol name (e.g., "http")
81    pub underlying_protocol: String,
82    /// Optional user instruction for this easy instance
83    pub user_instruction: Option<String>,
84    /// Underlying server ID (if this easy protocol wraps a server)
85    pub underlying_server_id: Option<ServerId>,
86    /// Underlying client ID (if this easy protocol wraps a client)
87    pub underlying_client_id: Option<ClientId>,
88    /// Easy protocol status
89    pub status: EasyStatus,
90    /// When the easy protocol was created
91    pub created_at: Instant,
92    /// When the status last changed
93    pub status_changed_at: Instant,
94    /// Task handle for cleanup (if needed)
95    pub handle: Option<JoinHandle<()>>,
96}
97
98impl EasyInstance {
99    /// Create a new easy protocol instance
100    pub fn new(
101        id: EasyId,
102        protocol_name: String,
103        underlying_protocol: String,
104        user_instruction: Option<String>,
105    ) -> Self {
106        let now = Instant::now();
107        Self {
108            id,
109            protocol_name,
110            underlying_protocol,
111            user_instruction,
112            underlying_server_id: None,
113            underlying_client_id: None,
114            status: EasyStatus::Starting,
115            created_at: now,
116            status_changed_at: now,
117            handle: None,
118        }
119    }
120
121    /// Set underlying server ID
122    pub fn set_underlying_server(&mut self, server_id: ServerId) {
123        self.underlying_server_id = Some(server_id);
124    }
125
126    /// Set underlying client ID
127    pub fn set_underlying_client(&mut self, client_id: ClientId) {
128        self.underlying_client_id = Some(client_id);
129    }
130
131    /// Update status
132    pub fn set_status(&mut self, status: EasyStatus) {
133        self.status = status;
134        self.status_changed_at = Instant::now();
135    }
136}