1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::fmt;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
#[cfg(feature = "server")]
use crate::body::Body;
#[cfg(all(feature = "http2", feature = "server"))]
use crate::proto::h2::server::H2Stream;
use crate::rt::Executor;
#[cfg(feature = "server")]
pub trait ConnStreamExec<F, B: Body>: Clone {
fn execute_h2stream(&mut self, fut: H2Stream<F, B>);
}
pub(crate) type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
#[derive(Clone)]
pub(crate) enum Exec {
Default,
Executor(Arc<dyn Executor<BoxSendFuture> + Send + Sync>),
}
impl Exec {
pub(crate) fn execute<F>(&self, fut: F)
where
F: Future<Output = ()> + Send + 'static,
{
match *self {
Exec::Default => {
panic!("executor must be set");
}
Exec::Executor(ref e) => {
e.execute(Box::pin(fut));
}
}
}
}
impl fmt::Debug for Exec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Exec").finish()
}
}
#[cfg(feature = "server")]
impl<F, B> ConnStreamExec<F, B> for Exec
where
H2Stream<F, B>: Future<Output = ()> + Send + 'static,
B: Body,
{
fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
self.execute(fut)
}
}
#[cfg(feature = "server")]
impl<E, F, B> ConnStreamExec<F, B> for E
where
E: Executor<H2Stream<F, B>> + Clone,
H2Stream<F, B>: Future<Output = ()>,
B: Body,
{
fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
self.execute(fut)
}
}
#[cfg(not(feature = "http2"))]
#[allow(missing_debug_implementations)]
pub struct H2Stream<F, B>(std::marker::PhantomData<(F, B)>);
#[cfg(not(feature = "http2"))]
impl<F, B, E> Future for H2Stream<F, B>
where
F: Future<Output = Result<http::Response<B>, E>>,
B: crate::body::Body,
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
E: Into<Box<dyn std::error::Error + Send + Sync>>,
{
type Output = ();
fn poll(
self: Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unreachable!()
}
}