• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"))]
35 
36 mod portability;
37 mod traits;
38 #[cfg(not(io_safety_is_in_std))]
39 mod types;
40 
41 #[cfg(not(io_safety_is_in_std))]
42 mod impls_std;
43 
44 #[cfg(not(io_safety_is_in_std))]
45 #[cfg(any(unix, target_os = "wasi"))]
46 pub use traits::AsFd;
47 #[cfg(not(io_safety_is_in_std))]
48 #[cfg(windows)]
49 pub use traits::{AsHandle, AsSocket};
50 #[cfg(any(unix, target_os = "wasi"))]
51 #[allow(deprecated)]
52 pub use traits::{FromFd, IntoFd};
53 #[cfg(windows)]
54 #[allow(deprecated)]
55 pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
56 
57 #[cfg(not(io_safety_is_in_std))]
58 #[cfg(any(unix, target_os = "wasi"))]
59 pub use types::{BorrowedFd, OwnedFd};
60 #[cfg(not(io_safety_is_in_std))]
61 #[cfg(windows)]
62 pub use types::{
63     BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, NullHandleError,
64     OwnedHandle, OwnedSocket,
65 };
66 
67 #[cfg(io_safety_is_in_std)]
68 #[cfg(unix)]
69 pub use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
70 #[cfg(io_safety_is_in_std)]
71 #[cfg(target_os = "wasi")]
72 pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
73 #[cfg(io_safety_is_in_std)]
74 #[cfg(windows)]
75 pub use std::os::windows::io::{
76     AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError,
77     NullHandleError, OwnedHandle, OwnedSocket,
78 };
79 
80 // io-lifetimes defined `FromFd`/`IntoFd` traits instead of just using
81 // `From`/`Into` because that allowed it to implement them for foreign types,
82 // including std types like File and TcpStream, and popular third-party types.
83 //
84 // std just uses `From`/`Into`, because it defines those traits itself so it
85 // can implement them for std types itself, and std won't be implementing them
86 // for third-party types. However, this means that until `OwnedFd` et al are
87 // stabilized, there will be no impls for third-party traits.
88 //
89 // So we define `FromFd`/`IntoFd` traits, and implement them in terms of
90 // `From`/`Into`,
91 #[cfg(io_safety_is_in_std)]
92 #[cfg(any(unix, target_os = "wasi"))]
93 #[allow(deprecated)]
94 impl<T: From<OwnedFd>> FromFd for T {
95     #[inline]
from_fd(owned_fd: OwnedFd) -> Self96     fn from_fd(owned_fd: OwnedFd) -> Self {
97         owned_fd.into()
98     }
99 }
100 #[cfg(io_safety_is_in_std)]
101 #[cfg(any(unix, target_os = "wasi"))]
102 #[allow(deprecated)]
103 impl<T> IntoFd for T
104 where
105     OwnedFd: From<T>,
106 {
107     #[inline]
into_fd(self) -> OwnedFd108     fn into_fd(self) -> OwnedFd {
109         self.into()
110     }
111 }
112 
113 #[cfg(io_safety_is_in_std)]
114 #[cfg(windows)]
115 #[allow(deprecated)]
116 impl<T: From<OwnedHandle>> FromHandle for T {
117     #[inline]
from_handle(owned_handle: OwnedHandle) -> Self118     fn from_handle(owned_handle: OwnedHandle) -> Self {
119         owned_handle.into()
120     }
121 }
122 #[cfg(io_safety_is_in_std)]
123 #[cfg(windows)]
124 #[allow(deprecated)]
125 impl<T> IntoHandle for T
126 where
127     OwnedHandle: From<T>,
128 {
129     #[inline]
into_handle(self) -> OwnedHandle130     fn into_handle(self) -> OwnedHandle {
131         self.into()
132     }
133 }
134 
135 #[cfg(io_safety_is_in_std)]
136 #[cfg(windows)]
137 #[allow(deprecated)]
138 impl<T: From<OwnedSocket>> FromSocket for T {
139     #[inline]
from_socket(owned_socket: OwnedSocket) -> Self140     fn from_socket(owned_socket: OwnedSocket) -> Self {
141         owned_socket.into()
142     }
143 }
144 #[cfg(io_safety_is_in_std)]
145 #[cfg(windows)]
146 #[allow(deprecated)]
147 impl<T> IntoSocket for T
148 where
149     OwnedSocket: From<T>,
150 {
151     #[inline]
into_socket(self) -> OwnedSocket152     fn into_socket(self) -> OwnedSocket {
153         self.into()
154     }
155 }
156 
157 pub use portability::{
158     AsFilelike, AsSocketlike, BorrowedFilelike, BorrowedSocketlike, FromFilelike, FromSocketlike,
159     IntoFilelike, IntoSocketlike, OwnedFilelike, OwnedSocketlike,
160 };
161 
162 #[cfg(feature = "close")]
163 pub mod example_ffi;
164 pub mod raw;
165 pub mod views;
166 
167 // Ideally, we'd want crates to implement our traits themselves. But for now,
168 // while we're prototyping, we provide a few impls on foreign types.
169 #[cfg(not(io_safety_is_in_std))]
170 #[cfg(feature = "async-std")]
171 mod impls_async_std;
172 #[cfg(not(io_safety_is_in_std))]
173 #[cfg(feature = "fs-err")]
174 mod impls_fs_err;
175 #[cfg(not(io_safety_is_in_std))]
176 #[cfg(feature = "mio")]
177 mod impls_mio;
178 #[cfg(not(target_os = "wasi"))]
179 #[cfg(not(io_safety_is_in_std))]
180 #[cfg(feature = "os_pipe")]
181 mod impls_os_pipe;
182 #[cfg(not(io_safety_is_in_std))]
183 #[cfg(feature = "socket2")]
184 mod impls_socket2;
185 #[cfg(not(io_safety_is_in_std))]
186 #[cfg(feature = "tokio")]
187 mod impls_tokio;
188