mysql_async/io/
read_packet.rs

1// Copyright (c) 2017 Anatoly Ikorsky
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use futures_core::{ready, stream::Stream};
10
11use std::{
12    future::Future,
13    io::{Error, ErrorKind},
14    pin::Pin,
15    task::{Context, Poll},
16};
17
18use crate::{buffer_pool::PooledBuf, connection_like::Connection, error::IoError};
19
20/// Reads a packet.
21#[derive(Debug)]
22#[must_use = "futures do nothing unless you `.await` or poll them"]
23pub struct ReadPacket<'a, 't>(pub(crate) Connection<'a, 't>);
24
25impl<'a, 't> ReadPacket<'a, 't> {
26    pub(crate) fn new<T: Into<Connection<'a, 't>>>(conn: T) -> Self {
27        Self(conn.into())
28    }
29
30    #[cfg(feature = "binlog")]
31    pub(crate) fn conn_ref(&self) -> &crate::Conn {
32        &self.0
33    }
34}
35
36impl Future for ReadPacket<'_, '_> {
37    type Output = std::result::Result<PooledBuf, IoError>;
38
39    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
40        let packet_opt = match self.0.stream_mut() {
41            Ok(stream) => ready!(Pin::new(stream).poll_next(cx)).transpose()?,
42            // `ConnectionClosed` error.
43            Err(_) => None,
44        };
45
46        match packet_opt {
47            Some(packet) => {
48                self.0.touch();
49                Poll::Ready(Ok(packet))
50            }
51            None => Poll::Ready(Err(Error::new(
52                ErrorKind::UnexpectedEof,
53                "connection closed",
54            )
55            .into())),
56        }
57    }
58}