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
use crate::{
store::{self, LazyReqStore},
Builder, Request,
};
use futures::future;
use serde::Deserialize;
use warp::{filters, reject, Filter, Rejection};
pub fn json_rpc() -> impl Filter<Extract = (Builder,), Error = Rejection> + Copy {
filters::method::post()
.and(filters::header::exact("Content-Type", "application/json"))
.and(store::filled().or(store_req()))
.map(|_| ())
.untuple_one()
.and(store::stored_req().map(|req: Request| Builder::new(req.id())))
}
fn store_req() -> impl Filter<Extract = (), Error = Rejection> + Copy {
filters::body::json::<Request>()
.and(store::store())
.map(|req: Request, store: LazyReqStore| {
store
.fill(req)
.expect("LazyReqStore is filled more than twice");
})
.untuple_one()
}
pub fn method(name: &'static str) -> impl Filter<Extract = (), Error = Rejection> + Copy {
store::stored_req()
.and_then(move |req: Request| {
if req.method() == name {
log::info!(target: "warp_json_rpc", "\"{}\" RPC", name);
future::ok(())
} else {
future::err(reject::reject())
}
})
.untuple_one()
}
pub fn params<T>() -> impl Filter<Extract = (T,), Error = Rejection> + Copy
where
for<'de> T: Deserialize<'de> + Send,
{
store::stored_req().and_then(|req: Request| {
future::ready(req.deserialize_param::<T>().map_err(|_| reject::reject()))
})
}