1use crate::local_node::Port;
11use thiserror::Error;
12
13#[derive(Debug)]
14pub enum OsResource {
15 #[cfg(unix)]
16 Fd(std::os::unix::io::OwnedFd),
17 #[cfg(windows)]
18 Handle(std::os::windows::io::OwnedHandle),
19 #[cfg(windows)]
20 Socket(std::os::windows::io::OwnedSocket),
21}
22
23#[derive(Debug)]
25pub enum Resource {
26 Port(Port),
28 Os(OsResource),
30}
31
32impl From<Port> for Resource {
33 fn from(port: Port) -> Self {
34 Self::Port(port)
35 }
36}
37
38#[derive(Debug, Error)]
39pub enum ResourceError {
40 #[error("wrong resource type")]
41 BadResourceType,
42 #[cfg(windows)]
43 #[error("failed to convert handle to socket")]
44 HandleToSocket(#[source] std::io::Error),
45}
46
47impl TryFrom<Resource> for Port {
48 type Error = ResourceError;
49
50 fn try_from(value: Resource) -> Result<Self, ResourceError> {
51 match value {
52 Resource::Port(port) => Ok(port),
53 _ => Err(ResourceError::BadResourceType),
54 }
55 }
56}
57
58#[cfg(unix)]
59impl From<std::os::unix::io::OwnedFd> for Resource {
60 fn from(fd: std::os::unix::io::OwnedFd) -> Self {
61 Self::Os(OsResource::Fd(fd))
62 }
63}
64
65#[cfg(unix)]
66impl TryFrom<Resource> for std::os::unix::io::OwnedFd {
67 type Error = ResourceError;
68
69 fn try_from(value: Resource) -> Result<Self, ResourceError> {
70 match value {
71 Resource::Os(OsResource::Fd(fd)) => Ok(fd),
72 _ => Err(ResourceError::BadResourceType),
73 }
74 }
75}
76
77#[cfg(windows)]
78impl From<std::os::windows::io::OwnedHandle> for Resource {
79 fn from(port: std::os::windows::io::OwnedHandle) -> Self {
80 Self::Os(OsResource::Handle(port))
81 }
82}
83
84#[cfg(windows)]
85impl TryFrom<Resource> for std::os::windows::io::OwnedHandle {
86 type Error = ResourceError;
87
88 fn try_from(value: Resource) -> Result<Self, ResourceError> {
89 match value {
90 Resource::Os(OsResource::Handle(handle)) => Ok(handle),
91 _ => Err(ResourceError::BadResourceType),
92 }
93 }
94}
95
96#[cfg(windows)]
97impl From<std::os::windows::io::OwnedSocket> for Resource {
98 fn from(port: std::os::windows::io::OwnedSocket) -> Self {
99 Self::Os(OsResource::Socket(port))
100 }
101}
102
103#[cfg(windows)]
104impl TryFrom<Resource> for std::os::windows::io::OwnedSocket {
105 type Error = ResourceError;
106
107 fn try_from(value: Resource) -> Result<Self, ResourceError> {
108 match value {
109 Resource::Os(OsResource::Socket(socket)) => Ok(socket),
110 Resource::Os(OsResource::Handle(handle)) => {
111 pal::windows::OwnedSocketExt::from_handle(handle)
112 .map_err(ResourceError::HandleToSocket)
113 }
114 _ => Err(ResourceError::BadResourceType),
115 }
116 }
117}
118
119pub type SerializedMessage = mesh_protobuf::SerializedMessage<Resource>;