smcp_server_core/
server.rs1use crate::auth::{AuthenticationProvider, DefaultAuthenticationProvider};
4use crate::handler::{ServerState, SmcpHandler};
5use crate::session::SessionManager;
6use socketioxide::layer::SocketIoLayer;
7use socketioxide::SocketIo;
8use std::sync::Arc;
9use tracing::info;
10
11#[derive(Clone)]
14pub struct SmcpServerBuilder {
15 auth_provider: Option<Arc<dyn AuthenticationProvider>>,
17 session_manager: Option<Arc<SessionManager>>,
19}
20
21impl Default for SmcpServerBuilder {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl SmcpServerBuilder {
28 pub fn new() -> Self {
31 Self {
32 auth_provider: None,
33 session_manager: None,
34 }
35 }
36
37 pub fn with_auth_provider(mut self, provider: Arc<dyn AuthenticationProvider>) -> Self {
40 self.auth_provider = Some(provider);
41 self
42 }
43
44 pub fn with_default_auth(
47 mut self,
48 admin_secret: Option<String>,
49 api_key_name: Option<String>,
50 ) -> Self {
51 let provider = Arc::new(DefaultAuthenticationProvider::new(
52 admin_secret,
53 api_key_name,
54 ));
55 self.auth_provider = Some(provider);
56 self
57 }
58
59 pub fn with_session_manager(mut self, manager: Arc<SessionManager>) -> Self {
62 self.session_manager = Some(manager);
63 self
64 }
65
66 pub fn build_layer(self) -> Result<SmcpServerLayer, crate::handler::HandlerError> {
69 let auth_provider = self
71 .auth_provider
72 .unwrap_or_else(|| Arc::new(DefaultAuthenticationProvider::new(None, None)));
73 let session_manager = self
74 .session_manager
75 .unwrap_or_else(|| Arc::new(SessionManager::new()));
76
77 let (layer, io) = SocketIo::builder().build_layer();
79
80 let state = ServerState {
82 session_manager,
83 auth_provider,
84 io: Arc::new(io.clone()),
85 };
86
87 SmcpHandler::register_handlers(&io, state.clone());
89
90 info!("SMCP Server layer built successfully");
91
92 Ok(SmcpServerLayer { io, layer, state })
93 }
94}
95
96#[derive(Clone)]
99pub struct SmcpServerLayer {
100 pub io: SocketIo,
102 pub layer: SocketIoLayer,
104 pub state: ServerState,
106}
107
108impl SmcpServerLayer {
109 pub fn socket_io(&self) -> &SocketIo {
110 &self.io
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use std::sync::Arc;
118
119 #[test]
120 fn test_server_builder() {
121 let builder = SmcpServerBuilder::new().with_default_auth(Some("test".to_string()), None);
122
123 assert!(builder.build_layer().is_ok());
124 }
125
126 #[test]
127 fn test_server_builder_with_custom_auth() {
128 let auth = Arc::new(DefaultAuthenticationProvider::new(
129 Some("test".to_string()),
130 None,
131 ));
132
133 let builder = SmcpServerBuilder::new().with_auth_provider(auth);
134 assert!(builder.build_layer().is_ok());
135 }
136
137 #[test]
138 fn test_server_builder_default_ok() {
139 let layer = SmcpServerBuilder::default().build_layer().unwrap();
140 let _io_ref = layer.socket_io();
141 }
142
143 #[test]
144 fn test_server_builder_with_session_manager_injection() {
145 let manager = Arc::new(SessionManager::new());
146 let layer = SmcpServerBuilder::new()
147 .with_session_manager(manager.clone())
148 .build_layer()
149 .unwrap();
150
151 assert!(Arc::ptr_eq(&layer.state.session_manager, &manager));
152 }
153
154 #[test]
155 fn test_socket_io_accessor_returns_inner() {
156 let layer = SmcpServerBuilder::new().build_layer().unwrap();
157 let io_ref = layer.socket_io();
158 let inner_ptr: *const SocketIo = &layer.io;
159 let accessor_ptr: *const SocketIo = io_ref;
160 assert_eq!(inner_ptr, accessor_ptr);
161 }
162}