io_extras/os/windows/
mod.rs

1//! The [`RawHandleOrSocket`] type and accompanying [`AsRawHandleOrSocket`],
2//! [`IntoRawHandleOrSocket`], and [`FromRawHandleOrSocket`] traits. These
3//! provide minimal Windows analogs for the Posix-ish `RawFd` type and
4//! accompanying `AsRawFd`, `IntoRawFd`, and `FromRawFd` traits.
5//!
6//! These types are only defined on Windows and do not require implementors to
7//! assert that they own their resources.
8
9#[cfg(any(test, feature = "os_pipe"))]
10use os_pipe::{PipeReader, PipeWriter};
11use std::fs::File;
12use std::io::{Stderr, StderrLock, Stdin, StdinLock, Stdout, StdoutLock};
13use std::net::{TcpListener, TcpStream, UdpSocket};
14use std::os::windows::io::{
15    AsRawHandle, AsRawSocket, IntoRawHandle, IntoRawSocket, RawHandle, RawSocket,
16};
17use std::process::{ChildStderr, ChildStdin, ChildStdout};
18use stdio::Stdio;
19
20mod stdio;
21mod traits;
22mod types;
23
24pub use crate::read_write::{AsRawReadWriteHandleOrSocket, AsReadWriteHandleOrSocket};
25pub use traits::AsHandleOrSocket;
26pub use types::{BorrowedHandleOrSocket, OwnedHandleOrSocket};
27
28/// A Windows analog for the Posix-ish `AsRawFd` type. Unlike Posix-ish
29/// platforms which have a single type for files and sockets, Windows has
30/// distinct types, `RawHandle` and `RawSocket`. And unlike Posix-ish
31/// platforms where text streams are generally UTF-8, the Windows Console
32/// is UTF-16. This type behaves like an enum which can hold either a
33/// handle or a socket, and to which UTF-8 text can be written.
34///
35/// It's reasonable to worry that this might be trying too hard to make Windows
36/// work like Posix-ish platforms, however in this case, the number of types is
37/// small, so the enum is simple and the overhead is relatively low, and the
38/// benefit is that we can abstract over major [`Read`] and [`Write`]
39/// resources.
40///
41/// [`Read`]: std::io::Read
42/// [`Write`]: std::io::Write
43#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
44#[repr(transparent)]
45pub struct RawHandleOrSocket(pub(crate) RawEnum);
46
47/// The enum itself is a private type so that we have the flexibility to change
48/// the representation in the future.
49///
50/// It's possible that Windows could add other handle-like types in the future.
51/// And it's possible that we'll want to optimize the representation, possibly
52/// by finding an unused bit in the `RawHandle` and `RawSocket` representations
53/// which we can repurpose as a discriminant.
54#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
55pub(crate) enum RawEnum {
56    /// A `RawHandle`.
57    Handle(RawHandle),
58
59    /// A `RawSocket`.
60    Socket(RawSocket),
61
62    /// `Stdin`, `Stdout`, or `Stderr` that might be on a console and might
63    /// need translation from UTF-8 to UTF-16.
64    Stdio(Stdio),
65}
66
67impl RawHandleOrSocket {
68    /// Like [`FromRawHandle::from_raw_handle`], but isn't unsafe because it
69    /// doesn't imply a dereference.
70    ///
71    /// [`FromRawHandle::from_raw_handle`]: std::os::windows::io::FromRawHandle::from_raw_handle
72    #[inline]
73    #[must_use]
74    pub const fn unowned_from_raw_handle(raw_handle: RawHandle) -> Self {
75        Self(RawEnum::Handle(raw_handle))
76    }
77
78    /// Like [`FromRawSocket::from_raw_socket`], but isn't unsafe because it
79    /// doesn't imply a dereference.
80    ///
81    /// [`FromRawSocket::from_raw_socket`]: std::os::windows::io::FromRawSocket::from_raw_socket
82    #[inline]
83    #[must_use]
84    pub const fn unowned_from_raw_socket(raw_socket: RawSocket) -> Self {
85        Self(RawEnum::Socket(raw_socket))
86    }
87
88    /// Like [`AsRawHandle::as_raw_handle`], but returns an `Option` so that
89    /// it can return `None` if `self` doesn't contain a `RawHandle`.
90    #[inline]
91    #[must_use]
92    pub fn as_raw_handle(&self) -> Option<RawHandle> {
93        match self.0 {
94            RawEnum::Handle(raw_handle) => Some(raw_handle),
95            RawEnum::Socket(_) => None,
96            RawEnum::Stdio(ref stdio) => Some(stdio.as_raw_handle()),
97        }
98    }
99
100    /// Like [`AsRawSocket::as_raw_socket`], but returns an `Option` so that
101    /// it can return `None` if `self` doesn't contain a `RawSocket`.
102    #[inline]
103    #[must_use]
104    pub const fn as_raw_socket(&self) -> Option<RawSocket> {
105        match self.0 {
106            RawEnum::Handle(_) | RawEnum::Stdio(_) => None,
107            RawEnum::Socket(raw_socket) => Some(raw_socket),
108        }
109    }
110
111    /// Return a `RawHandleOrSocket` representing stdin.
112    ///
113    /// This differs from `unowned_from_raw_handle` on the stdin handle in two
114    /// ways:
115    ///  - It tracks the stdin handle, which may change dynamically via
116    ///    `SetStdHandle`.
117    ///  - When stdin is attached to a console, reads from this handle via
118    ///    `RawReadable` are decoded into UTF-8.
119    #[inline]
120    #[must_use]
121    pub const fn stdin() -> Self {
122        Self(RawEnum::Stdio(Stdio::stdin()))
123    }
124
125    /// Return a `RawHandleOrSocket` representing stdout.
126    ///
127    /// This differs from `unowned_from_raw_handle` on the stdout handle in two
128    /// ways:
129    ///  - It tracks the stdout handle, which may change dynamically via
130    ///    `SetStdHandle`.
131    ///  - When stdout is attached to a console, writes to this handle via
132    ///    `RawWriteable` are encoded from UTF-8.
133    #[inline]
134    #[must_use]
135    pub const fn stdout() -> Self {
136        Self(RawEnum::Stdio(Stdio::stdout()))
137    }
138
139    /// Return a `RawHandleOrSocket` representing stderr.
140    ///
141    /// This differs from `unowned_from_raw_handle` on the stderr handle in two
142    /// ways:
143    ///  - It tracks the stderr handle, which may change dynamically via
144    ///    `SetStdHandle`.
145    ///  - When stderr is attached to a console, writes to this handle via
146    ///    `RawWriteable` are encoded from UTF-8.
147    #[inline]
148    #[must_use]
149    pub const fn stderr() -> Self {
150        Self(RawEnum::Stdio(Stdio::stderr()))
151    }
152}
153
154/// Like [`AsRawHandle`] and [`AsRawSocket`], but implementable by types which
155/// can implement either one.
156pub trait AsRawHandleOrSocket {
157    /// Like [`AsRawHandle::as_raw_handle`] and [`AsRawSocket::as_raw_socket`]
158    /// but can return either type.
159    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket;
160}
161
162/// Like [`IntoRawHandle`] and [`IntoRawSocket`], but implementable by types
163/// which can implement either one.
164pub trait IntoRawHandleOrSocket {
165    /// Like [`IntoRawHandle::into_raw_handle`] and
166    /// [`IntoRawSocket::into_raw_socket`] but can return either type.
167    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket;
168}
169
170/// Like [`FromRawHandle`] and [`FromRawSocket`], but implementable by types
171/// which can implement both.
172///
173/// Note: Don't implement this trait for types which can only implement one
174/// or the other, such that it would need to panic if passed the wrong form.
175///
176/// [`FromRawHandle`]: std::os::windows::io::FromRawHandle
177/// [`FromRawSocket`]: std::os::windows::io::FromRawSocket
178pub trait FromRawHandleOrSocket {
179    /// Like [`FromRawHandle::from_raw_handle`] and
180    /// [`FromRawSocket::from_raw_socket`] but can be passed either type.
181    ///
182    /// # Safety
183    ///
184    /// `raw_handle_or_socket` must be valid and otherwise unowned.
185    ///
186    /// [`FromRawHandle::from_raw_handle`]: std::os::windows::io::FromRawHandle::from_raw_handle
187    /// [`FromRawSocket::from_raw_socket`]: std::os::windows::io::FromRawSocket::from_raw_socket
188    unsafe fn from_raw_handle_or_socket(raw_handle_or_socket: RawHandleOrSocket) -> Self;
189}
190
191/// The Windows [`HANDLE`] and [`SOCKET`] types may be sent between threads.
192///
193/// [`HANDLE`]: std::os::windows::raw::HANDLE
194/// [`SOCKET`]: std::os::windows::raw::SOCKET
195unsafe impl Send for RawHandleOrSocket {}
196
197/// The Windows [`HANDLE`] and [`SOCKET`] types may be shared between threads.
198///
199/// [`HANDLE`]: std::os::windows::raw::HANDLE
200/// [`SOCKET`]: std::os::windows::raw::SOCKET
201unsafe impl Sync for RawHandleOrSocket {}
202
203impl AsRawHandleOrSocket for RawHandleOrSocket {
204    #[inline]
205    fn as_raw_handle_or_socket(&self) -> Self {
206        *self
207    }
208}
209
210impl AsRawHandleOrSocket for Stdin {
211    #[inline]
212    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
213        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
214    }
215}
216
217impl AsRawHandleOrSocket for StdinLock<'_> {
218    #[inline]
219    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
220        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
221    }
222}
223
224impl AsRawHandleOrSocket for Stdout {
225    #[inline]
226    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
227        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
228    }
229}
230
231impl AsRawHandleOrSocket for StdoutLock<'_> {
232    #[inline]
233    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
234        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
235    }
236}
237
238impl AsRawHandleOrSocket for Stderr {
239    #[inline]
240    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
241        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
242    }
243}
244
245impl AsRawHandleOrSocket for StderrLock<'_> {
246    #[inline]
247    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
248        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
249    }
250}
251
252impl AsRawHandleOrSocket for File {
253    #[inline]
254    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
255        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
256    }
257}
258
259impl AsRawHandleOrSocket for ChildStdin {
260    #[inline]
261    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
262        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
263    }
264}
265
266impl AsRawHandleOrSocket for ChildStdout {
267    #[inline]
268    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
269        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
270    }
271}
272
273impl AsRawHandleOrSocket for ChildStderr {
274    #[inline]
275    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
276        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
277    }
278}
279
280impl AsRawHandleOrSocket for TcpStream {
281    #[inline]
282    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
283        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
284    }
285}
286
287impl AsRawHandleOrSocket for TcpListener {
288    #[inline]
289    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
290        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
291    }
292}
293
294impl AsRawHandleOrSocket for UdpSocket {
295    #[inline]
296    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
297        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
298    }
299}
300
301#[cfg(feature = "async-std")]
302impl AsRawHandleOrSocket for async_std::io::Stdin {
303    #[inline]
304    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
305        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
306    }
307}
308
309#[cfg(feature = "async-std")]
310impl AsRawHandleOrSocket for async_std::io::Stdout {
311    #[inline]
312    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
313        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
314    }
315}
316
317#[cfg(feature = "async-std")]
318impl AsRawHandleOrSocket for async_std::io::Stderr {
319    #[inline]
320    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
321        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
322    }
323}
324
325#[cfg(feature = "async-std")]
326impl AsRawHandleOrSocket for async_std::fs::File {
327    #[inline]
328    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
329        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
330    }
331}
332
333// async_std's `ChildStdin`, `ChildStdout`, and `ChildStderr` don't implement
334// `AsRawFd` or `AsRawHandle`.
335
336#[cfg(feature = "async-std")]
337impl AsRawHandleOrSocket for async_std::net::TcpStream {
338    #[inline]
339    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
340        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
341    }
342}
343
344#[cfg(feature = "async-std")]
345impl AsRawHandleOrSocket for async_std::net::TcpListener {
346    #[inline]
347    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
348        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
349    }
350}
351
352#[cfg(feature = "async-std")]
353impl AsRawHandleOrSocket for async_std::net::UdpSocket {
354    #[inline]
355    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
356        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
357    }
358}
359
360#[cfg(feature = "tokio")]
361impl AsRawHandleOrSocket for tokio::io::Stdin {
362    #[inline]
363    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
364        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
365    }
366}
367
368#[cfg(feature = "tokio")]
369impl AsRawHandleOrSocket for tokio::io::Stdout {
370    #[inline]
371    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
372        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
373    }
374}
375
376#[cfg(feature = "tokio")]
377impl AsRawHandleOrSocket for tokio::io::Stderr {
378    #[inline]
379    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
380        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
381    }
382}
383
384#[cfg(feature = "tokio")]
385impl AsRawHandleOrSocket for tokio::fs::File {
386    #[inline]
387    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
388        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
389    }
390}
391
392#[cfg(feature = "tokio")]
393impl AsRawHandleOrSocket for tokio::net::TcpStream {
394    #[inline]
395    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
396        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
397    }
398}
399
400#[cfg(feature = "tokio")]
401impl AsRawHandleOrSocket for tokio::net::TcpListener {
402    #[inline]
403    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
404        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
405    }
406}
407
408#[cfg(feature = "tokio")]
409impl AsRawHandleOrSocket for tokio::net::UdpSocket {
410    #[inline]
411    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
412        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
413    }
414}
415
416#[cfg(feature = "tokio")]
417impl AsRawHandleOrSocket for tokio::process::ChildStdin {
418    #[inline]
419    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
420        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
421    }
422}
423
424#[cfg(feature = "tokio")]
425impl AsRawHandleOrSocket for tokio::process::ChildStdout {
426    #[inline]
427    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
428        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
429    }
430}
431
432#[cfg(feature = "tokio")]
433impl AsRawHandleOrSocket for tokio::process::ChildStderr {
434    #[inline]
435    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
436        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
437    }
438}
439
440#[cfg(any(test, feature = "os_pipe"))]
441impl AsRawHandleOrSocket for PipeReader {
442    #[inline]
443    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
444        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
445    }
446}
447
448#[cfg(any(test, feature = "os_pipe"))]
449impl AsRawHandleOrSocket for PipeWriter {
450    #[inline]
451    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
452        RawHandleOrSocket::unowned_from_raw_handle(Self::as_raw_handle(self))
453    }
454}
455
456#[cfg(feature = "socket2")]
457impl AsRawHandleOrSocket for socket2::Socket {
458    #[inline]
459    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
460        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
461    }
462}
463
464#[cfg(feature = "use_mio_net")]
465impl AsRawHandleOrSocket for mio::net::TcpStream {
466    #[inline]
467    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
468        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
469    }
470}
471
472#[cfg(feature = "use_mio_net")]
473impl AsRawHandleOrSocket for mio::net::TcpListener {
474    #[inline]
475    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
476        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
477    }
478}
479
480#[cfg(feature = "use_mio_net")]
481impl AsRawHandleOrSocket for mio::net::UdpSocket {
482    #[inline]
483    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
484        RawHandleOrSocket::unowned_from_raw_socket(Self::as_raw_socket(self))
485    }
486}
487
488impl IntoRawHandleOrSocket for File {
489    #[inline]
490    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
491        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
492    }
493}
494
495impl IntoRawHandleOrSocket for ChildStdin {
496    #[inline]
497    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
498        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
499    }
500}
501
502impl IntoRawHandleOrSocket for ChildStdout {
503    #[inline]
504    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
505        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
506    }
507}
508
509impl IntoRawHandleOrSocket for ChildStderr {
510    #[inline]
511    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
512        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
513    }
514}
515
516impl IntoRawHandleOrSocket for TcpStream {
517    #[inline]
518    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
519        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
520    }
521}
522
523impl IntoRawHandleOrSocket for TcpListener {
524    #[inline]
525    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
526        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
527    }
528}
529
530impl IntoRawHandleOrSocket for UdpSocket {
531    #[inline]
532    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
533        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
534    }
535}
536
537#[cfg(feature = "os_pipe")]
538impl IntoRawHandleOrSocket for PipeReader {
539    #[inline]
540    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
541        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
542    }
543}
544
545#[cfg(feature = "os_pipe")]
546impl IntoRawHandleOrSocket for PipeWriter {
547    #[inline]
548    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
549        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
550    }
551}
552
553#[cfg(feature = "socket2")]
554impl IntoRawHandleOrSocket for socket2::Socket {
555    #[inline]
556    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
557        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
558    }
559}
560
561#[cfg(feature = "use_mio_net")]
562impl IntoRawHandleOrSocket for mio::net::TcpStream {
563    #[inline]
564    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
565        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
566    }
567}
568
569#[cfg(feature = "use_mio_net")]
570impl IntoRawHandleOrSocket for mio::net::TcpListener {
571    #[inline]
572    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
573        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
574    }
575}
576
577#[cfg(feature = "use_mio_net")]
578impl IntoRawHandleOrSocket for mio::net::UdpSocket {
579    #[inline]
580    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
581        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
582    }
583}
584
585#[cfg(feature = "async-std")]
586impl IntoRawHandleOrSocket for async_std::fs::File {
587    #[inline]
588    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
589        RawHandleOrSocket::unowned_from_raw_handle(Self::into_raw_handle(self))
590    }
591}
592
593#[cfg(feature = "async-std")]
594impl IntoRawHandleOrSocket for async_std::net::TcpStream {
595    #[inline]
596    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
597        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
598    }
599}
600
601#[cfg(feature = "async-std")]
602impl IntoRawHandleOrSocket for async_std::net::TcpListener {
603    #[inline]
604    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
605        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
606    }
607}
608
609#[cfg(feature = "async-std")]
610impl IntoRawHandleOrSocket for async_std::net::UdpSocket {
611    #[inline]
612    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
613        RawHandleOrSocket::unowned_from_raw_socket(Self::into_raw_socket(self))
614    }
615}