Skip to main content

Grove/Protocol/
mod.rs

1//! Protocol Module
2//!
3//! Handles protocol communication with Mountain and other services.
4//! Implements the Spine protocol for extension host communication.
5
6pub mod SpineConnection;
7
8// Re-exports for convenience - use module prefix to avoid E0255 conflicts
9// Note: SpineConnection must be accessed via
10// SpineConnection::SpineConnectionImpl
11
12/// Protocol version
13pub const SPINE_PROTOCOL_VERSION:&str = "1.0.0";
14
15/// Default Mountain gRPC endpoint
16pub const DEFAULT_MOUNTAIN_ENDPOINT:&str = "127.0.0.1:50050";
17
18/// Default connection timeout in milliseconds
19pub const DEFAULT_CONNECTION_TIMEOUT_MS:u64 = 5000;
20
21/// Default heartbeat interval in seconds
22pub const DEFAULT_HEARTBEAT_INTERVAL_SEC:u64 = 30;
23
24/// Default message buffer size
25pub const DEFAULT_MESSAGE_BUFFER_SIZE:usize = 8192;
26
27/// Protocol configuration
28#[derive(Debug, Clone)]
29pub struct ProtocolConfig {
30	/// Protocol version
31	pub version:String,
32	/// Mountain endpoint
33	pub mountain_endpoint:String,
34	/// Connection timeout
35	pub connection_timeout_ms:u64,
36	/// Heartbeat interval
37	pub heartbeat_interval_sec:u64,
38	/// Message buffer size
39	pub message_buffer_size:usize,
40	/// Enable TLS
41	pub enable_tls:bool,
42	/// Enable compression
43	pub enable_compression:bool,
44}
45
46impl ProtocolConfig {
47	/// Create a new protocol configuration
48	pub fn new() -> Self {
49		Self {
50			version:SPINE_PROTOCOL_VERSION.to_string(),
51			mountain_endpoint:DEFAULT_MOUNTAIN_ENDPOINT.to_string(),
52			connection_timeout_ms:DEFAULT_CONNECTION_TIMEOUT_MS,
53			heartbeat_interval_sec:DEFAULT_HEARTBEAT_INTERVAL_SEC,
54			message_buffer_size:DEFAULT_MESSAGE_BUFFER_SIZE,
55			enable_tls:false,
56			enable_compression:false,
57		}
58	}
59
60	/// Set mountain endpoint
61	pub fn with_mountain_endpoint(mut self, endpoint:String) -> Self {
62		self.mountain_endpoint = endpoint;
63		self
64	}
65
66	/// Set connection timeout
67	pub fn with_connection_timeout(mut self, timeout_ms:u64) -> Self {
68		self.connection_timeout_ms = timeout_ms;
69		self
70	}
71
72	/// Set heartbeat interval
73	pub fn with_heartbeat_interval(mut self, interval_sec:u64) -> Self {
74		self.heartbeat_interval_sec = interval_sec;
75		self
76	}
77
78	/// Enable or disable TLS
79	pub fn with_tls(mut self, enable:bool) -> Self {
80		self.enable_tls = enable;
81		self
82	}
83
84	/// Enable or disable compression
85	pub fn with_compression(mut self, enable:bool) -> Self {
86		self.enable_compression = enable;
87		self
88	}
89}
90
91impl Default for ProtocolConfig {
92	fn default() -> Self { Self::new() }
93}
94
95/// Message types for Spine protocol
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97pub enum MessageType {
98	/// Heartbeat message
99	Heartbeat = 0,
100	/// Registration message
101	Register = 1,
102	/// Unregistration message
103	Unregister = 2,
104	/// Event message
105	Event = 3,
106	/// Request message
107	Request = 4,
108	/// Response message
109	Response = 5,
110	/// Error message
111	Error = 6,
112}
113
114impl MessageType {
115	/// Convert to u32
116	pub fn as_u32(self) -> u32 { self as u32 }
117
118	/// Convert from u32
119	pub fn from_u32(value:u32) -> Option<Self> {
120		match value {
121			0 => Some(Self::Heartbeat),
122			1 => Some(Self::Register),
123			2 => Some(Self::Unregister),
124			3 => Some(Self::Event),
125			4 => Some(Self::Request),
126			5 => Some(Self::Response),
127			6 => Some(Self::Error),
128			_ => None,
129		}
130	}
131}
132
133/// Protocol error types
134#[derive(Debug, thiserror::Error)]
135pub enum ProtocolError {
136	/// Connection error
137	#[error("Connection error: {0}")]
138	ConnectionError(String),
139
140	/// Serialization error
141	#[error("Serialization error: {0}")]
142	SerializationError(String),
143
144	/// Deserialization error
145	#[error("Deserialization error: {0}")]
146	DeserializationError(String),
147
148	/// Invalid message error
149	#[error("Invalid message: {0}")]
150	InvalidMessage(String),
151
152	/// Timeout error
153	#[error("Timeout error")]
154	Timeout,
155
156	/// Protocol error
157	#[error("Protocol error: {0}")]
158	ProtocolError(String),
159}
160
161#[cfg(test)]
162mod tests {
163	use super::*;
164
165	#[test]
166	fn test_protocol_config_default() {
167		let config = ProtocolConfig::default();
168		assert_eq!(config.mountain_endpoint, DEFAULT_MOUNTAIN_ENDPOINT);
169		assert_eq!(config.connection_timeout_ms, DEFAULT_CONNECTION_TIMEOUT_MS);
170	}
171
172	#[test]
173	fn test_protocol_config_builder() {
174		let config = ProtocolConfig::default()
175			.with_mountain_endpoint("127.0.0.1:60000".to_string())
176			.with_connection_timeout(10000)
177			.with_heartbeat_interval(60);
178
179		assert_eq!(config.mountain_endpoint, "127.0.0.1:60000");
180		assert_eq!(config.connection_timeout_ms, 10000);
181		assert_eq!(config.heartbeat_interval_sec, 60);
182	}
183
184	#[test]
185	fn test_message_type_conversion() {
186		let msg_type = MessageType::Heartbeat;
187		assert_eq!(msg_type.as_u32(), 0);
188
189		let converted = MessageType::from_u32(0);
190		assert_eq!(converted, Some(MessageType::Heartbeat));
191
192		let invalid = MessageType::from_u32(999);
193		assert_eq!(invalid, None);
194	}
195}