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 Ipc,
61 Wasm,
63 Unknown,
65}
66
67impl TransportType {
68 pub fn AsString(&self) -> &'static str {
70 match self {
71 Self::Grpc => "grpc",
72 Self::Ipc => "ipc",
73 Self::Wasm => "wasm",
74 Self::Unknown => "unknown",
75 }
76 }
77}
78
79impl fmt::Display for TransportType {
80 fn fmt(&self, Formatter:&mut fmt::Formatter<'_>) -> fmt::Result { Formatter.write_str(self.AsString()) }
81}
82
83impl std::str::FromStr for TransportType {
84 type Err = anyhow::Error;
85
86 fn from_str(Input:&str) -> Result<Self, Self::Err> {
87 match Input.to_lowercase().as_str() {
88 "grpc" => Ok(Self::Grpc),
89 "ipc" => Ok(Self::Ipc),
90 "wasm" => Ok(Self::Wasm),
91 "unknown" => Ok(Self::Unknown),
92 _ => Err(anyhow::anyhow!("Unknown transport type: {}", Input)),
93 }
94 }
95}
96
97pub trait TransportTypeDetector: Send + Sync {
102 fn DetectBestTransport(&self) -> TransportType;
104
105 fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool;
107
108 fn ListAvailableTransports(&self) -> Vec<TransportType>;
110}
111
112pub struct DefaultTransportTypeDetector;
114
115impl DefaultTransportTypeDetector {
116 pub fn list_available_transports() -> Vec<TransportType> {
118 let Instance = DefaultTransportTypeDetector;
119 Instance.ListAvailableTransports()
120 }
121}
122
123impl TransportTypeDetector for DefaultTransportTypeDetector {
124 fn DetectBestTransport(&self) -> TransportType {
125 #[cfg(target_arch = "wasm32")]
126 {
127 TransportType::Wasm
128 }
129
130 #[cfg(not(target_arch = "wasm32"))]
131 {
132 TransportType::Grpc
133 }
134 }
135
136 fn IsTransportAvailable(&self, TransportKind:TransportType) -> bool {
137 match TransportKind {
138 TransportType::Grpc => true,
139 TransportType::Ipc => {
140 #[cfg(any(unix, windows))]
141 {
142 true
143 }
144 #[cfg(not(any(unix, windows)))]
145 {
146 false
147 }
148 },
149 TransportType::Wasm => {
150 #[cfg(target_arch = "wasm32")]
151 {
152 true
153 }
154 #[cfg(not(target_arch = "wasm32"))]
155 {
156 false
157 }
158 },
159 TransportType::Unknown => false,
160 }
161 }
162
163 fn ListAvailableTransports(&self) -> Vec<TransportType> {
164 let mut Available = Vec::new();
165
166 if self.IsTransportAvailable(TransportType::Grpc) {
167 Available.push(TransportType::Grpc);
168 }
169 if self.IsTransportAvailable(TransportType::Ipc) {
170 Available.push(TransportType::Ipc);
171 }
172 if self.IsTransportAvailable(TransportType::Wasm) {
173 Available.push(TransportType::Wasm);
174 }
175
176 Available
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 fn TestTransportTypeAsString() {
186 assert_eq!(TransportType::Grpc.AsString(), "grpc");
187 assert_eq!(TransportType::Ipc.AsString(), "ipc");
188 assert_eq!(TransportType::Wasm.AsString(), "wasm");
189 assert_eq!(TransportType::Unknown.AsString(), "unknown");
190 }
191
192 #[test]
193 fn TestTransportTypeFromString() {
194 assert_eq!("grpc".parse::<TransportType>().unwrap(), TransportType::Grpc);
195 assert_eq!("ipc".parse::<TransportType>().unwrap(), TransportType::Ipc);
196 assert_eq!("wasm".parse::<TransportType>().unwrap(), TransportType::Wasm);
197 assert!("invalid".parse::<TransportType>().is_err());
198 }
199
200 #[test]
201 fn TestDefaultDetector() {
202 let Available = DefaultTransportTypeDetector::list_available_transports();
203 assert!(Available.contains(&TransportType::Grpc));
204 }
205}