1use crate::grip::RawGrip;
4#[cfg(not(windows))]
5use crate::os::rustix::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
6use io_lifetimes::raw::RawFilelike;
7use io_lifetimes::views::FilelikeView;
8use std::fmt;
9use std::fs::File;
10use std::io::{self, IoSlice, IoSliceMut, Read, Write};
11#[cfg(all(doc, not(windows)))]
12use std::net::TcpStream;
13#[cfg(windows)]
14use {
15 crate::os::windows::{
16 AsRawHandleOrSocket, FromRawHandleOrSocket, IntoRawHandleOrSocket, RawEnum,
17 RawHandleOrSocket,
18 },
19 io_lifetimes::raw::RawSocketlike,
20 io_lifetimes::views::SocketlikeView,
21 std::net::TcpStream,
22 std::os::windows::io::{FromRawHandle, RawHandle},
23};
24
25#[derive(Copy, Clone)]
36#[repr(transparent)]
37pub struct RawReadable(RawGrip);
38
39#[derive(Copy, Clone)]
50#[repr(transparent)]
51pub struct RawWriteable(RawGrip);
52
53#[cfg(not(windows))]
55impl AsRawFd for RawReadable {
56 #[inline]
57 fn as_raw_fd(&self) -> RawFd {
58 self.0
59 }
60}
61
62#[cfg(not(windows))]
64impl IntoRawFd for RawReadable {
65 #[inline]
66 fn into_raw_fd(self) -> RawFd {
67 self.0
68 }
69}
70
71#[cfg(not(windows))]
73impl FromRawFd for RawReadable {
74 #[inline]
75 unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
76 Self(raw_fd)
77 }
78}
79
80#[cfg(not(windows))]
82impl AsRawFd for RawWriteable {
83 #[inline]
84 fn as_raw_fd(&self) -> RawFd {
85 self.0
86 }
87}
88
89#[cfg(not(windows))]
91impl IntoRawFd for RawWriteable {
92 #[inline]
93 fn into_raw_fd(self) -> RawFd {
94 self.0
95 }
96}
97
98#[cfg(not(windows))]
100impl FromRawFd for RawWriteable {
101 #[inline]
102 unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
103 Self(raw_fd)
104 }
105}
106
107#[cfg(windows)]
111impl AsRawHandleOrSocket for RawReadable {
112 #[inline]
113 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
114 self.0
115 }
116}
117
118#[cfg(windows)]
120impl IntoRawHandleOrSocket for RawReadable {
121 #[inline]
122 fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
123 self.0
124 }
125}
126
127#[cfg(windows)]
129impl FromRawHandleOrSocket for RawReadable {
130 #[inline]
131 unsafe fn from_raw_handle_or_socket(raw_handle_or_socket: RawHandleOrSocket) -> Self {
132 Self(raw_handle_or_socket)
133 }
134}
135
136#[cfg(windows)]
138impl FromRawHandle for RawReadable {
139 #[inline]
140 unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
141 Self(RawHandleOrSocket::unowned_from_raw_handle(raw_handle))
142 }
143}
144
145#[cfg(windows)]
147impl AsRawHandleOrSocket for RawWriteable {
148 #[inline]
149 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
150 self.0
151 }
152}
153
154#[cfg(windows)]
156impl IntoRawHandleOrSocket for RawWriteable {
157 #[inline]
158 fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
159 self.0
160 }
161}
162
163#[cfg(windows)]
165impl FromRawHandleOrSocket for RawWriteable {
166 #[inline]
167 unsafe fn from_raw_handle_or_socket(raw_handle_or_socket: RawHandleOrSocket) -> Self {
168 Self(raw_handle_or_socket)
169 }
170}
171
172#[cfg(windows)]
174impl FromRawHandle for RawWriteable {
175 #[inline]
176 unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
177 Self(RawHandleOrSocket::unowned_from_raw_handle(raw_handle))
178 }
179}
180
181#[inline]
182unsafe fn as_file_view<'a>(file: RawFilelike) -> FilelikeView<'a, File> {
183 FilelikeView::<'a>::view_raw(file)
184}
185
186#[cfg(windows)]
187#[inline]
188unsafe fn as_socket_view<'a>(socket: RawSocketlike) -> SocketlikeView<'a, TcpStream> {
189 SocketlikeView::<'a>::view_raw(socket)
190}
191
192#[cfg(not(windows))]
193impl Read for RawReadable {
194 #[inline]
195 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
196 unsafe { &*as_file_view(self.0) }.read(buf)
200 }
201
202 #[inline]
203 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
204 unsafe { &*as_file_view(self.0) }.read_vectored(bufs)
205 }
206
207 #[cfg(can_vector)]
208 #[inline]
209 fn is_read_vectored(&self) -> bool {
210 unsafe { &*as_file_view(self.0) }.is_read_vectored()
211 }
212
213 #[inline]
214 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
215 unsafe { &*as_file_view(self.0) }.read_to_end(buf)
216 }
217
218 #[inline]
219 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
220 unsafe { &*as_file_view(self.0) }.read_to_string(buf)
221 }
222
223 #[inline]
224 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
225 unsafe { &*as_file_view(self.0) }.read_exact(buf)
226 }
227}
228
229#[cfg(windows)]
230impl Read for RawReadable {
231 #[inline]
232 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
233 match self.0 .0 {
234 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.read(buf),
235 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.read(buf),
236 RawEnum::Stdio(ref mut stdio) => stdio.read(buf),
237 }
238 }
239
240 #[inline]
241 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
242 match self.0 .0 {
243 RawEnum::Handle(raw_handle) => {
244 unsafe { &*as_file_view(raw_handle) }.read_vectored(bufs)
245 }
246 RawEnum::Socket(raw_socket) => {
247 unsafe { &*as_socket_view(raw_socket) }.read_vectored(bufs)
248 }
249 RawEnum::Stdio(ref mut stdio) => stdio.read_vectored(bufs),
250 }
251 }
252
253 #[cfg(can_vector)]
254 #[inline]
255 fn is_read_vectored(&self) -> bool {
256 match self.0 .0 {
257 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.is_read_vectored(),
258 RawEnum::Socket(raw_socket) => {
259 unsafe { &*as_socket_view(raw_socket) }.is_read_vectored()
260 }
261 RawEnum::Stdio(ref stdio) => stdio.is_read_vectored(),
262 }
263 }
264
265 #[inline]
266 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
267 match self.0 .0 {
268 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.read_to_end(buf),
269 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.read_to_end(buf),
270 RawEnum::Stdio(ref mut stdio) => stdio.read_to_end(buf),
271 }
272 }
273
274 #[inline]
275 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
276 match self.0 .0 {
277 RawEnum::Handle(raw_handle) => {
278 unsafe { &*as_file_view(raw_handle) }.read_to_string(buf)
279 }
280 RawEnum::Socket(raw_socket) => {
281 unsafe { &*as_socket_view(raw_socket) }.read_to_string(buf)
282 }
283 RawEnum::Stdio(ref mut stdio) => stdio.read_to_string(buf),
284 }
285 }
286
287 #[inline]
288 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
289 match self.0 .0 {
290 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.read_exact(buf),
291 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.read_exact(buf),
292 RawEnum::Stdio(ref mut stdio) => stdio.read_exact(buf),
293 }
294 }
295}
296
297#[cfg(not(windows))]
298impl Write for RawWriteable {
299 #[inline]
300 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
301 unsafe { &*as_file_view(self.0) }.write(buf)
305 }
306
307 #[inline]
308 fn flush(&mut self) -> io::Result<()> {
309 unsafe { &*as_file_view(self.0) }.flush()
310 }
311
312 #[inline]
313 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
314 unsafe { &*as_file_view(self.0) }.write_vectored(bufs)
315 }
316
317 #[cfg(can_vector)]
318 #[inline]
319 fn is_write_vectored(&self) -> bool {
320 unsafe { &*as_file_view(self.0) }.is_write_vectored()
321 }
322
323 #[inline]
324 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
325 unsafe { &*as_file_view(self.0) }.write_all(buf)
326 }
327
328 #[cfg(write_all_vectored)]
329 #[inline]
330 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
331 unsafe { &*as_file_view(self.0) }.write_all_vectored(bufs)
332 }
333
334 #[inline]
335 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
336 unsafe { &*as_file_view(self.0) }.write_fmt(fmt)
337 }
338}
339
340#[cfg(windows)]
341impl Write for RawWriteable {
342 #[inline]
343 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
344 match self.0 .0 {
345 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.write(buf),
346 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.write(buf),
347 RawEnum::Stdio(ref mut stdio) => stdio.write(buf),
348 }
349 }
350
351 #[inline]
352 fn flush(&mut self) -> io::Result<()> {
353 match self.0 .0 {
354 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.flush(),
355 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.flush(),
356 RawEnum::Stdio(ref mut stdio) => stdio.flush(),
357 }
358 }
359
360 #[inline]
361 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
362 match self.0 .0 {
363 RawEnum::Handle(raw_handle) => {
364 unsafe { &*as_file_view(raw_handle) }.write_vectored(bufs)
365 }
366 RawEnum::Socket(raw_socket) => {
367 unsafe { &*as_socket_view(raw_socket) }.write_vectored(bufs)
368 }
369 RawEnum::Stdio(ref mut stdio) => stdio.write_vectored(bufs),
370 }
371 }
372
373 #[cfg(can_vector)]
374 #[inline]
375 fn is_write_vectored(&self) -> bool {
376 match self.0 .0 {
377 RawEnum::Handle(raw_handle) => {
378 unsafe { &*as_file_view(raw_handle) }.is_write_vectored()
379 }
380 RawEnum::Socket(raw_socket) => {
381 unsafe { &*as_socket_view(raw_socket) }.is_write_vectored()
382 }
383 RawEnum::Stdio(ref stdio) => stdio.is_write_vectored(),
384 }
385 }
386
387 #[inline]
388 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
389 match self.0 .0 {
390 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.write_all(buf),
391 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.write_all(buf),
392 RawEnum::Stdio(ref mut stdio) => stdio.write_all(buf),
393 }
394 }
395
396 #[cfg(write_all_vectored)]
397 #[inline]
398 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
399 match self.0 .0 {
400 RawEnum::Handle(raw_handle) => {
401 unsafe { &*as_file_view(raw_handle) }.write_all_vectored(bufs)
402 }
403 RawEnum::Socket(raw_socket) => {
404 unsafe { &*as_socket_view(raw_socket) }.write_all_vectored(bufs)
405 }
406 RawEnum::Stdio(ref mut stdio) => stdio.write_all_vectored(bufs),
407 }
408 }
409
410 #[inline]
411 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
412 match self.0 .0 {
413 RawEnum::Handle(raw_handle) => unsafe { &*as_file_view(raw_handle) }.write_fmt(fmt),
414 RawEnum::Socket(raw_socket) => unsafe { &*as_socket_view(raw_socket) }.write_fmt(fmt),
415 RawEnum::Stdio(ref mut stdio) => stdio.write_fmt(fmt),
416 }
417 }
418}
419
420#[cfg(not(windows))]
421impl fmt::Debug for RawReadable {
422 #[allow(clippy::missing_inline_in_public_items)]
423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424 f.debug_struct("RawReadable")
426 .field("raw_fd", &self.0)
427 .finish()
428 }
429}
430
431#[cfg(windows)]
432impl fmt::Debug for RawReadable {
433 #[allow(clippy::missing_inline_in_public_items)]
434 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
435 f.debug_struct("RawReadable")
437 .field("raw_handle_or_socket", &self.0)
438 .finish()
439 }
440}
441
442#[cfg(not(windows))]
443impl fmt::Debug for RawWriteable {
444 #[allow(clippy::missing_inline_in_public_items)]
445 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
446 f.debug_struct("RawWriteable")
448 .field("raw_fd", &self.0)
449 .finish()
450 }
451}
452
453#[cfg(windows)]
454impl fmt::Debug for RawWriteable {
455 #[allow(clippy::missing_inline_in_public_items)]
456 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457 f.debug_struct("RawWriteable")
459 .field("raw_handle_or_socket", &self.0)
460 .finish()
461 }
462}