/rust/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/io/chain.rs
Line  | Count  | Source  | 
1  |  | use futures_core::ready;  | 
2  |  | use futures_core::task::{Context, Poll}; | 
3  |  | use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut}; | 
4  |  | use pin_project_lite::pin_project;  | 
5  |  | use std::fmt;  | 
6  |  | use std::io;  | 
7  |  | use std::pin::Pin;  | 
8  |  |  | 
9  |  | pin_project! { | 
10  |  |     /// Reader for the [`chain`](super::AsyncReadExt::chain) method.  | 
11  |  |     #[must_use = "readers do nothing unless polled"]  | 
12  |  |     pub struct Chain<T, U> { | 
13  |  |         #[pin]  | 
14  |  |         first: T,  | 
15  |  |         #[pin]  | 
16  |  |         second: U,  | 
17  |  |         done_first: bool,  | 
18  |  |     }  | 
19  |  | }  | 
20  |  |  | 
21  |  | impl<T, U> Chain<T, U>  | 
22  |  | where  | 
23  |  |     T: AsyncRead,  | 
24  |  |     U: AsyncRead,  | 
25  |  | { | 
26  | 0  |     pub(super) fn new(first: T, second: U) -> Self { | 
27  | 0  |         Self { first, second, done_first: false } | 
28  | 0  |     }  | 
29  |  |  | 
30  |  |     /// Gets references to the underlying readers in this `Chain`.  | 
31  | 0  |     pub fn get_ref(&self) -> (&T, &U) { | 
32  | 0  |         (&self.first, &self.second)  | 
33  | 0  |     }  | 
34  |  |  | 
35  |  |     /// Gets mutable references to the underlying readers in this `Chain`.  | 
36  |  |     ///  | 
37  |  |     /// Care should be taken to avoid modifying the internal I/O state of the  | 
38  |  |     /// underlying readers as doing so may corrupt the internal state of this  | 
39  |  |     /// `Chain`.  | 
40  | 0  |     pub fn get_mut(&mut self) -> (&mut T, &mut U) { | 
41  | 0  |         (&mut self.first, &mut self.second)  | 
42  | 0  |     }  | 
43  |  |  | 
44  |  |     /// Gets pinned mutable references to the underlying readers in this `Chain`.  | 
45  |  |     ///  | 
46  |  |     /// Care should be taken to avoid modifying the internal I/O state of the  | 
47  |  |     /// underlying readers as doing so may corrupt the internal state of this  | 
48  |  |     /// `Chain`.  | 
49  | 0  |     pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { | 
50  | 0  |         let this = self.project();  | 
51  | 0  |         (this.first, this.second)  | 
52  | 0  |     }  | 
53  |  |  | 
54  |  |     /// Consumes the `Chain`, returning the wrapped readers.  | 
55  | 0  |     pub fn into_inner(self) -> (T, U) { | 
56  | 0  |         (self.first, self.second)  | 
57  | 0  |     }  | 
58  |  | }  | 
59  |  |  | 
60  |  | impl<T, U> fmt::Debug for Chain<T, U>  | 
61  |  | where  | 
62  |  |     T: fmt::Debug,  | 
63  |  |     U: fmt::Debug,  | 
64  |  | { | 
65  | 0  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
66  | 0  |         f.debug_struct("Chain") | 
67  | 0  |             .field("t", &self.first) | 
68  | 0  |             .field("u", &self.second) | 
69  | 0  |             .field("done_first", &self.done_first) | 
70  | 0  |             .finish()  | 
71  | 0  |     }  | 
72  |  | }  | 
73  |  |  | 
74  |  | impl<T, U> AsyncRead for Chain<T, U>  | 
75  |  | where  | 
76  |  |     T: AsyncRead,  | 
77  |  |     U: AsyncRead,  | 
78  |  | { | 
79  | 0  |     fn poll_read(  | 
80  | 0  |         self: Pin<&mut Self>,  | 
81  | 0  |         cx: &mut Context<'_>,  | 
82  | 0  |         buf: &mut [u8],  | 
83  | 0  |     ) -> Poll<io::Result<usize>> { | 
84  | 0  |         let this = self.project();  | 
85  |  |  | 
86  | 0  |         if !*this.done_first { | 
87  | 0  |             match ready!(this.first.poll_read(cx, buf)?) { | 
88  | 0  |                 0 if !buf.is_empty() => *this.done_first = true,  | 
89  | 0  |                 n => return Poll::Ready(Ok(n)),  | 
90  |  |             }  | 
91  | 0  |         }  | 
92  | 0  |         this.second.poll_read(cx, buf)  | 
93  | 0  |     }  | 
94  |  |  | 
95  | 0  |     fn poll_read_vectored(  | 
96  | 0  |         self: Pin<&mut Self>,  | 
97  | 0  |         cx: &mut Context<'_>,  | 
98  | 0  |         bufs: &mut [IoSliceMut<'_>],  | 
99  | 0  |     ) -> Poll<io::Result<usize>> { | 
100  | 0  |         let this = self.project();  | 
101  |  |  | 
102  | 0  |         if !*this.done_first { | 
103  | 0  |             let n = ready!(this.first.poll_read_vectored(cx, bufs)?);  | 
104  | 0  |             if n == 0 && bufs.iter().any(|b| !b.is_empty()) { | 
105  | 0  |                 *this.done_first = true  | 
106  |  |             } else { | 
107  | 0  |                 return Poll::Ready(Ok(n));  | 
108  |  |             }  | 
109  | 0  |         }  | 
110  | 0  |         this.second.poll_read_vectored(cx, bufs)  | 
111  | 0  |     }  | 
112  |  | }  | 
113  |  |  | 
114  |  | impl<T, U> AsyncBufRead for Chain<T, U>  | 
115  |  | where  | 
116  |  |     T: AsyncBufRead,  | 
117  |  |     U: AsyncBufRead,  | 
118  |  | { | 
119  | 0  |     fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> { | 
120  | 0  |         let this = self.project();  | 
121  |  |  | 
122  | 0  |         if !*this.done_first { | 
123  | 0  |             match ready!(this.first.poll_fill_buf(cx)?) { | 
124  | 0  |                 buf if buf.is_empty() => { | 
125  | 0  |                     *this.done_first = true;  | 
126  | 0  |                 }  | 
127  | 0  |                 buf => return Poll::Ready(Ok(buf)),  | 
128  |  |             }  | 
129  | 0  |         }  | 
130  | 0  |         this.second.poll_fill_buf(cx)  | 
131  | 0  |     }  | 
132  |  |  | 
133  | 0  |     fn consume(self: Pin<&mut Self>, amt: usize) { | 
134  | 0  |         let this = self.project();  | 
135  |  |  | 
136  | 0  |         if !*this.done_first { | 
137  | 0  |             this.first.consume(amt)  | 
138  |  |         } else { | 
139  | 0  |             this.second.consume(amt)  | 
140  |  |         }  | 
141  | 0  |     }  | 
142  |  | }  |