CommonLibrary/Transport/Common/
mod.rs1#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
2use std::{
7 fmt,
8 time::{SystemTime, UNIX_EPOCH},
9};
10
11use serde::{Deserialize, Serialize};
12
13pub type CorrelationId = String;
17
18pub type Timestamp = u64;
22
23pub trait CorrelationIdGenerator {
25 fn Generate() -> CorrelationId;
27}
28
29pub struct UuidCorrelationIdGenerator;
31
32impl CorrelationIdGenerator for UuidCorrelationIdGenerator {
33 fn Generate() -> CorrelationId { uuid::Uuid::new_v4().to_string() }
34}
35
36pub trait TimestampGenerator {
38 fn Now() -> Timestamp;
40}
41
42pub struct SystemTimestampGenerator;
44
45impl TimestampGenerator for SystemTimestampGenerator {
46 fn Now() -> Timestamp {
47 SystemTime::now()
48 .duration_since(UNIX_EPOCH)
49 .map(|Duration| Duration.as_micros() as Timestamp)
50 .unwrap_or(0)
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
56pub enum TransportType {
57 Grpc,
59
60 Ipc,
62
63 Wasm,
65
66 Unknown,
68}
69
70impl TransportType {
71 pub fn AsString(&self) -> &'static str {
73 match self {
74 Self::Grpc => "grpc",
75
76 Self::Ipc => "ipc",
77
78 Self::Wasm => "wasm",
79
80 Self::Unknown => "unknown",
81 }
82 }
83}
84
85impl fmt::Display for TransportType {
86 fn fmt(&self, Formatter:&mut fmt::Formatter<'_>) -> fmt::Result { Formatter.write_str(self.AsString()) }
87}
88
89impl std::str::FromStr for TransportType {
90 type Err = anyhow::Error;
91
92 fn from_str(Input:&str) -> Result<Self, Self::Err> {
93 match Input.to_lowercase().as_str() {
94 "grpc" => Ok(Self::Grpc),
95
96 "ipc" => Ok(Self::Ipc),
97
98 "wasm" => Ok(Self::Wasm),
99
100 "unknown" => Ok(Self::Unknown),
101
102 _ => Err(anyhow::anyhow!("Unknown transport type: {}", Input)),
103 }
104 }
105}
106
107pub trait TransportTypeDetector: Send + Sync {
112 fn DetectBestTransport(&self) -> TransportType;
114
115 fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool;
117
118 fn ListAvailableTransports(&self) -> Vec<TransportType>;
120}
121
122pub struct DefaultTransportTypeDetector;
124
125impl DefaultTransportTypeDetector {
126 pub fn list_available_transports() -> Vec<TransportType> {
128 let Instance = DefaultTransportTypeDetector;
129
130 Instance.ListAvailableTransports()
131 }
132}
133
134impl TransportTypeDetector for DefaultTransportTypeDetector {
135 fn DetectBestTransport(&self) -> TransportType {
136 #[cfg(target_arch = "wasm32")]
137 {
138 TransportType::Wasm
139 }
140
141 #[cfg(not(target_arch = "wasm32"))]
142 {
143 TransportType::Grpc
144 }
145 }
146
147 fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool {
148 match TransportKind {
149 TransportType::Grpc => true,
150
151 TransportType::Ipc => {
152 #[cfg(any(unix, windows))]
153 {
154 true
155 }
156
157 #[cfg(not(any(unix, windows)))]
158 {
159 false
160 }
161 },
162
163 TransportType::Wasm => {
164 #[cfg(target_arch = "wasm32")]
165 {
166 true
167 }
168
169 #[cfg(not(target_arch = "wasm32"))]
170 {
171 false
172 }
173 },
174
175 TransportType::Unknown => false,
176 }
177 }
178
179 fn ListAvailableTransports(&self) -> Vec<TransportType> {
180 let mut Available = Vec::new();
181
182 if self.IsTransportAvailable(TransportType::Grpc) {
183 Available.push(TransportType::Grpc);
184 }
185
186 if self.IsTransportAvailable(TransportType::Ipc) {
187 Available.push(TransportType::Ipc);
188 }
189
190 if self.IsTransportAvailable(TransportType::Wasm) {
191 Available.push(TransportType::Wasm);
192 }
193
194 Available
195 }
196}
197
198#[cfg(test)]
199mod tests {
200
201 use super::*;
202
203 #[test]
204 fn TestTransportTypeAsString() {
205 assert_eq!(TransportType::Grpc.AsString(), "grpc");
206
207 assert_eq!(TransportType::Ipc.AsString(), "ipc");
208
209 assert_eq!(TransportType::Wasm.AsString(), "wasm");
210
211 assert_eq!(TransportType::Unknown.AsString(), "unknown");
212 }
213
214 #[test]
215 fn TestTransportTypeFromString() {
216 assert_eq!("grpc".parse::<TransportType>().unwrap(), TransportType::Grpc);
217
218 assert_eq!("ipc".parse::<TransportType>().unwrap(), TransportType::Ipc);
219
220 assert_eq!("wasm".parse::<TransportType>().unwrap(), TransportType::Wasm);
221
222 assert!("invalid".parse::<TransportType>().is_err());
223 }
224
225 #[test]
226 fn TestDefaultDetector() {
227 let Available = DefaultTransportTypeDetector::list_available_transports();
228
229 assert!(Available.contains(&TransportType::Grpc));
230 }
231}