1use serde::{Deserialize, Serialize};
7use std::fmt;
8use std::sync::Arc;
9
10#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
33#[serde(transparent)]
34pub struct TransportKey(Arc<str>);
35
36impl TransportKey {
37 pub fn new(key: impl Into<Arc<str>>) -> Self {
39 Self(key.into())
40 }
41
42 pub fn as_str(&self) -> &str {
44 &self.0
45 }
46}
47
48impl std::ops::Deref for TransportKey {
50 type Target = str;
51
52 fn deref(&self) -> &Self::Target {
53 &self.0
54 }
55}
56
57impl AsRef<str> for TransportKey {
59 fn as_ref(&self) -> &str {
60 &self.0
61 }
62}
63
64impl From<&str> for TransportKey {
66 fn from(s: &str) -> Self {
67 Self(Arc::from(s))
68 }
69}
70
71impl From<String> for TransportKey {
72 fn from(s: String) -> Self {
73 Self(Arc::from(s))
74 }
75}
76
77impl From<Arc<str>> for TransportKey {
78 fn from(s: Arc<str>) -> Self {
79 Self(s)
80 }
81}
82
83impl From<&String> for TransportKey {
84 fn from(s: &String) -> Self {
85 Self(Arc::from(s.as_str()))
86 }
87}
88
89impl From<TransportKey> for String {
90 fn from(val: TransportKey) -> Self {
91 val.0.to_string()
92 }
93}
94
95impl std::borrow::Borrow<str> for TransportKey {
97 fn borrow(&self) -> &str {
98 &self.0
99 }
100}
101
102impl fmt::Display for TransportKey {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(f, "{}", self.0)
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use std::collections::{HashMap, HashSet};
113
114 #[test]
115 fn test_transport_key_creation() {
116 let key1 = TransportKey::new("tcp");
118 assert_eq!(key1.as_str(), "tcp");
119
120 let key2: TransportKey = "rdma".into();
122 assert_eq!(key2.as_str(), "rdma");
123
124 let key3 = TransportKey::from(String::from("udp"));
126 assert_eq!(key3.as_str(), "udp");
127
128 let s = String::from("grpc");
130 let key4 = TransportKey::from(&s);
131 assert_eq!(key4.as_str(), "grpc");
132
133 let arc_str: Arc<str> = Arc::from("http");
135 let key5 = TransportKey::from(arc_str);
136 assert_eq!(key5.as_str(), "http");
137 }
138
139 #[test]
140 fn test_transport_key_deref() {
141 let key = TransportKey::from("tcp");
142
143 assert_eq!(key.len(), 3);
145 assert_eq!(key.chars().count(), 3);
146 assert!(key.starts_with("tc"));
147 assert!(key.ends_with("cp"));
148
149 assert_eq!(&key[0..2], "tc");
151 }
152
153 #[test]
154 fn test_transport_key_as_ref() {
155 let key = TransportKey::from("tcp");
156
157 fn takes_str_ref(s: &str) -> usize {
159 s.len()
160 }
161
162 assert_eq!(takes_str_ref(&key), 3);
163 assert_eq!(takes_str_ref(key.as_ref()), 3);
164 }
165
166 #[test]
167 fn test_transport_key_display() {
168 let key = TransportKey::from("tcp");
169 assert_eq!(format!("{}", key), "tcp");
170 assert_eq!(key.to_string(), "tcp");
171 }
172
173 #[test]
174 fn test_transport_key_debug() {
175 let key = TransportKey::from("tcp");
176 let debug_str = format!("{:?}", key);
177 assert!(debug_str.contains("TransportKey"));
178 assert!(debug_str.contains("tcp"));
179 }
180
181 #[test]
182 fn test_transport_key_equality() {
183 let key1 = TransportKey::from("tcp");
184 let key2 = TransportKey::from("tcp");
185 let key3 = TransportKey::from("rdma");
186
187 assert_eq!(key1, key2);
188 assert_ne!(key1, key3);
189
190 let key4: TransportKey = String::from("tcp").into();
192 assert_eq!(key1, key4);
193 }
194
195 #[test]
196 fn test_transport_key_ordering() {
197 let mut keys = [
198 TransportKey::from("udp"),
199 TransportKey::from("tcp"),
200 TransportKey::from("rdma"),
201 TransportKey::from("grpc"),
202 ];
203
204 keys.sort();
205
206 assert_eq!(keys[0], TransportKey::from("grpc"));
207 assert_eq!(keys[1], TransportKey::from("rdma"));
208 assert_eq!(keys[2], TransportKey::from("tcp"));
209 assert_eq!(keys[3], TransportKey::from("udp"));
210 }
211
212 #[test]
213 fn test_transport_key_hash() {
214 let mut set = HashSet::new();
215 set.insert(TransportKey::from("tcp"));
216 set.insert(TransportKey::from("rdma"));
217 set.insert(TransportKey::from("tcp")); assert_eq!(set.len(), 2);
220 assert!(set.contains(&TransportKey::from("tcp")));
221 assert!(set.contains(&TransportKey::from("rdma")));
222 assert!(!set.contains(&TransportKey::from("udp")));
223 }
224
225 #[test]
226 fn test_transport_key_in_hashmap() {
227 let mut map = HashMap::new();
228 map.insert(TransportKey::from("tcp"), "tcp://127.0.0.1:5555");
229 map.insert(TransportKey::from("rdma"), "rdma://10.0.0.1:6666");
230
231 assert_eq!(
233 map.get(&TransportKey::from("tcp")),
234 Some(&"tcp://127.0.0.1:5555")
235 );
236
237 assert_eq!(map.get("tcp"), Some(&"tcp://127.0.0.1:5555"));
239 assert_eq!(map.get("rdma"), Some(&"rdma://10.0.0.1:6666"));
240 assert_eq!(map.get("udp"), None);
241 }
242
243 #[test]
244 fn test_transport_key_clone() {
245 let key1 = TransportKey::from("tcp");
246 let key2 = key1.clone();
247
248 assert_eq!(key1, key2);
249 assert_eq!(key1.as_str(), key2.as_str());
250
251 let ptr1 = key1.as_str().as_ptr();
253 let ptr2 = key2.as_str().as_ptr();
254 assert_eq!(ptr1, ptr2);
255 }
256}