io_lifetimes/
lib.rs

1//! Experimental new types and traits to replace the `Raw` family of types and
2//! traits.
3//!
4//! This API has much conceptual similarity with the `Raw` API, but introduces
5//! explicit concepts of ownership and borrowing:
6//!
7//! | `Raw` API  | This experimental API    |
8//! | ---------- | ------------------------ |
9//! | `Raw*`     | `Borrowed*` and `Owned*` |
10//! | `AsRaw*`   | `As*`                    |
11//! | `IntoRaw*` | `Into*`                  |
12//! | `FromRaw*` | `From*`                  |
13//!
14//! This gives it several advantages:
15//!
16//!  - Less `unsafe` in user code!
17//!
18//!  - Easier to understand ownership.
19//!
20//!  - It avoids the inconsistency where `AsRawFd` and `IntoRawFd` return
21//!    `RawFd` values that users ought to be able to trust, but aren't unsafe,
22//!    so it's possible to fail to uphold this trust in purely safe Rust.
23//!
24//!  - It enables a number of safe and portable convenience features, such as
25//!    [safe typed views] and [from+into conversions].
26//!
27//! [safe typed views]: AsFilelike::as_filelike_view
28//! [from+into conversions]: FromFilelike::from_into_filelike
29
30#![deny(missing_docs)]
31// Work around <https://github.com/rust-lang/rust/issues/103306>.
32#![cfg_attr(all(wasi_ext, target_os = "wasi"), feature(wasi_ext))]
33// Currently supported platforms.
34#![cfg(any(unix, windows, target_os = "wasi", target_os = "hermit"))]
35#![cfg_attr(docsrs, feature(doc_cfg))]
36
37mod portability;
38mod traits;
39
40#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
41#[allow(deprecated)]
42pub use traits::{FromFd, IntoFd};
43#[cfg(windows)]
44#[allow(deprecated)]
45pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
46
47#[cfg(target_os = "hermit")]
48pub use std::os::hermit::io::{AsFd, BorrowedFd, OwnedFd};
49#[cfg(unix)]
50pub use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
51#[cfg(target_os = "wasi")]
52pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
53#[cfg(windows)]
54pub use std::os::windows::io::{
55    AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError,
56    NullHandleError, OwnedHandle, OwnedSocket,
57};
58
59// io-lifetimes defined `FromFd`/`IntoFd` traits instead of just using
60// `From`/`Into` because that allowed it to implement them for foreign types,
61// including std types like File and TcpStream, and popular third-party types.
62//
63// std just uses `From`/`Into`, because it defines those traits itself so it
64// can implement them for std types itself, and std won't be implementing them
65// for third-party types. However, this means that until `OwnedFd` et al are
66// stabilized, there will be no impls for third-party traits.
67//
68// So we define `FromFd`/`IntoFd` traits, and implement them in terms of
69// `From`/`Into`,
70#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
71#[allow(deprecated)]
72impl<T: From<OwnedFd>> FromFd for T {
73    #[inline]
74    fn from_fd(owned_fd: OwnedFd) -> Self {
75        owned_fd.into()
76    }
77}
78#[cfg(any(unix, target_os = "wasi", target_os = "hermit"))]
79#[allow(deprecated)]
80impl<T> IntoFd for T
81where
82    OwnedFd: From<T>,
83{
84    #[inline]
85    fn into_fd(self) -> OwnedFd {
86        self.into()
87    }
88}
89
90#[cfg(windows)]
91#[allow(deprecated)]
92impl<T: From<OwnedHandle>> FromHandle for T {
93    #[inline]
94    fn from_handle(owned_handle: OwnedHandle) -> Self {
95        owned_handle.into()
96    }
97}
98#[cfg(windows)]
99#[allow(deprecated)]
100impl<T> IntoHandle for T
101where
102    OwnedHandle: From<T>,
103{
104    #[inline]
105    fn into_handle(self) -> OwnedHandle {
106        self.into()
107    }
108}
109
110#[cfg(windows)]
111#[allow(deprecated)]
112impl<T: From<OwnedSocket>> FromSocket for T {
113    #[inline]
114    fn from_socket(owned_socket: OwnedSocket) -> Self {
115        owned_socket.into()
116    }
117}
118#[cfg(windows)]
119#[allow(deprecated)]
120impl<T> IntoSocket for T
121where
122    OwnedSocket: From<T>,
123{
124    #[inline]
125    fn into_socket(self) -> OwnedSocket {
126        self.into()
127    }
128}
129
130pub use portability::{
131    AsFilelike, AsSocketlike, BorrowedFilelike, BorrowedSocketlike, FromFilelike, FromSocketlike,
132    IntoFilelike, IntoSocketlike, OwnedFilelike, OwnedSocketlike,
133};
134
135#[cfg(feature = "close")]
136#[cfg_attr(docsrs, doc(cfg(feature = "close")))]
137pub mod example_ffi;
138pub mod raw;
139pub mod views;