io_extras/
read_write.rs

1//! Traits for working with types that may have up to two I/O objects.
2
3#[cfg(windows)]
4use crate::os::windows::{
5    AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, RawHandleOrSocket,
6};
7use std::fs::File;
8use std::net::TcpStream;
9#[cfg(unix)]
10use std::os::unix::net::UnixStream;
11#[cfg(not(windows))]
12use {
13    crate::os::rustix::{AsRawFd, RawFd},
14    io_lifetimes::{AsFd, BorrowedFd},
15};
16
17/// Like [`AsRawFd`], but for types which may have one or two file descriptors,
18/// for reading and writing.
19///
20/// For types that only have one, both functions return the same value.
21#[cfg(not(windows))]
22pub trait AsRawReadWriteFd {
23    /// Extracts the raw file descriptor for reading.
24    ///
25    /// Like [`AsRawFd::as_raw_fd`], but returns the reading file descriptor.
26    fn as_raw_read_fd(&self) -> RawFd;
27
28    /// Extracts the raw file descriptor for writing.
29    ///
30    /// Like [`AsRawFd::as_raw_fd`], but returns the writing file descriptor.
31    fn as_raw_write_fd(&self) -> RawFd;
32}
33
34/// Like [`AsFd`], but for types which may have one or two file descriptors,
35/// for reading and writing.
36///
37/// For types that only have one, both functions return the same value.
38#[cfg(not(windows))]
39pub trait AsReadWriteFd {
40    /// Extracts the file descriptor for reading.
41    ///
42    /// Like [`AsFd::as_fd`], but returns the reading file descriptor.
43    fn as_read_fd(&self) -> BorrowedFd<'_>;
44
45    /// Extracts the file descriptor for writing.
46    ///
47    /// Like [`AsFd::as_fd`], but returns the writing file descriptor.
48    fn as_write_fd(&self) -> BorrowedFd<'_>;
49}
50
51/// Like [`AsRawHandleOrSocket`], but for types which may have one or two
52/// handles or sockets, for reading and writing.
53///
54/// For types that only have one, both functions return the same value.
55#[cfg(windows)]
56pub trait AsRawReadWriteHandleOrSocket {
57    /// Extracts the raw handle or socket for reading.
58    ///
59    /// Like [`AsRawHandleOrSocket::as_raw_handle_or_socket`], but returns the
60    /// reading handle.
61    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket;
62
63    /// Extracts the raw handle or socket for writing.
64    ///
65    /// Like [`AsRawHandleOrSocket::as_raw_handle_or_socket`], but returns the
66    /// writing handle.
67    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket;
68}
69
70/// Like [`AsHandleOrSocket`], but for types which may have one or two
71/// handles or sockets, for reading and writing.
72///
73/// For types that only have one, both functions return the same value.
74#[cfg(windows)]
75pub trait AsReadWriteHandleOrSocket {
76    /// Extracts the handle or socket for reading.
77    ///
78    /// Like [`AsHandleOrSocket::as_handle_or_socket`], but returns the
79    /// reading handle.
80    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_>;
81
82    /// Extracts the handle or socket for writing.
83    ///
84    /// Like [`AsHandleOrSocket::as_handle_or_socket`], but returns the
85    /// writing handle.
86    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_>;
87}
88
89#[cfg(not(windows))]
90impl AsRawReadWriteFd for File {
91    #[inline]
92    fn as_raw_read_fd(&self) -> RawFd {
93        self.as_raw_fd()
94    }
95
96    #[inline]
97    fn as_raw_write_fd(&self) -> RawFd {
98        self.as_raw_fd()
99    }
100}
101
102#[cfg(not(windows))]
103impl AsReadWriteFd for File {
104    #[inline]
105    fn as_read_fd(&self) -> BorrowedFd<'_> {
106        self.as_fd()
107    }
108
109    #[inline]
110    fn as_write_fd(&self) -> BorrowedFd<'_> {
111        self.as_fd()
112    }
113}
114
115#[cfg(windows)]
116impl AsRawReadWriteHandleOrSocket for File {
117    #[inline]
118    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
119        self.as_raw_handle_or_socket()
120    }
121
122    #[inline]
123    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
124        self.as_raw_handle_or_socket()
125    }
126}
127
128#[cfg(windows)]
129impl AsReadWriteHandleOrSocket for File {
130    #[inline]
131    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
132        self.as_handle_or_socket()
133    }
134
135    #[inline]
136    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
137        self.as_handle_or_socket()
138    }
139}
140
141#[cfg(not(windows))]
142impl AsRawReadWriteFd for TcpStream {
143    #[inline]
144    fn as_raw_read_fd(&self) -> RawFd {
145        self.as_raw_fd()
146    }
147
148    #[inline]
149    fn as_raw_write_fd(&self) -> RawFd {
150        self.as_raw_fd()
151    }
152}
153
154#[cfg(not(windows))]
155impl AsReadWriteFd for TcpStream {
156    #[inline]
157    fn as_read_fd(&self) -> BorrowedFd<'_> {
158        self.as_fd()
159    }
160
161    #[inline]
162    fn as_write_fd(&self) -> BorrowedFd<'_> {
163        self.as_fd()
164    }
165}
166
167#[cfg(windows)]
168impl AsRawReadWriteHandleOrSocket for TcpStream {
169    #[inline]
170    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
171        self.as_raw_handle_or_socket()
172    }
173
174    #[inline]
175    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
176        self.as_raw_handle_or_socket()
177    }
178}
179
180#[cfg(windows)]
181impl AsReadWriteHandleOrSocket for TcpStream {
182    #[inline]
183    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
184        self.as_handle_or_socket()
185    }
186
187    #[inline]
188    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
189        self.as_handle_or_socket()
190    }
191}
192
193#[cfg(unix)]
194impl AsRawReadWriteFd for UnixStream {
195    #[inline]
196    fn as_raw_read_fd(&self) -> RawFd {
197        self.as_raw_fd()
198    }
199
200    #[inline]
201    fn as_raw_write_fd(&self) -> RawFd {
202        self.as_raw_fd()
203    }
204}
205
206#[cfg(unix)]
207impl AsReadWriteFd for UnixStream {
208    #[inline]
209    fn as_read_fd(&self) -> BorrowedFd<'_> {
210        self.as_fd()
211    }
212
213    #[inline]
214    fn as_write_fd(&self) -> BorrowedFd<'_> {
215        self.as_fd()
216    }
217}
218
219#[cfg(all(feature = "async-std", not(windows)))]
220impl AsRawReadWriteFd for async_std::fs::File {
221    #[inline]
222    fn as_raw_read_fd(&self) -> RawFd {
223        self.as_raw_fd()
224    }
225
226    #[inline]
227    fn as_raw_write_fd(&self) -> RawFd {
228        self.as_raw_fd()
229    }
230}
231
232#[cfg(all(feature = "async-std", not(windows)))]
233impl AsReadWriteFd for async_std::fs::File {
234    #[inline]
235    fn as_read_fd(&self) -> BorrowedFd<'_> {
236        self.as_fd()
237    }
238
239    #[inline]
240    fn as_write_fd(&self) -> BorrowedFd<'_> {
241        self.as_fd()
242    }
243}
244
245#[cfg(all(feature = "async-std", windows))]
246impl AsRawReadWriteHandleOrSocket for async_std::fs::File {
247    #[inline]
248    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
249        self.as_raw_handle_or_socket()
250    }
251
252    #[inline]
253    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
254        self.as_raw_handle_or_socket()
255    }
256}
257
258#[cfg(all(feature = "async-std", windows))]
259impl AsReadWriteHandleOrSocket for async_std::fs::File {
260    #[inline]
261    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
262        self.as_handle_or_socket()
263    }
264
265    #[inline]
266    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
267        self.as_handle_or_socket()
268    }
269}
270
271#[cfg(all(feature = "async-std", not(windows)))]
272impl AsRawReadWriteFd for async_std::net::TcpStream {
273    #[inline]
274    fn as_raw_read_fd(&self) -> RawFd {
275        self.as_raw_fd()
276    }
277
278    #[inline]
279    fn as_raw_write_fd(&self) -> RawFd {
280        self.as_raw_fd()
281    }
282}
283
284#[cfg(all(feature = "async-std", not(windows)))]
285impl AsReadWriteFd for async_std::net::TcpStream {
286    #[inline]
287    fn as_read_fd(&self) -> BorrowedFd<'_> {
288        self.as_fd()
289    }
290
291    #[inline]
292    fn as_write_fd(&self) -> BorrowedFd<'_> {
293        self.as_fd()
294    }
295}
296
297#[cfg(all(feature = "async-std", windows))]
298impl AsRawReadWriteHandleOrSocket for async_std::net::TcpStream {
299    #[inline]
300    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
301        self.as_raw_handle_or_socket()
302    }
303
304    #[inline]
305    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
306        self.as_raw_handle_or_socket()
307    }
308}
309
310#[cfg(all(feature = "async-std", windows))]
311impl AsReadWriteHandleOrSocket for async_std::net::TcpStream {
312    #[inline]
313    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
314        self.as_handle_or_socket()
315    }
316
317    #[inline]
318    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
319        self.as_handle_or_socket()
320    }
321}
322
323#[cfg(all(feature = "async-std", unix))]
324impl AsRawReadWriteFd for async_std::os::unix::net::UnixStream {
325    #[inline]
326    fn as_raw_read_fd(&self) -> RawFd {
327        self.as_raw_fd()
328    }
329
330    #[inline]
331    fn as_raw_write_fd(&self) -> RawFd {
332        self.as_raw_fd()
333    }
334}
335
336#[cfg(all(feature = "async-std", unix))]
337impl AsReadWriteFd for async_std::os::unix::net::UnixStream {
338    #[inline]
339    fn as_read_fd(&self) -> BorrowedFd<'_> {
340        self.as_fd()
341    }
342
343    #[inline]
344    fn as_write_fd(&self) -> BorrowedFd<'_> {
345        self.as_fd()
346    }
347}
348
349#[cfg(all(feature = "tokio", not(windows)))]
350impl AsRawReadWriteFd for tokio::fs::File {
351    #[inline]
352    fn as_raw_read_fd(&self) -> RawFd {
353        self.as_raw_fd()
354    }
355
356    #[inline]
357    fn as_raw_write_fd(&self) -> RawFd {
358        self.as_raw_fd()
359    }
360}
361
362#[cfg(all(feature = "tokio", not(windows)))]
363impl AsReadWriteFd for tokio::fs::File {
364    #[inline]
365    fn as_read_fd(&self) -> BorrowedFd<'_> {
366        self.as_fd()
367    }
368
369    #[inline]
370    fn as_write_fd(&self) -> BorrowedFd<'_> {
371        self.as_fd()
372    }
373}
374
375#[cfg(all(feature = "tokio", windows))]
376impl AsRawReadWriteHandleOrSocket for tokio::fs::File {
377    #[inline]
378    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
379        self.as_raw_handle_or_socket()
380    }
381
382    #[inline]
383    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
384        self.as_raw_handle_or_socket()
385    }
386}
387
388#[cfg(all(feature = "tokio", windows))]
389impl AsReadWriteHandleOrSocket for tokio::fs::File {
390    #[inline]
391    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
392        self.as_handle_or_socket()
393    }
394
395    #[inline]
396    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
397        self.as_handle_or_socket()
398    }
399}
400
401#[cfg(all(feature = "tokio", not(windows)))]
402impl AsRawReadWriteFd for tokio::net::TcpStream {
403    #[inline]
404    fn as_raw_read_fd(&self) -> RawFd {
405        self.as_raw_fd()
406    }
407
408    #[inline]
409    fn as_raw_write_fd(&self) -> RawFd {
410        self.as_raw_fd()
411    }
412}
413
414#[cfg(all(feature = "tokio", not(windows)))]
415impl AsReadWriteFd for tokio::net::TcpStream {
416    #[inline]
417    fn as_read_fd(&self) -> BorrowedFd<'_> {
418        self.as_fd()
419    }
420
421    #[inline]
422    fn as_write_fd(&self) -> BorrowedFd<'_> {
423        self.as_fd()
424    }
425}
426
427#[cfg(all(feature = "tokio", windows))]
428impl AsReadWriteHandleOrSocket for tokio::net::TcpStream {
429    #[inline]
430    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
431        self.as_handle_or_socket()
432    }
433
434    #[inline]
435    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
436        self.as_handle_or_socket()
437    }
438}
439
440#[cfg(all(feature = "tokio", unix))]
441impl AsRawReadWriteFd for tokio::net::UnixStream {
442    #[inline]
443    fn as_raw_read_fd(&self) -> RawFd {
444        self.as_raw_fd()
445    }
446
447    #[inline]
448    fn as_raw_write_fd(&self) -> RawFd {
449        self.as_raw_fd()
450    }
451}
452
453#[cfg(all(feature = "tokio", unix))]
454impl AsReadWriteFd for tokio::net::UnixStream {
455    #[inline]
456    fn as_read_fd(&self) -> BorrowedFd<'_> {
457        self.as_fd()
458    }
459
460    #[inline]
461    fn as_write_fd(&self) -> BorrowedFd<'_> {
462        self.as_fd()
463    }
464}
465
466#[cfg(not(windows))]
467impl<T: AsRawReadWriteFd> AsRawReadWriteFd for Box<T> {
468    #[inline]
469    fn as_raw_read_fd(&self) -> RawFd {
470        (**self).as_raw_read_fd()
471    }
472
473    #[inline]
474    fn as_raw_write_fd(&self) -> RawFd {
475        (**self).as_raw_write_fd()
476    }
477}
478
479#[cfg(not(windows))]
480impl<T: AsReadWriteFd> AsReadWriteFd for Box<T> {
481    #[inline]
482    fn as_read_fd(&self) -> BorrowedFd<'_> {
483        (**self).as_read_fd()
484    }
485
486    #[inline]
487    fn as_write_fd(&self) -> BorrowedFd<'_> {
488        (**self).as_write_fd()
489    }
490}
491
492#[cfg(windows)]
493impl<T: AsRawReadWriteHandleOrSocket> AsRawReadWriteHandleOrSocket for Box<T> {
494    #[inline]
495    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
496        (**self).as_raw_read_handle_or_socket()
497    }
498
499    #[inline]
500    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
501        (**self).as_raw_write_handle_or_socket()
502    }
503}
504
505#[cfg(windows)]
506impl<T: AsReadWriteHandleOrSocket> AsReadWriteHandleOrSocket for Box<T> {
507    #[inline]
508    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
509        (**self).as_read_handle_or_socket()
510    }
511
512    #[inline]
513    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
514        (**self).as_write_handle_or_socket()
515    }
516}
517
518#[cfg(all(not(windows), feature = "socket2"))]
519impl AsRawReadWriteFd for socket2::Socket {
520    #[inline]
521    fn as_raw_read_fd(&self) -> RawFd {
522        self.as_raw_fd()
523    }
524
525    #[inline]
526    fn as_raw_write_fd(&self) -> RawFd {
527        self.as_raw_fd()
528    }
529}
530
531#[cfg(all(not(windows), feature = "socket2"))]
532impl AsReadWriteFd for socket2::Socket {
533    #[inline]
534    fn as_read_fd(&self) -> BorrowedFd<'_> {
535        self.as_fd()
536    }
537
538    #[inline]
539    fn as_write_fd(&self) -> BorrowedFd<'_> {
540        self.as_fd()
541    }
542}
543
544#[cfg(all(windows, feature = "socket2"))]
545impl AsRawReadWriteHandleOrSocket for socket2::Socket {
546    #[inline]
547    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
548        self.as_raw_handle_or_socket()
549    }
550
551    #[inline]
552    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
553        self.as_raw_handle_or_socket()
554    }
555}
556
557#[cfg(all(windows, feature = "socket2"))]
558impl AsReadWriteHandleOrSocket for socket2::Socket {
559    #[inline]
560    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
561        self.as_handle_or_socket()
562    }
563
564    #[inline]
565    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
566        self.as_handle_or_socket()
567    }
568}
569
570#[cfg(all(not(windows), feature = "use_mio_net"))]
571impl AsRawReadWriteFd for mio::net::TcpListener {
572    #[inline]
573    fn as_raw_read_fd(&self) -> RawFd {
574        self.as_raw_fd()
575    }
576
577    #[inline]
578    fn as_raw_write_fd(&self) -> RawFd {
579        self.as_raw_fd()
580    }
581}
582
583#[cfg(all(not(windows), feature = "use_mio_net"))]
584impl AsReadWriteFd for mio::net::TcpListener {
585    #[inline]
586    fn as_read_fd(&self) -> BorrowedFd<'_> {
587        self.as_fd()
588    }
589
590    #[inline]
591    fn as_write_fd(&self) -> BorrowedFd<'_> {
592        self.as_fd()
593    }
594}
595
596#[cfg(all(windows, feature = "use_mio_net"))]
597impl AsRawReadWriteHandleOrSocket for mio::net::TcpListener {
598    #[inline]
599    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
600        self.as_raw_handle_or_socket()
601    }
602
603    #[inline]
604    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
605        self.as_raw_handle_or_socket()
606    }
607}
608
609#[cfg(all(windows, feature = "use_mio_net"))]
610#[cfg(not(io_lifetimes_use_std))] // TODO: Enable once we have mio impls
611impl AsReadWriteHandleOrSocket for mio::net::TcpListener {
612    #[inline]
613    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
614        self.as_handle_or_socket()
615    }
616
617    #[inline]
618    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
619        self.as_handle_or_socket()
620    }
621}
622
623#[cfg(all(not(windows), feature = "use_mio_net"))]
624impl AsRawReadWriteFd for mio::net::TcpStream {
625    #[inline]
626    fn as_raw_read_fd(&self) -> RawFd {
627        self.as_raw_fd()
628    }
629
630    #[inline]
631    fn as_raw_write_fd(&self) -> RawFd {
632        self.as_raw_fd()
633    }
634}
635
636#[cfg(all(not(windows), feature = "use_mio_net"))]
637impl AsReadWriteFd for mio::net::TcpStream {
638    #[inline]
639    fn as_read_fd(&self) -> BorrowedFd<'_> {
640        self.as_fd()
641    }
642
643    #[inline]
644    fn as_write_fd(&self) -> BorrowedFd<'_> {
645        self.as_fd()
646    }
647}
648
649#[cfg(all(windows, feature = "use_mio_net"))]
650impl AsRawReadWriteHandleOrSocket for mio::net::TcpStream {
651    #[inline]
652    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
653        self.as_raw_handle_or_socket()
654    }
655
656    #[inline]
657    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
658        self.as_raw_handle_or_socket()
659    }
660}
661
662#[cfg(all(windows, feature = "use_mio_net"))]
663#[cfg(not(io_lifetimes_use_std))] // TODO: Enable once we have mio impls
664impl AsReadWriteHandleOrSocket for mio::net::TcpStream {
665    #[inline]
666    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
667        self.as_handle_or_socket()
668    }
669
670    #[inline]
671    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
672        self.as_handle_or_socket()
673    }
674}
675
676#[cfg(all(not(windows), feature = "use_mio_net"))]
677impl AsRawReadWriteFd for mio::net::UdpSocket {
678    #[inline]
679    fn as_raw_read_fd(&self) -> RawFd {
680        self.as_raw_fd()
681    }
682
683    #[inline]
684    fn as_raw_write_fd(&self) -> RawFd {
685        self.as_raw_fd()
686    }
687}
688
689#[cfg(all(not(windows), feature = "use_mio_net"))]
690impl AsReadWriteFd for mio::net::UdpSocket {
691    #[inline]
692    fn as_read_fd(&self) -> BorrowedFd<'_> {
693        self.as_fd()
694    }
695
696    #[inline]
697    fn as_write_fd(&self) -> BorrowedFd<'_> {
698        self.as_fd()
699    }
700}
701
702#[cfg(all(windows, feature = "use_mio_net"))]
703impl AsRawReadWriteHandleOrSocket for mio::net::UdpSocket {
704    #[inline]
705    fn as_raw_read_handle_or_socket(&self) -> RawHandleOrSocket {
706        self.as_raw_handle_or_socket()
707    }
708
709    #[inline]
710    fn as_raw_write_handle_or_socket(&self) -> RawHandleOrSocket {
711        self.as_raw_handle_or_socket()
712    }
713}
714
715#[cfg(all(windows, feature = "use_mio_net"))]
716#[cfg(not(io_lifetimes_use_std))] // TODO: Enable once we have mio impls
717impl AsReadWriteHandleOrSocket for mio::net::UdpSocket {
718    #[inline]
719    fn as_read_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
720        self.as_handle_or_socket()
721    }
722
723    #[inline]
724    fn as_write_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
725        self.as_handle_or_socket()
726    }
727}
728
729/// Adapt an `AsReadWriteGrip` implementation to implement
730/// `AsGrip` with the read handle.
731#[allow(clippy::exhaustive_structs)]
732#[derive(Debug, Copy, Clone)]
733pub struct ReadHalf<'a, RW>(&'a RW);
734
735impl<'a, RW> ReadHalf<'a, RW> {
736    /// Returns a new instance of `Self`.
737    #[inline]
738    pub const fn new(rw: &'a RW) -> Self {
739        Self(rw)
740    }
741}
742
743#[cfg(not(windows))]
744impl<'a, RW: AsReadWriteFd> AsFd for ReadHalf<'a, RW> {
745    #[inline]
746    fn as_fd(&self) -> BorrowedFd<'a> {
747        self.0.as_read_fd()
748    }
749}
750
751#[cfg(windows)]
752impl<'a, RW: AsReadWriteHandleOrSocket> AsHandleOrSocket for ReadHalf<'a, RW> {
753    #[inline]
754    fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'a> {
755        self.0.as_read_handle_or_socket()
756    }
757}
758
759/// Adapt an `AsReadWriteGrip` implementation to implement
760/// `AsGrip` with the write handle.
761#[allow(clippy::exhaustive_structs)]
762#[derive(Debug, Copy, Clone)]
763pub struct WriteHalf<'a, RW>(&'a RW);
764
765impl<'a, RW> WriteHalf<'a, RW> {
766    /// Returns a new instance of `Self`.
767    #[inline]
768    pub const fn new(rw: &'a RW) -> Self {
769        Self(rw)
770    }
771}
772
773#[cfg(not(windows))]
774impl<'a, RW: AsReadWriteFd> AsFd for WriteHalf<'a, RW> {
775    #[inline]
776    fn as_fd(&self) -> BorrowedFd<'a> {
777        self.0.as_write_fd()
778    }
779}
780
781#[cfg(windows)]
782impl<'a, RW: AsReadWriteHandleOrSocket> AsHandleOrSocket for WriteHalf<'a, RW> {
783    #[inline]
784    fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'a> {
785        self.0.as_write_handle_or_socket()
786    }
787}