hyper_client_io_wizard/
lib.rs

1#![forbid(unsafe_code)]
2
3use std::{
4    io,
5    pin::{
6        Pin,
7    },
8    task::{
9        Poll,
10        Context,
11    },
12};
13
14use tokio::{
15    net::{
16        TcpStream,
17    },
18};
19
20pub use hyper_util::{
21    rt::{
22        TokioIo,
23        TokioExecutor,
24    },
25};
26
27pub mod builder;
28
29mod resolver;
30
31pub struct Io {
32    pub protocols: Protocols,
33    pub uri_host: String,
34    pub stream: IoStream,
35}
36
37pub struct Protocols {
38    http1_support: bool,
39    http2_support: bool,
40}
41
42impl Io {
43    pub fn resolver_setup() -> builder::ResolverBuilder {
44        builder::ResolverBuilder::new()
45    }
46}
47
48impl Protocols {
49    pub fn http1_support_announced(&self) -> bool {
50        self.http1_support
51    }
52
53    pub fn http2_support_announced(&self) -> bool {
54        self.http2_support
55    }
56}
57
58pub struct IoStream {
59    kind: IoKind,
60}
61
62enum IoKind {
63    Tcp(IoTcp),
64    TcpTls(IoTcpTls),
65}
66
67struct IoTcp {
68    stream: TokioIo<TcpStream>,
69}
70
71struct IoTcpTls {
72    stream: TokioIo<tokio_rustls::client::TlsStream<TcpStream>>,
73}
74
75impl hyper::rt::Read for IoStream {
76    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: hyper::rt::ReadBufCursor<'_>) -> Poll<Result<(), io::Error>> {
77        match &mut self.kind {
78            IoKind::Tcp(io) =>
79                Pin::new(&mut io.stream).poll_read(cx, buf),
80            IoKind::TcpTls(io) =>
81                Pin::new(&mut io.stream).poll_read(cx, buf),
82        }
83    }
84}
85
86impl hyper::rt::Write for IoStream {
87    fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
88        match &mut self.kind {
89            IoKind::Tcp(io) =>
90                Pin::new(&mut io.stream).poll_write(cx, buf),
91            IoKind::TcpTls(io) =>
92                Pin::new(&mut io.stream).poll_write(cx, buf),
93        }
94    }
95
96    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
97        match &mut self.kind {
98            IoKind::Tcp(io) =>
99                Pin::new(&mut io.stream).poll_flush(cx),
100            IoKind::TcpTls(io) =>
101                Pin::new(&mut io.stream).poll_flush(cx),
102        }
103    }
104
105    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
106        match &mut self.kind {
107            IoKind::Tcp(io) =>
108                Pin::new(&mut io.stream).poll_shutdown(cx),
109            IoKind::TcpTls(io) =>
110                Pin::new(&mut io.stream).poll_shutdown(cx),
111        }
112    }
113
114    fn is_write_vectored(&self) -> bool {
115        match &self.kind {
116            IoKind::Tcp(io) =>
117                io.stream.is_write_vectored(),
118            IoKind::TcpTls(io) =>
119                io.stream.is_write_vectored(),
120        }
121    }
122
123    fn poll_write_vectored(mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[std::io::IoSlice<'_>]) -> Poll<Result<usize, io::Error>> {
124        match &mut self.kind {
125            IoKind::Tcp(io) =>
126                Pin::new(&mut io.stream).poll_write_vectored(cx, bufs),
127            IoKind::TcpTls(io) =>
128                Pin::new(&mut io.stream).poll_write_vectored(cx, bufs),
129        }
130    }
131}