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
mod input;
mod output;
mod server;
pub use self::{
input::{Input, IntoRequestBody},
output::Output,
server::{Server, Session},
};
use {
http::{Request, Response},
hyper::body::Payload,
tsukuyomi_service::{MakeService, Service},
};
pub trait ResponseExt {
fn header<H>(&self, name: H) -> crate::Result<&http::header::HeaderValue>
where
H: http::header::AsHeaderName + std::fmt::Display;
}
impl<T> ResponseExt for http::Response<T> {
fn header<H>(&self, name: H) -> crate::Result<&http::header::HeaderValue>
where
H: http::header::AsHeaderName + std::fmt::Display,
{
let err = failure::format_err!("missing header field: `{}'", name);
self.headers()
.get(name)
.ok_or_else(|| crate::Error::from(err))
}
}
pub fn server<S, Bd>(make_service: S) -> crate::Result<Server<S, tokio::runtime::Runtime>>
where
S: MakeService<(), Request<hyper::Body>, Response = Response<Bd>>,
S::Error: Into<crate::CritError>,
S::Service: Send + 'static,
<S::Service as Service<Request<hyper::Body>>>::Future: Send + 'static,
S::MakeError: Into<crate::CritError>,
S::Future: Send + 'static,
Bd: Payload,
{
let mut builder = tokio::runtime::Builder::new();
builder.core_threads(1);
builder.blocking_threads(1);
builder.name_prefix("tsukuyomi-server");
let runtime = builder.build()?;
Ok(Server::new(make_service, runtime))
}
pub fn local_server<S, Bd>(
make_service: S,
) -> crate::Result<Server<S, tokio::runtime::current_thread::Runtime>>
where
S: MakeService<(), Request<hyper::Body>, Response = Response<Bd>>,
S::Error: Into<crate::CritError>,
S::MakeError: Into<crate::CritError>,
Bd: Payload,
{
let runtime = tokio::runtime::current_thread::Runtime::new()?;
Ok(Server::new(make_service, runtime))
}