CommonLibrary/Transport/Common/
mod.rs1use std::{
6 fmt,
7 time::{SystemTime, UNIX_EPOCH},
8};
9
10use serde::{Deserialize, Serialize};
11
12pub type CorrelationId = String;
16
17pub type Timestamp = u64;
21
22pub trait CorrelationIdGenerator {
24 fn Generate() -> CorrelationId;
26}
27
28pub struct UuidCorrelationIdGenerator;
30
31impl CorrelationIdGenerator for UuidCorrelationIdGenerator {
32 fn Generate() -> CorrelationId { uuid::Uuid::new_v4().to_string() }
33}
34
35pub trait TimestampGenerator {
37 fn Now() -> Timestamp;
39}
40
41pub 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#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
55pub enum TransportType {
56 Grpc,
58
59 Ipc,
61
62 Wasm,
64
65 Unknown,
67}
68
69impl TransportType {
70 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
106pub trait TransportTypeDetector: Send + Sync {
111 fn DetectBestTransport(&self) -> TransportType;
113
114 fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool;
116
117 fn ListAvailableTransports(&self) -> Vec<TransportType>;
119}
120
121pub struct DefaultTransportTypeDetector;
123
124impl DefaultTransportTypeDetector {
125 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}