1use crate::grip::{AsRawGrip, FromRawGrip, OwnedGrip};
4use crate::raw::{RawReadable, RawWriteable};
5#[cfg(not(windows))]
6use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
7use std::fmt;
8use std::io::{self, IoSlice, IoSliceMut, Read, Write};
9#[cfg(all(doc, not(windows)))]
10use std::net::TcpStream;
11#[cfg(unix)]
12use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
13#[cfg(target_os = "wasi")]
14use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd};
15#[cfg(windows)]
16use {
17 crate::os::windows::{
18 AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, FromRawHandleOrSocket,
19 IntoRawHandleOrSocket, OwnedHandleOrSocket,
20 },
21 io_lifetimes::OwnedHandle,
22 std::os::windows::io::{FromRawHandle, IntoRawHandle},
23};
24
25#[repr(transparent)]
35pub struct OwnedReadable(RawReadable);
36
37#[repr(transparent)]
47pub struct OwnedWriteable(RawWriteable);
48
49#[cfg(not(windows))]
51impl AsFd for OwnedReadable {
52 #[inline]
53 fn as_fd(&self) -> BorrowedFd<'_> {
54 unsafe { BorrowedFd::borrow_raw(self.0.as_raw_fd()) }
55 }
56}
57
58#[cfg(not(windows))]
60impl From<OwnedReadable> for OwnedFd {
61 #[inline]
62 fn from(owned: OwnedReadable) -> Self {
63 unsafe { Self::from_raw_fd(owned.0.into_raw_fd()) }
64 }
65}
66
67#[cfg(not(windows))]
69impl From<OwnedFd> for OwnedReadable {
70 #[inline]
71 fn from(fd: OwnedFd) -> Self {
72 unsafe { Self(RawReadable::from_raw_fd(fd.into_raw_fd())) }
73 }
74}
75
76#[cfg(not(windows))]
78impl AsFd for OwnedWriteable {
79 #[inline]
80 fn as_fd(&self) -> BorrowedFd<'_> {
81 unsafe { BorrowedFd::borrow_raw(self.0.as_raw_fd()) }
82 }
83}
84
85#[cfg(not(windows))]
87impl From<OwnedWriteable> for OwnedFd {
88 #[inline]
89 fn from(owned: OwnedWriteable) -> Self {
90 unsafe { Self::from_raw_fd(owned.0.as_raw_fd()) }
91 }
92}
93
94#[cfg(not(windows))]
96impl From<OwnedFd> for OwnedWriteable {
97 #[inline]
98 fn from(fd: OwnedFd) -> Self {
99 unsafe { Self(RawWriteable::from_raw_fd(fd.into_raw_fd())) }
100 }
101}
102
103#[cfg(windows)]
107impl AsHandleOrSocket for OwnedReadable {
108 #[inline]
109 fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
110 unsafe { BorrowedHandleOrSocket::borrow_raw(self.0.as_raw_handle_or_socket()) }
111 }
112}
113
114#[cfg(windows)]
116impl From<OwnedReadable> for OwnedHandleOrSocket {
117 #[inline]
118 fn from(readable: OwnedReadable) -> Self {
119 unsafe {
120 OwnedHandleOrSocket::from_raw_handle_or_socket(readable.0.into_raw_handle_or_socket())
121 }
122 }
123}
124
125#[cfg(windows)]
127impl From<OwnedHandleOrSocket> for OwnedReadable {
128 #[inline]
129 fn from(handle_or_socket: OwnedHandleOrSocket) -> Self {
130 unsafe {
131 Self(RawReadable::from_raw_handle_or_socket(
132 handle_or_socket.into_raw_handle_or_socket(),
133 ))
134 }
135 }
136}
137
138#[cfg(windows)]
140impl From<OwnedHandle> for OwnedReadable {
141 #[inline]
142 fn from(handle: OwnedHandle) -> Self {
143 unsafe { Self(RawReadable::from_raw_handle(handle.into_raw_handle())) }
144 }
145}
146
147#[cfg(windows)]
149impl AsHandleOrSocket for OwnedWriteable {
150 #[inline]
151 fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
152 unsafe { BorrowedHandleOrSocket::borrow_raw(self.0.as_raw_handle_or_socket()) }
153 }
154}
155
156#[cfg(windows)]
158impl From<OwnedWriteable> for OwnedHandleOrSocket {
159 #[inline]
160 fn from(writeable: OwnedWriteable) -> Self {
161 unsafe {
162 OwnedHandleOrSocket::from_raw_handle_or_socket(writeable.0.into_raw_handle_or_socket())
163 }
164 }
165}
166
167#[cfg(windows)]
169impl From<OwnedHandleOrSocket> for OwnedWriteable {
170 #[inline]
171 fn from(handle_or_socket: OwnedHandleOrSocket) -> Self {
172 unsafe {
173 Self(RawWriteable::from_raw_handle_or_socket(
174 handle_or_socket.into_raw_handle_or_socket(),
175 ))
176 }
177 }
178}
179
180#[cfg(windows)]
182impl From<OwnedHandle> for OwnedWriteable {
183 #[inline]
184 fn from(handle: OwnedHandle) -> Self {
185 unsafe { Self(RawWriteable::from_raw_handle(handle.into_raw_handle())) }
186 }
187}
188
189#[cfg(not(windows))]
190impl Read for OwnedReadable {
191 #[inline]
192 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
193 self.0.read(buf)
194 }
195
196 #[inline]
197 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
198 self.0.read_vectored(bufs)
199 }
200
201 #[cfg(can_vector)]
202 #[inline]
203 fn is_read_vectored(&self) -> bool {
204 self.0.is_read_vectored()
205 }
206
207 #[inline]
208 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
209 self.0.read_to_end(buf)
210 }
211
212 #[inline]
213 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
214 self.0.read_to_string(buf)
215 }
216
217 #[inline]
218 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
219 self.0.read_exact(buf)
220 }
221}
222
223#[cfg(windows)]
224impl Read for OwnedReadable {
225 #[inline]
226 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
227 self.0.read(buf)
228 }
229
230 #[inline]
231 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
232 self.0.read_vectored(bufs)
233 }
234
235 #[cfg(can_vector)]
236 #[inline]
237 fn is_read_vectored(&self) -> bool {
238 self.0.is_read_vectored()
239 }
240
241 #[inline]
242 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
243 self.0.read_to_end(buf)
244 }
245
246 #[inline]
247 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
248 self.0.read_to_string(buf)
249 }
250
251 #[inline]
252 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
253 self.0.read_exact(buf)
254 }
255}
256
257#[cfg(not(windows))]
258impl Write for OwnedWriteable {
259 #[inline]
260 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
261 self.0.write(buf)
262 }
263
264 #[inline]
265 fn flush(&mut self) -> io::Result<()> {
266 self.0.flush()
267 }
268
269 #[inline]
270 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
271 self.0.write_vectored(bufs)
272 }
273
274 #[cfg(can_vector)]
275 #[inline]
276 fn is_write_vectored(&self) -> bool {
277 self.0.is_write_vectored()
278 }
279
280 #[inline]
281 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
282 self.0.write_all(buf)
283 }
284
285 #[cfg(write_all_vectored)]
286 #[inline]
287 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
288 self.0.write_all_vectored(bufs)
289 }
290
291 #[inline]
292 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
293 self.0.write_fmt(fmt)
294 }
295}
296
297#[cfg(windows)]
298impl Write for OwnedWriteable {
299 #[inline]
300 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
301 self.0.write(buf)
302 }
303
304 #[inline]
305 fn flush(&mut self) -> io::Result<()> {
306 self.0.flush()
307 }
308
309 #[inline]
310 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
311 self.0.write_vectored(bufs)
312 }
313
314 #[cfg(can_vector)]
315 #[inline]
316 fn is_write_vectored(&self) -> bool {
317 self.0.is_write_vectored()
318 }
319
320 #[inline]
321 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
322 self.0.write_all(buf)
323 }
324
325 #[cfg(write_all_vectored)]
326 #[inline]
327 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
328 self.0.write_all_vectored(bufs)
329 }
330
331 #[inline]
332 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
333 self.0.write_fmt(fmt)
334 }
335}
336
337impl Drop for OwnedReadable {
338 #[inline]
339 fn drop(&mut self) {
340 unsafe {
341 let _owned = OwnedGrip::from_raw_grip(self.0.as_raw_grip());
342 }
343 }
344}
345
346impl Drop for OwnedWriteable {
347 #[inline]
348 fn drop(&mut self) {
349 unsafe {
350 let _owned = OwnedGrip::from_raw_grip(self.0.as_raw_grip());
351 }
352 }
353}
354
355#[cfg(not(windows))]
356impl fmt::Debug for OwnedReadable {
357 #[allow(clippy::missing_inline_in_public_items)]
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 f.debug_struct("OwnedReadable")
361 .field("fd", &self.0)
362 .finish()
363 }
364}
365
366#[cfg(windows)]
367impl fmt::Debug for OwnedReadable {
368 #[allow(clippy::missing_inline_in_public_items)]
369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370 f.debug_struct("OwnedReadable")
372 .field("handle_or_socket", &self.0)
373 .finish()
374 }
375}
376
377#[cfg(not(windows))]
378impl fmt::Debug for OwnedWriteable {
379 #[allow(clippy::missing_inline_in_public_items)]
380 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
381 f.debug_struct("OwnedWriteable")
383 .field("fd", &self.0)
384 .finish()
385 }
386}
387
388#[cfg(windows)]
389impl fmt::Debug for OwnedWriteable {
390 #[allow(clippy::missing_inline_in_public_items)]
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 f.debug_struct("OwnedWriteable")
394 .field("handle_or_socket", &self.0)
395 .finish()
396 }
397}