1pub mod SpineConnection;
7
8pub const SPINE_PROTOCOL_VERSION:&str = "1.0.0";
14
15pub const DEFAULT_MOUNTAIN_ENDPOINT:&str = "127.0.0.1:50050";
17
18pub const DEFAULT_CONNECTION_TIMEOUT_MS:u64 = 5000;
20
21pub const DEFAULT_HEARTBEAT_INTERVAL_SEC:u64 = 30;
23
24pub const DEFAULT_MESSAGE_BUFFER_SIZE:usize = 8192;
26
27#[derive(Debug, Clone)]
29pub struct ProtocolConfig {
30 pub version:String,
32
33 pub mountain_endpoint:String,
35
36 pub connection_timeout_ms:u64,
38
39 pub heartbeat_interval_sec:u64,
41
42 pub message_buffer_size:usize,
44
45 pub enable_tls:bool,
47
48 pub enable_compression:bool,
50}
51
52impl ProtocolConfig {
53 pub fn new() -> Self {
55 Self {
56 version:SPINE_PROTOCOL_VERSION.to_string(),
57
58 mountain_endpoint:DEFAULT_MOUNTAIN_ENDPOINT.to_string(),
59
60 connection_timeout_ms:DEFAULT_CONNECTION_TIMEOUT_MS,
61
62 heartbeat_interval_sec:DEFAULT_HEARTBEAT_INTERVAL_SEC,
63
64 message_buffer_size:DEFAULT_MESSAGE_BUFFER_SIZE,
65
66 enable_tls:false,
67
68 enable_compression:false,
69 }
70 }
71
72 pub fn with_mountain_endpoint(mut self, endpoint:String) -> Self {
74 self.mountain_endpoint = endpoint;
75
76 self
77 }
78
79 pub fn with_connection_timeout(mut self, timeout_ms:u64) -> Self {
81 self.connection_timeout_ms = timeout_ms;
82
83 self
84 }
85
86 pub fn with_heartbeat_interval(mut self, interval_sec:u64) -> Self {
88 self.heartbeat_interval_sec = interval_sec;
89
90 self
91 }
92
93 pub fn with_tls(mut self, enable:bool) -> Self {
95 self.enable_tls = enable;
96
97 self
98 }
99
100 pub fn with_compression(mut self, enable:bool) -> Self {
102 self.enable_compression = enable;
103
104 self
105 }
106}
107
108impl Default for ProtocolConfig {
109 fn default() -> Self { Self::new() }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
114pub enum MessageType {
115 Heartbeat = 0,
117
118 Register = 1,
120
121 Unregister = 2,
123
124 Event = 3,
126
127 Request = 4,
129
130 Response = 5,
132
133 Error = 6,
135}
136
137impl MessageType {
138 pub fn as_u32(self) -> u32 { self as u32 }
140
141 pub fn from_u32(value:u32) -> Option<Self> {
143 match value {
144 0 => Some(Self::Heartbeat),
145
146 1 => Some(Self::Register),
147
148 2 => Some(Self::Unregister),
149
150 3 => Some(Self::Event),
151
152 4 => Some(Self::Request),
153
154 5 => Some(Self::Response),
155
156 6 => Some(Self::Error),
157
158 _ => None,
159 }
160 }
161}
162
163#[derive(Debug, thiserror::Error)]
165pub enum ProtocolError {
166 #[error("Connection error: {0}")]
168 ConnectionError(String),
169
170 #[error("Serialization error: {0}")]
172 SerializationError(String),
173
174 #[error("Deserialization error: {0}")]
176 DeserializationError(String),
177
178 #[error("Invalid message: {0}")]
180 InvalidMessage(String),
181
182 #[error("Timeout error")]
184 Timeout,
185
186 #[error("Protocol error: {0}")]
188 ProtocolError(String),
189}
190
191#[cfg(test)]
192mod tests {
193
194 use super::*;
195
196 #[test]
197 fn test_protocol_config_default() {
198 let config = ProtocolConfig::default();
199
200 assert_eq!(config.mountain_endpoint, DEFAULT_MOUNTAIN_ENDPOINT);
201
202 assert_eq!(config.connection_timeout_ms, DEFAULT_CONNECTION_TIMEOUT_MS);
203 }
204
205 #[test]
206 fn test_protocol_config_builder() {
207 let config = ProtocolConfig::default()
208 .with_mountain_endpoint("127.0.0.1:60000".to_string())
209 .with_connection_timeout(10000)
210 .with_heartbeat_interval(60);
211
212 assert_eq!(config.mountain_endpoint, "127.0.0.1:60000");
213
214 assert_eq!(config.connection_timeout_ms, 10000);
215
216 assert_eq!(config.heartbeat_interval_sec, 60);
217 }
218
219 #[test]
220 fn test_message_type_conversion() {
221 let msg_type = MessageType::Heartbeat;
222
223 assert_eq!(msg_type.as_u32(), 0);
224
225 let converted = MessageType::from_u32(0);
226
227 assert_eq!(converted, Some(MessageType::Heartbeat));
228
229 let invalid = MessageType::from_u32(999);
230
231 assert_eq!(invalid, None);
232 }
233}