boxlite_shared/
transport.rs1use std::path::PathBuf;
4
5#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
10pub enum Transport {
11 Tcp { port: u16 },
13
14 Unix { socket_path: PathBuf },
16
17 Vsock { port: u32 },
19}
20
21impl Transport {
22 pub fn tcp(port: u16) -> Self {
24 Self::Tcp { port }
25 }
26
27 pub fn unix(socket_path: PathBuf) -> Self {
29 Self::Unix { socket_path }
30 }
31
32 pub fn vsock(port: u32) -> Self {
34 Self::Vsock { port }
35 }
36
37 pub fn to_uri(&self) -> String {
39 match self {
40 Transport::Tcp { port } => format!("tcp://127.0.0.1:{}", port),
41 Transport::Unix { socket_path } => format!("unix://{}", socket_path.display()),
42 Transport::Vsock { port } => format!("vsock://{}", port),
43 }
44 }
45
46 pub fn from_uri(uri: &str) -> Result<Self, String> {
48 if let Some(rest) = uri.strip_prefix("tcp://") {
49 let port = rest
50 .split(':')
51 .nth(1)
52 .ok_or_else(|| format!("invalid TCP URI '{}': missing port", uri))?
53 .parse::<u16>()
54 .map_err(|e| format!("invalid TCP port in '{}': {}", uri, e))?;
55 Ok(Self::tcp(port))
56 } else if let Some(path) = uri.strip_prefix("unix://") {
57 Ok(Self::unix(PathBuf::from(path)))
58 } else if let Some(port_str) = uri.strip_prefix("vsock://") {
59 let port = port_str
60 .parse::<u32>()
61 .map_err(|e| format!("invalid vsock port in '{}': {}", uri, e))?;
62 Ok(Self::vsock(port))
63 } else {
64 Err(format!(
65 "invalid transport URI '{}': expected tcp://, unix://, or vsock://",
66 uri
67 ))
68 }
69 }
70}
71
72impl std::fmt::Display for Transport {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 write!(f, "{}", self.to_uri())
75 }
76}
77
78impl std::str::FromStr for Transport {
79 type Err = String;
80
81 fn from_str(s: &str) -> Result<Self, Self::Err> {
82 Self::from_uri(s)
83 }
84}