rustant_core/gateway/
session.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use uuid::Uuid;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub enum SessionState {
11 Active,
12 Paused,
13 Ended,
14}
15
16#[derive(Debug, Clone)]
18pub struct GatewaySession {
19 pub session_id: Uuid,
20 pub state: SessionState,
21 pub created_at: DateTime<Utc>,
22 pub updated_at: DateTime<Utc>,
23 pub connection_id: Uuid,
24}
25
26#[derive(Debug, Default)]
28pub struct SessionManager {
29 sessions: HashMap<Uuid, GatewaySession>,
30}
31
32impl SessionManager {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn create_session(&mut self, connection_id: Uuid) -> Uuid {
39 let now = Utc::now();
40 let session_id = Uuid::new_v4();
41 self.sessions.insert(
42 session_id,
43 GatewaySession {
44 session_id,
45 state: SessionState::Active,
46 created_at: now,
47 updated_at: now,
48 connection_id,
49 },
50 );
51 session_id
52 }
53
54 pub fn pause_session(&mut self, session_id: &Uuid) -> bool {
56 if let Some(session) = self.sessions.get_mut(session_id)
57 && session.state == SessionState::Active
58 {
59 session.state = SessionState::Paused;
60 session.updated_at = Utc::now();
61 return true;
62 }
63 false
64 }
65
66 pub fn resume_session(&mut self, session_id: &Uuid) -> bool {
68 if let Some(session) = self.sessions.get_mut(session_id)
69 && session.state == SessionState::Paused
70 {
71 session.state = SessionState::Active;
72 session.updated_at = Utc::now();
73 return true;
74 }
75 false
76 }
77
78 pub fn end_session(&mut self, session_id: &Uuid) -> bool {
80 if let Some(session) = self.sessions.get_mut(session_id)
81 && session.state != SessionState::Ended
82 {
83 session.state = SessionState::Ended;
84 session.updated_at = Utc::now();
85 return true;
86 }
87 false
88 }
89
90 pub fn get(&self, session_id: &Uuid) -> Option<&GatewaySession> {
92 self.sessions.get(session_id)
93 }
94
95 pub fn active_count(&self) -> usize {
97 self.sessions
98 .values()
99 .filter(|s| s.state == SessionState::Active)
100 .count()
101 }
102
103 pub fn total_count(&self) -> usize {
105 self.sessions.len()
106 }
107
108 pub fn list_active(&self) -> Vec<&GatewaySession> {
110 self.sessions
111 .values()
112 .filter(|s| s.state == SessionState::Active)
113 .collect()
114 }
115
116 pub fn cleanup_ended(&mut self) -> usize {
118 let before = self.sessions.len();
119 self.sessions.retain(|_, s| s.state != SessionState::Ended);
120 before - self.sessions.len()
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_create_session() {
130 let mut mgr = SessionManager::new();
131 let conn_id = Uuid::new_v4();
132 let session_id = mgr.create_session(conn_id);
133
134 let session = mgr.get(&session_id).unwrap();
135 assert_eq!(session.state, SessionState::Active);
136 assert_eq!(session.connection_id, conn_id);
137 assert_eq!(mgr.active_count(), 1);
138 }
139
140 #[test]
141 fn test_pause_resume_session() {
142 let mut mgr = SessionManager::new();
143 let session_id = mgr.create_session(Uuid::new_v4());
144
145 assert!(mgr.pause_session(&session_id));
146 assert_eq!(mgr.get(&session_id).unwrap().state, SessionState::Paused);
147 assert_eq!(mgr.active_count(), 0);
148
149 assert!(mgr.resume_session(&session_id));
150 assert_eq!(mgr.get(&session_id).unwrap().state, SessionState::Active);
151 assert_eq!(mgr.active_count(), 1);
152 }
153
154 #[test]
155 fn test_end_session() {
156 let mut mgr = SessionManager::new();
157 let session_id = mgr.create_session(Uuid::new_v4());
158
159 assert!(mgr.end_session(&session_id));
160 assert_eq!(mgr.get(&session_id).unwrap().state, SessionState::Ended);
161 assert_eq!(mgr.active_count(), 0);
162
163 assert!(!mgr.end_session(&session_id));
165 }
166
167 #[test]
168 fn test_invalid_state_transitions() {
169 let mut mgr = SessionManager::new();
170 let session_id = mgr.create_session(Uuid::new_v4());
171
172 assert!(!mgr.resume_session(&session_id));
174
175 mgr.pause_session(&session_id);
177 assert!(!mgr.pause_session(&session_id));
178 }
179
180 #[test]
181 fn test_cleanup_ended() {
182 let mut mgr = SessionManager::new();
183 let s1 = mgr.create_session(Uuid::new_v4());
184 let _s2 = mgr.create_session(Uuid::new_v4());
185 let s3 = mgr.create_session(Uuid::new_v4());
186
187 mgr.end_session(&s1);
188 mgr.end_session(&s3);
189
190 assert_eq!(mgr.total_count(), 3);
191 let removed = mgr.cleanup_ended();
192 assert_eq!(removed, 2);
193 assert_eq!(mgr.total_count(), 1);
194 }
195
196 #[test]
197 fn test_nonexistent_session() {
198 let mut mgr = SessionManager::new();
199 let fake = Uuid::new_v4();
200 assert!(mgr.get(&fake).is_none());
201 assert!(!mgr.pause_session(&fake));
202 assert!(!mgr.resume_session(&fake));
203 assert!(!mgr.end_session(&fake));
204 }
205
206 #[test]
207 fn test_session_state_serialization() {
208 let json = serde_json::to_string(&SessionState::Active).unwrap();
209 let restored: SessionState = serde_json::from_str(&json).unwrap();
210 assert_eq!(restored, SessionState::Active);
211 }
212}