Skip to main content

CommonLibrary/Transport/Common/
mod.rs

1//! # Transport Common Types
2//!
3//! Shared types and utilities used across all transport implementations.
4
5use std::{
6	fmt,
7	time::{SystemTime, UNIX_EPOCH},
8};
9
10use serde::{Deserialize, Serialize};
11
12/// Correlation ID type.
13///
14/// Used to uniquely identify requests and match responses to requests.
15pub type CorrelationId = String;
16
17/// Timestamp type.
18///
19/// Represents time in microseconds since Unix epoch (1970-01-01 00:00:00 UTC).
20pub type Timestamp = u64;
21
22/// Generator trait for correlation IDs.
23pub trait CorrelationIdGenerator {
24	/// Generates a new unique correlation ID.
25	fn Generate() -> CorrelationId;
26}
27
28/// Default correlation ID generator using UUID v4.
29pub struct UuidCorrelationIdGenerator;
30
31impl CorrelationIdGenerator for UuidCorrelationIdGenerator {
32	fn Generate() -> CorrelationId { uuid::Uuid::new_v4().to_string() }
33}
34
35/// Generator trait for timestamps.
36pub trait TimestampGenerator {
37	/// Returns the current timestamp in microseconds since Unix epoch.
38	fn Now() -> Timestamp;
39}
40
41/// Default timestamp generator using system clock.
42pub struct SystemTimestampGenerator;
43
44impl TimestampGenerator for SystemTimestampGenerator {
45	fn Now() -> Timestamp {
46		SystemTime::now()
47			.duration_since(UNIX_EPOCH)
48			.map(|Duration| Duration.as_micros() as Timestamp)
49			.unwrap_or(0)
50	}
51}
52
53/// Transport type enumeration.
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
55pub enum TransportType {
56	/// gRPC over HTTP/2
57	Grpc,
58
59	/// Native inter-process communication (Unix sockets, named pipes)
60	Ipc,
61
62	/// WebAssembly/WebWorker transport (browser)
63	Wasm,
64
65	/// Unknown or unspecified transport
66	Unknown,
67}
68
69impl TransportType {
70	/// Returns the string representation of this transport type.
71	pub fn AsString(&self) -> &'static str {
72		match self {
73			Self::Grpc => "grpc",
74
75			Self::Ipc => "ipc",
76
77			Self::Wasm => "wasm",
78
79			Self::Unknown => "unknown",
80		}
81	}
82}
83
84impl fmt::Display for TransportType {
85	fn fmt(&self, Formatter:&mut fmt::Formatter<'_>) -> fmt::Result { Formatter.write_str(self.AsString()) }
86}
87
88impl std::str::FromStr for TransportType {
89	type Err = anyhow::Error;
90
91	fn from_str(Input:&str) -> Result<Self, Self::Err> {
92		match Input.to_lowercase().as_str() {
93			"grpc" => Ok(Self::Grpc),
94
95			"ipc" => Ok(Self::Ipc),
96
97			"wasm" => Ok(Self::Wasm),
98
99			"unknown" => Ok(Self::Unknown),
100
101			_ => Err(anyhow::anyhow!("Unknown transport type: {}", Input)),
102		}
103	}
104}
105
106/// Transport type detector.
107///
108/// Provides runtime detection of the appropriate transport based on
109/// environment and capabilities.
110pub trait TransportTypeDetector: Send + Sync {
111	/// Detects the best available transport for the current environment.
112	fn DetectBestTransport(&self) -> TransportType;
113
114	/// Checks if a specific transport is available in the current environment.
115	fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool;
116
117	/// Lists all available transports in the current environment.
118	fn ListAvailableTransports(&self) -> Vec<TransportType>;
119}
120
121/// Default transport detector using environment detection.
122pub struct DefaultTransportTypeDetector;
123
124impl DefaultTransportTypeDetector {
125	/// Lists all available transports (static convenience method).
126	pub fn list_available_transports() -> Vec<TransportType> {
127		let Instance = DefaultTransportTypeDetector;
128
129		Instance.ListAvailableTransports()
130	}
131}
132
133impl TransportTypeDetector for DefaultTransportTypeDetector {
134	fn DetectBestTransport(&self) -> TransportType {
135		#[cfg(target_arch = "wasm32")]
136		{
137			TransportType::Wasm
138		}
139
140		#[cfg(not(target_arch = "wasm32"))]
141		{
142			TransportType::Grpc
143		}
144	}
145
146	fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool {
147		match TransportKind {
148			TransportType::Grpc => true,
149
150			TransportType::Ipc => {
151				#[cfg(any(unix, windows))]
152				{
153					true
154				}
155
156				#[cfg(not(any(unix, windows)))]
157				{
158					false
159				}
160			},
161
162			TransportType::Wasm => {
163				#[cfg(target_arch = "wasm32")]
164				{
165					true
166				}
167
168				#[cfg(not(target_arch = "wasm32"))]
169				{
170					false
171				}
172			},
173
174			TransportType::Unknown => false,
175		}
176	}
177
178	fn ListAvailableTransports(&self) -> Vec<TransportType> {
179		let mut Available = Vec::new();
180
181		if self.IsTransportAvailable(TransportType::Grpc) {
182			Available.push(TransportType::Grpc);
183		}
184
185		if self.IsTransportAvailable(TransportType::Ipc) {
186			Available.push(TransportType::Ipc);
187		}
188
189		if self.IsTransportAvailable(TransportType::Wasm) {
190			Available.push(TransportType::Wasm);
191		}
192
193		Available
194	}
195}
196
197#[cfg(test)]
198mod tests {
199
200	use super::*;
201
202	#[test]
203	fn TestTransportTypeAsString() {
204		assert_eq!(TransportType::Grpc.AsString(), "grpc");
205
206		assert_eq!(TransportType::Ipc.AsString(), "ipc");
207
208		assert_eq!(TransportType::Wasm.AsString(), "wasm");
209
210		assert_eq!(TransportType::Unknown.AsString(), "unknown");
211	}
212
213	#[test]
214	fn TestTransportTypeFromString() {
215		assert_eq!("grpc".parse::<TransportType>().unwrap(), TransportType::Grpc);
216
217		assert_eq!("ipc".parse::<TransportType>().unwrap(), TransportType::Ipc);
218
219		assert_eq!("wasm".parse::<TransportType>().unwrap(), TransportType::Wasm);
220
221		assert!("invalid".parse::<TransportType>().is_err());
222	}
223
224	#[test]
225	fn TestDefaultDetector() {
226		let Available = DefaultTransportTypeDetector::list_available_transports();
227
228		assert!(Available.contains(&TransportType::Grpc));
229	}
230}