Coverage Report

Created: 2025-09-04 06:37

/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/io/chain.rs
Line
Count
Source (jump to first uncovered line)
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
0
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
0
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
0
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
0
136
0
        if !*this.done_first {
137
0
            this.first.consume(amt)
138
        } else {
139
0
            this.second.consume(amt)
140
        }
141
0
    }
142
}