1use std::pin::Pin;
2use std::task::{self, Poll};
3use std::{fmt, io};
4
5use futures_util::TryFutureExt;
6use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
7
8/// An upgraded HTTP connection.
9pub struct Upgraded {
10 inner: hyper::upgrade::Upgraded,
11}
12
13impl AsyncRead for Upgraded {
14 fn poll_read(
15 mut self: Pin<&mut Self>,
16 cx: &mut task::Context<'_>,
17 buf: &mut ReadBuf<'_>,
18 ) -> Poll<io::Result<()>> {
19 Pin::new(&mut self.inner).poll_read(cx, buf)
20 }
21}
22
23impl AsyncWrite for Upgraded {
24 fn poll_write(
25 mut self: Pin<&mut Self>,
26 cx: &mut task::Context<'_>,
27 buf: &[u8],
28 ) -> Poll<io::Result<usize>> {
29 Pin::new(&mut self.inner).poll_write(cx, buf)
30 }
31
32 fn poll_write_vectored(
33 mut self: Pin<&mut Self>,
34 cx: &mut task::Context<'_>,
35 bufs: &[io::IoSlice<'_>],
36 ) -> Poll<io::Result<usize>> {
37 Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
38 }
39
40 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
41 Pin::new(&mut self.inner).poll_flush(cx)
42 }
43
44 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
45 Pin::new(&mut self.inner).poll_shutdown(cx)
46 }
47
48 fn is_write_vectored(&self) -> bool {
49 self.inner.is_write_vectored()
50 }
51}
52
53impl fmt::Debug for Upgraded {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.debug_struct(name:"Upgraded").finish()
56 }
57}
58
59impl From<hyper::upgrade::Upgraded> for Upgraded {
60 fn from(inner: hyper::upgrade::Upgraded) -> Self {
61 Upgraded { inner }
62 }
63}
64
65impl super::response::Response {
66 /// Consumes the response and returns a future for a possible HTTP upgrade.
67 pub async fn upgrade(self) -> crate::Result<Upgraded> {
68 hyperMapErr(…) -> …>, …>::upgrade::on(self.res)
69 .map_ok(Upgraded::from)
70 .map_err(crate::error::upgrade)
71 .await
72 }
73}
74