Skip to content

Commit b93d5a9

Browse files
1 parent b6525f4 commit b93d5a9

11 files changed

Lines changed: 2087 additions & 6 deletions

File tree

Cargo.toml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,25 @@ toml = { workspace = true }
44

55
[dependencies]
66
tauri = { workspace = true, features = [
7-
"wry",
8-
"tray-icon",
9-
"devtools",
10-
"rustls-tls",
11-
"compression",
12-
], default-features = false }
7+
"wry",
8+
"tray-icon",
9+
"devtools",
10+
"rustls-tls",
11+
"compression",
12+
], default-features = false }
1313

1414
async-trait = { workspace = true }
1515
serde = { workspace = true }
1616
serde_json = { workspace = true }
1717
thiserror = { workspace = true }
1818
url = { workspace = true }
1919

20+
# Transport-specific dependencies
21+
uuid = { workspace = true }
22+
futures = { workspace = true }
23+
anyhow = { workspace = true }
24+
prometheus = { workspace = true }
25+
2026
[features]
2127
default = []
2228

Source/Library.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ pub mod Webview;
7171

7272
pub mod Workspace;
7373

74+
// --- Transport Layer ---
75+
// Provides transport-agnostic communication abstractions (gRPC, IPC, WASM)
76+
pub mod Transport;
77+
7478
// --- Global DTO Module ---
7579
//
7680
// A top-level module that re-exports all Data Transfer Objects (DTOs) from the

