use std::fmt;
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct TransportKey(Arc<str>);
impl TransportKey {
pub fn new(key: impl Into<Arc<str>>) -> Self {
Self(key.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::ops::Deref for TransportKey {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<str> for TransportKey {
fn as_ref(&self) -> &str {
&self.0
}
}
impl From<&str> for TransportKey {
fn from(s: &str) -> Self {
Self(Arc::from(s))
}
}
impl From<String> for TransportKey {
fn from(s: String) -> Self {
Self(Arc::from(s))
}
}
impl From<Arc<str>> for TransportKey {
fn from(s: Arc<str>) -> Self {
Self(s)
}
}
impl From<&String> for TransportKey {
fn from(s: &String) -> Self {
Self(Arc::from(s.as_str()))
}
}
impl From<TransportKey> for String {
fn from(val: TransportKey) -> Self {
val.0.to_string()
}
}
impl std::borrow::Borrow<str> for TransportKey {
fn borrow(&self) -> &str {
&self.0
}
}
impl fmt::Display for TransportKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::{HashMap, HashSet};
#[test]
fn test_transport_key_creation() {
let key1 = TransportKey::new("tcp");
assert_eq!(key1.as_str(), "tcp");
let key2: TransportKey = "rdma".into();
assert_eq!(key2.as_str(), "rdma");
let key3 = TransportKey::from(String::from("udp"));
assert_eq!(key3.as_str(), "udp");
let s = String::from("grpc");
let key4 = TransportKey::from(&s);
assert_eq!(key4.as_str(), "grpc");
let arc_str: Arc<str> = Arc::from("http");
let key5 = TransportKey::from(arc_str);
assert_eq!(key5.as_str(), "http");
}
#[test]
fn test_transport_key_deref() {
let key = TransportKey::from("tcp");
assert_eq!(key.len(), 3);
assert_eq!(key.chars().count(), 3);
assert!(key.starts_with("tc"));
assert!(key.ends_with("cp"));
assert_eq!(&key[0..2], "tc");
}
#[test]
fn test_transport_key_as_ref() {
let key = TransportKey::from("tcp");
fn takes_str_ref(s: &str) -> usize {
s.len()
}
assert_eq!(takes_str_ref(&key), 3);
assert_eq!(takes_str_ref(key.as_ref()), 3);
}
#[test]
fn test_transport_key_display() {
let key = TransportKey::from("tcp");
assert_eq!(format!("{}", key), "tcp");
assert_eq!(key.to_string(), "tcp");
}
#[test]
fn test_transport_key_debug() {
let key = TransportKey::from("tcp");
let debug_str = format!("{:?}", key);
assert!(debug_str.contains("TransportKey"));
assert!(debug_str.contains("tcp"));
}
#[test]
fn test_transport_key_equality() {
let key1 = TransportKey::from("tcp");
let key2 = TransportKey::from("tcp");
let key3 = TransportKey::from("rdma");
assert_eq!(key1, key2);
assert_ne!(key1, key3);
let key4: TransportKey = String::from("tcp").into();
assert_eq!(key1, key4);
}
#[test]
fn test_transport_key_ordering() {
let mut keys = [
TransportKey::from("udp"),
TransportKey::from("tcp"),
TransportKey::from("rdma"),
TransportKey::from("grpc"),
];
keys.sort();
assert_eq!(keys[0], TransportKey::from("grpc"));
assert_eq!(keys[1], TransportKey::from("rdma"));
assert_eq!(keys[2], TransportKey::from("tcp"));
assert_eq!(keys[3], TransportKey::from("udp"));
}
#[test]
fn test_transport_key_hash() {
let mut set = HashSet::new();
set.insert(TransportKey::from("tcp"));
set.insert(TransportKey::from("rdma"));
set.insert(TransportKey::from("tcp"));
assert_eq!(set.len(), 2);
assert!(set.contains(&TransportKey::from("tcp")));
assert!(set.contains(&TransportKey::from("rdma")));
assert!(!set.contains(&TransportKey::from("udp")));
}
#[test]
fn test_transport_key_in_hashmap() {
let mut map = HashMap::new();
map.insert(TransportKey::from("tcp"), "tcp://127.0.0.1:5555");
map.insert(TransportKey::from("rdma"), "rdma://10.0.0.1:6666");
assert_eq!(
map.get(&TransportKey::from("tcp")),
Some(&"tcp://127.0.0.1:5555")
);
assert_eq!(map.get("tcp"), Some(&"tcp://127.0.0.1:5555"));
assert_eq!(map.get("rdma"), Some(&"rdma://10.0.0.1:6666"));
assert_eq!(map.get("udp"), None);
}
#[test]
fn test_transport_key_clone() {
let key1 = TransportKey::from("tcp");
let key2 = key1.clone();
assert_eq!(key1, key2);
assert_eq!(key1.as_str(), key2.as_str());
let ptr1 = key1.as_str().as_ptr();
let ptr2 = key2.as_str().as_ptr();
assert_eq!(ptr1, ptr2);
}
}