1//! Portability abstractions over `Raw*`.
2//!
3//! On Unix, "everything is a file descriptor". On Windows, file/pipe/process
4//! handles are distinct from socket descriptors. This file provides a minimal
5//! layer of portability over this difference.
6
7#[cfg(target_os = "hermit")]
8use std::os::hermit::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
9#[cfg(unix)]
10use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
11#[cfg(target_os = "wasi")]
12use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
13#[cfg(windows)]
14use std::os::windows::io::{
15 AsRawHandle, AsRawSocket, FromRawHandle, FromRawSocket, IntoRawHandle, IntoRawSocket,
16 RawHandle, RawSocket,
17};
18
19/// A raw filelike object.
20///
21/// This is a portability abstraction over Unix-like [`RawFd`] and
22/// Windows' `RawHandle`.
23#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
24pub type RawFilelike = RawFd;
25
26/// A raw filelike object.
27///
28/// This is a portability abstraction over Unix-like `RawFd` and
29/// Windows' [`RawHandle`].
30#[cfg(windows)]
31pub type RawFilelike = RawHandle;
32
33/// A raw socketlike object.
34///
35/// This is a portability abstraction over Unix-like [`RawFd`] and
36/// Windows' `RawSocket`.
37#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
38pub type RawSocketlike = RawFd;
39
40/// A raw socketlike object.
41///
42/// This is a portability abstraction over Unix-like `RawFd` and
43/// Windows' [`RawSocket`].
44#[cfg(windows)]
45pub type RawSocketlike = RawSocket;
46
47/// A portable trait to obtain the raw value of an underlying filelike object.
48///
49/// This is a portability abstraction over Unix-like [`AsRawFd`] and Windows'
50/// `AsRawHandle`.
51#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
52pub trait AsRawFilelike: AsRawFd {
53 /// Returns the raw value.
54 fn as_raw_filelike(&self) -> RawFilelike;
55}
56
57#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
58impl<T: AsRawFd> AsRawFilelike for T {
59 #[inline]
60 fn as_raw_filelike(&self) -> RawFilelike {
61 self.as_raw_fd()
62 }
63}
64
65/// This is a portability abstraction over Unix-like `AsRawFd` and Windows'
66/// [`AsRawHandle`].
67#[cfg(windows)]
68pub trait AsRawFilelike: AsRawHandle {
69 /// Returns the raw value.
70 fn as_raw_filelike(&self) -> RawFilelike;
71}
72
73#[cfg(windows)]
74impl<T: AsRawHandle> AsRawFilelike for T {
75 #[inline]
76 fn as_raw_filelike(&self) -> RawFilelike {
77 self.as_raw_handle()
78 }
79}
80
81/// This is a portability abstraction over Unix-like [`AsRawFd`] and Windows'
82/// `AsRawSocket`.
83#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
84pub trait AsRawSocketlike: AsRawFd {
85 /// Returns the raw value.
86 fn as_raw_socketlike(&self) -> RawSocketlike;
87}
88
89#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
90impl<T: AsRawFd> AsRawSocketlike for T {
91 #[inline]
92 fn as_raw_socketlike(&self) -> RawSocketlike {
93 self.as_raw_fd()
94 }
95}
96
97/// This is a portability abstraction over Unix-like `AsRawFd` and Windows'
98/// [`AsRawSocket`].
99#[cfg(windows)]
100pub trait AsRawSocketlike: AsRawSocket {
101 /// Returns the raw value.
102 fn as_raw_socketlike(&self) -> RawSocketlike;
103}
104
105#[cfg(windows)]
106impl<T: AsRawSocket> AsRawSocketlike for T {
107 #[inline]
108 fn as_raw_socketlike(&self) -> RawSocketlike {
109 self.as_raw_socket()
110 }
111}
112
113/// This is a portability abstraction over Unix-like [`IntoRawFd`] and Windows'
114/// `IntoRawHandle`.
115#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
116pub trait IntoRawFilelike: IntoRawFd {
117 /// Returns the raw value.
118 fn into_raw_filelike(self) -> RawFilelike;
119}
120
121#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
122impl<T: IntoRawFd> IntoRawFilelike for T {
123 #[inline]
124 fn into_raw_filelike(self) -> RawFilelike {
125 self.into_raw_fd()
126 }
127}
128
129/// This is a portability abstraction over Unix-like `IntoRawFd` and Windows'
130/// [`IntoRawHandle`].
131#[cfg(windows)]
132pub trait IntoRawFilelike: IntoRawHandle {
133 /// Returns the raw value.
134 fn into_raw_filelike(self) -> RawFilelike;
135}
136
137#[cfg(windows)]
138impl<T: IntoRawHandle> IntoRawFilelike for T {
139 #[inline]
140 fn into_raw_filelike(self) -> RawFilelike {
141 self.into_raw_handle()
142 }
143}
144
145/// This is a portability abstraction over Unix-like [`IntoRawFd`] and Windows'
146/// `IntoRawSocket`.
147#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
148pub trait IntoRawSocketlike: IntoRawFd {
149 /// Returns the raw value.
150 fn into_raw_socketlike(self) -> RawSocketlike;
151}
152
153#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
154impl<T: IntoRawFd> IntoRawSocketlike for T {
155 #[inline]
156 fn into_raw_socketlike(self) -> RawSocketlike {
157 self.into_raw_fd()
158 }
159}
160
161/// This is a portability abstraction over Unix-like `IntoRawFd` and Windows'
162/// [`IntoRawSocket`].
163#[cfg(windows)]
164pub trait IntoRawSocketlike: IntoRawSocket {
165 /// Returns the raw value.
166 fn into_raw_socketlike(self) -> RawSocketlike;
167}
168
169#[cfg(windows)]
170impl<T: IntoRawSocket> IntoRawSocketlike for T {
171 #[inline]
172 fn into_raw_socketlike(self) -> RawSocketlike {
173 self.into_raw_socket()
174 }
175}
176
177/// This is a portability abstraction over Unix-like [`FromRawFd`] and Windows'
178/// `FromRawHandle`.
179#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
180pub trait FromRawFilelike: FromRawFd {
181 /// Constructs `Self` from the raw value.
182 ///
183 /// # Safety
184 ///
185 /// This is `unsafe` for the same reason as [`from_raw_fd`] and
186 /// [`from_raw_handle`].
187 ///
188 /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.from_raw_fd
189 /// [`from_raw_handle`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.FromRawHandle.html#tymethod.from_raw_handle
190 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self;
191}
192
193#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
194impl<T: FromRawFd> FromRawFilelike for T {
195 #[inline]
196 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self {
197 Self::from_raw_fd(raw)
198 }
199}
200
201/// This is a portability abstraction over Unix-like `FromRawFd` and Windows'
202/// [`FromRawHandle`].
203#[cfg(windows)]
204pub trait FromRawFilelike: FromRawHandle {
205 /// Constructs `Self` from the raw value.
206 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self;
207}
208
209#[cfg(windows)]
210impl<T: FromRawHandle> FromRawFilelike for T {
211 #[inline]
212 unsafe fn from_raw_filelike(raw: RawFilelike) -> Self {
213 Self::from_raw_handle(raw)
214 }
215}
216
217/// This is a portability abstraction over Unix-like [`FromRawFd`] and Windows'
218/// `FromRawSocket`.
219#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
220pub trait FromRawSocketlike: FromRawFd {
221 /// Constructs `Self` from the raw value.
222 ///
223 /// # Safety
224 ///
225 /// This is `unsafe` for the same reason as [`from_raw_fd`] and
226 /// [`from_raw_socket`].
227 ///
228 /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.from_raw_fd
229 /// [`from_raw_socket`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.FromRawSocket.html#tymethod.from_raw_socket
230 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self;
231}
232
233#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
234impl<T: FromRawFd> FromRawSocketlike for T {
235 #[inline]
236 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self {
237 Self::from_raw_fd(raw)
238 }
239}
240
241/// This is a portability abstraction over Unix-like `FromRawFd` and Windows'
242/// [`FromRawSocket`].
243#[cfg(windows)]
244pub trait FromRawSocketlike: FromRawSocket {
245 /// Constructs `Self` from the raw value.
246 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self;
247}
248
249#[cfg(windows)]
250impl<T: FromRawSocket> FromRawSocketlike for T {
251 #[inline]
252 unsafe fn from_raw_socketlike(raw: RawSocketlike) -> Self {
253 Self::from_raw_socket(raw)
254 }
255}
256