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, Conn};
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    pub(crate) fn conn_ref(&self) -> &Conn {
31        &*self.0
32    }
33}
34
35impl Future for ReadPacket<'_, '_> {
36    type Output = std::result::Result<PooledBuf, IoError>;
37
38    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
39        let packet_opt = match self.0.stream_mut() {
40            Ok(stream) => ready!(Pin::new(stream).poll_next(cx)).transpose()?,
41            // `ConnectionClosed` error.
42            Err(_) => None,
43        };
44
45        match packet_opt {
46            Some(packet) => {
47                self.0.touch();
48                Poll::Ready(Ok(packet))
49            }
50            None => Poll::Ready(Err(Error::new(
51                ErrorKind::UnexpectedEof,
52                "connection closed",
53            )
54            .into())),
55        }
56    }
57}