Source/Transport/Common/mod.rs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
//! # Transport Common Types
2+
//!
3+
//! Shared types and utilities used across all transport implementations.
4+
//!
5+
//! This module provides:
6+
//!
7+
//! - [`CorrelationId`] - UUID type for request correlation
8+
//! - [`Timestamp`] - Microsecond timestamp type
9+
//! - [`TransportType`] - Transport kind enumeration
10+
//! - [`TransportTypeDetector`] - Runtime transport detection
11+
//! - [`CorrelationIdGenerator`] - Trait for generating correlation IDs
12+
//! - [`TimestampGenerator`] - Trait for getting current timestamps
13+
14+
use serde::{Deserialize, Serialize};
15+
use std::fmt;
16+
use std::time::{SystemTime, UNIX_EPOCH};
17+
18+
/// Correlation ID type.
19+
///
20+
/// Used to uniquely identify requests and match responses to requests.
21+
pub type CorrelationId = String;
22+
23+
/// Timestamp type.
24+
///
25+
/// Represents time in microseconds since Unix epoch (1970-01-01 00:00:00 UTC).
26+
pub type Timestamp = u64;
27+
28+
/// Generator trait for correlation IDs.
29+
///
30+
/// This allows different ID generation strategies (UUID, sequential, etc.)
31+
/// to be injected for testing or special requirements.
32+
pub trait CorrelationIdGenerator {
33+
/// Generates a new unique correlation ID.
34+
fn generate() -> CorrelationId;
35+
}
36+
37+
/// Default correlation ID generator using UUID v4.
38+
pub struct UuidCorrelationIdGenerator;
39+
40+
impl CorrelationIdGenerator for UuidCorrelationIdGenerator {
41+
fn generate() -> CorrelationId {
42+
uuid::Uuid::new_v4().to_string()
43+
}
44+
}
45+
46+
/// Generator trait for timestamps.
47+
///
48+
/// Allows time to be injected for testing (mock clocks) or obtained
49+
/// from system clocks.
50+
pub trait TimestampGenerator {
51+
/// Returns the current timestamp in microseconds since Unix epoch.
52+
fn now() -> Timestamp;
53+
}
54+
55+
/// Default timestamp generator using system clock.
56+
pub struct SystemTimestampGenerator;
57+
58+
impl TimestampGenerator for SystemTimestampGenerator {
59+
fn now() -> Timestamp {
60+
SystemTime::now()
61+
.duration_since(UNIX_EPOCH)
62+
.map(|d| d.as_micros() as Timestamp)
63+
.unwrap_or(0)
64+
}
65+
}
66+
67+
/// Transport type enumeration.
68+
///
69+
/// Indicates which transport mechanism is being used or requested.
70+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
71+
pub enum TransportType {
72+
/// gRPC over HTTP/2
73+
Grpc,
74+
/// Native inter-process communication (Unix sockets, named pipes)
75+
Ipc,
76+
/// WebAssembly/WebWorker transport (browser)
77+
Wasm,
78+
/// Unknown or unspecified transport
79+
Unknown,
80+
}
81+
82+
impl TransportType {
83+
/// Returns the string representation of this transport type.
84+
pub fn as_str(&self) -> &'static str {
85+
match self {
86+
Self::Grpc => "grpc",
87+
Self::Ipc => "ipc",
88+
Self::Wasm => "wasm",
89+
Self::Unknown => "unknown",
90+
}
91+
}
92+
}
93+
94+
impl fmt::Display for TransportType {
95+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96+
f.write_str(self.as_str())
97+
}
98+
}
99+
100+
impl std::str::FromStr for TransportType {
101+
type Err = anyhow::Error;
102+
103+
fn from_str(s: &str) -> Result<Self, Self::Err> {
104+
match s.to_lowercase().as_str() {
105+
"grpc" => Ok(Self::Grpc),
106+
"ipc" => Ok(Self::Ipc),
107+
"wasm" => Ok(Self::Wasm),
108+
"unknown" => Ok(Self::Unknown),
109+
_ => Err(anyhow::anyhow!("Unknown transport type: {}", s)),
110+
}
111+
}
112+
}
113+
114+
/// Transport type detector.
115+
///
116+
/// Provides runtime detection of the appropriate transport based on
117+
/// environment and capabilities.
118+
pub trait TransportTypeDetector {
119+
/// Detects the best available transport for the current environment.
120+
fn detect_best_transport() -> TransportType;
121+
122+
/// Checks if a specific transport is available in the current environment.
123+
fn is_transport_available(transport_type: TransportType) -> bool;
124+
125+
/// Lists all available transports in the current environment.
126+
fn list_available_transports() -> Vec<TransportType>;
127+
}
128+
129+
/// Default transport detector using environment detection.
130+
pub struct DefaultTransportTypeDetector;
131+
132+
impl TransportTypeDetector for DefaultTransportTypeDetector {
133+
fn detect_best_transport() -> TransportType {
134+
// Priority order based on environment:
135+
// - If in browser and WASM supported: WASM
136+
// - If same-process and IPC available: IPC
137+
// - Otherwise: gRPC
138+
139+
#[cfg(target_arch = "wasm32")]
140+
{
141+
// In browser, prefer WASM
142+
TransportType::Wasm
143+
}
144+
145+
#[cfg(not(target_arch = "wasm32"))]
146+
{
147+
// On desktop/server, check if we're in same process
148+
// For now, default to gRPC (cross-process)
149+
TransportType::Grpc
150+
}
151+
}
152+
153+
fn is_transport_available(transport_type: TransportType) -> bool {
154+
match transport_type {
155+
TransportType::Grpc => true, // gRPC always available
156+
TransportType::Ipc => {
157+
#[cfg(unix)]
158+
{
159+
true // Unix sockets available
160+
}
161+
#[cfg(windows)]
162+
{
163+
true // Named pipes available
164+
}
165+
}
166+
TransportType::Wasm => {
167+
#[cfg(target_arch = "wasm32")]
168+
{
169+
true
170+
}
171+
#[cfg(not(target_arch = "wasm32"))]
172+
{
173+
false // WASM not available outside browser
174+
}
175+
}
176+
TransportType::Unknown => false,
177+
}
178+
}
179+
180+
fn list_available_transports() -> Vec<TransportType> {
181+
let mut available = Vec::new();
182+
183+
if Self::is_transport_available(TransportType::Grpc) {
184+
available.push(TransportType::Grpc);
185+
}
186+
if Self::is_transport_available(TransportType::Ipc) {
187+
available.push(TransportType::Ipc);
188+
}
189+
if Self::is_transport_available(TransportType::Wasm) {
190+
available.push(TransportType::Wasm);
191+
}
192+
193+
available
194+
}
195+
}
196+
197+
#[cfg(test)]
198+
mod tests {
199+
use super::*;
200+
201+
#[test]
202+
fn test_transport_type_as_str() {
203+
assert_eq!(TransportType::Grpc.as_str(), "grpc");
204+
assert_eq!(TransportType::Ipc.as_str(), "ipc");
205+
assert_eq!(TransportType::Wasm.as_str(), "wasm");
206+
assert_eq!(TransportType::Unknown.as_str(), "unknown");
207+
}
208+
209+
#[test]
210+
fn test_transport_type_from_str() {
211+
assert_eq!("grpc".parse().unwrap(), TransportType::Grpc);
212+
assert_eq!("ipc".parse().unwrap(), TransportType::Ipc);
213+
assert_eq!("wasm".parse().unwrap(), TransportType::Wasm);
214+
assert!("invalid".parse::<TransportType>().is_err());
215+
}
216+
217+
#[test]
218+
fn test_default_detector() {
219+
let available = DefaultTransportTypeDetector::list_available_transports();
220+
// At minimum gRPC should be available
221+
assert!(available.contains(&TransportType::Grpc));
222+
}
223+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//! Correlation ID types and utilities.
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
/// Correlation ID type.
6+
///
7+
/// Used to uniquely identify requests and match responses to requests.
8+
pub type CorrelationId = String;
9+
10+
/// Trait for generating correlation IDs.
11+
///
12+
/// This allows different ID generation strategies (UUID, sequential, etc.)
13+
/// for testing or special requirements.
14+
pub trait CorrelationIdGenerator {
15+
/// Generates a new unique correlation ID.
16+
fn generate() -> CorrelationId;
17+
}
18+
19+
/// UUID-based correlation ID generator.
20+
pub struct UuidCorrelationIdGenerator;
21+
22+
impl CorrelationIdGenerator for UuidCorrelationIdGenerator {
23+
fn generate() -> CorrelationId {
24+
uuid::Uuid::new_v4().to_string()
25+
}
26+
}
27+
28+
#[cfg(test)]
29+
mod tests {
30+
use super::*;
31+
32+
#[test]
33+
fn test_correlation_id_generation() {
34+
let id1 = UuidCorrelationIdGenerator::generate();
35+
let id2 = UuidCorrelationIdGenerator::generate();
36+
assert!(!id1.is_empty());
37+
assert!(!id2.is_empty());
38+
assert_ne!(id1, id2); // Should be unique
39+
}
40+
}

Source/Transport/DTO/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! # Transport DTOs
2+
//!
3+
//! Data Transfer Objects used by the transport layer.
4+
//!
5+
//! This module re-exports all DTOs defined in the transport system, providing
6+
//! a single import location for all transport-related types.
7+
8+
// Core DTOs
9+
pub mod unified_request;
10+
pub mod unified_response;
11+
pub mod transport_error;
12+
pub mod correlation;
13+
14+
// Re-exports
15+
pub use unified_request::UnifiedRequest;
16+
pub use unified_response::{UnifiedResponse, ResponseError};
17+
pub use transport_error::{TransportError, TransportErrorCode};
18+
pub use correlation::{CorrelationId, CorrelationIdGenerator};

0 commit comments

Comments
 (0)