1
+ #![ feature( async_await) ]
1
2
#![ deny( warnings) ]
2
- extern crate futures ;
3
+
3
4
extern crate hyper;
4
5
5
- use futures:: future;
6
- use hyper:: rt:: { Future , Stream } ;
7
- use hyper:: service:: service_fn;
8
- use hyper:: { Body , Method , Request , Response , Server , StatusCode } ;
6
+ use futures_util:: stream:: StreamExt ; // TODO: is this correct or?
9
7
10
- /// We need to return different futures depending on the route matched,
11
- /// and we can do that with an enum, such as `futures::Either`, or with
12
- /// trait objects.
13
- ///
14
- /// A boxed Future (trait object) is used as it is easier to understand
15
- /// and extend with more types. Advanced users could switch to `Either`.
16
- type BoxFut = Box < dyn Future < Item = Response < Body > , Error = hyper:: Error > + Send > ;
8
+ use hyper:: { Body , Method , Request , Response , Server , StatusCode } ;
9
+ use hyper:: service:: { make_service_fn, service_fn} ;
10
+ use hyper:: body:: Chunk ;
17
11
18
12
/// This is our service handler. It receives a Request, routes on its
19
13
/// path, and returns a Future of a Response.
20
- fn echo ( req : Request < Body > ) -> BoxFut {
14
+ async fn echo ( req : Request < Body > ) -> Result < Response < Body > , hyper :: Error > {
21
15
let mut response = Response :: new ( Body :: empty ( ) ) ;
22
16
23
17
match ( req. method ( ) , req. uri ( ) . path ( ) ) {
@@ -34,13 +28,15 @@ fn echo(req: Request<Body>) -> BoxFut {
34
28
// Convert to uppercase before sending back to client.
35
29
( & Method :: POST , "/echo/uppercase" ) => {
36
30
let mapping = req. into_body ( ) . map ( |chunk| {
37
- chunk
31
+ let chunk= chunk. unwrap ( ) ;
32
+ let x = chunk
38
33
. iter ( )
39
34
. map ( |byte| byte. to_ascii_uppercase ( ) )
40
- . collect :: < Vec < u8 > > ( )
41
- } ) ;
35
+ . collect :: < Vec < _ > > ( ) ;
36
+ x
37
+ } ) . collect :: < Vec < _ > > ( ) . await ;
42
38
43
- * response. body_mut ( ) = Body :: wrap_stream ( mapping) ;
39
+ * response. body_mut ( ) = Body :: from ( mapping) ;
44
40
}
45
41
46
42
// Reverse the entire body before sending back to the client.
@@ -49,32 +45,42 @@ fn echo(req: Request<Body>) -> BoxFut {
49
45
// the chunks as they arrive. So, this returns a different
50
46
// future, waiting on concatenating the full body, so that
51
47
// it can be reversed. Only then can we return a `Response`.
52
- ( & Method :: POST , "/echo/reversed" ) => {
53
- let reversed = req. into_body ( ) . concat2 ( ) . map ( move |chunk| {
54
- let body = chunk. iter ( ) . rev ( ) . cloned ( ) . collect :: < Vec < u8 > > ( ) ;
55
- * response. body_mut ( ) = Body :: from ( body) ;
56
- response
57
- } ) ;
58
-
59
- return Box :: new ( reversed) ;
60
- }
48
+ // (&Method::POST, "/echo/reversed") => {
49
+ // let reversed = req.into_body().concat2().map(move |chunk| {
50
+ // let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
51
+ // *response.body_mut() = Body::from(body);
52
+ // response
53
+ // });
54
+ //
55
+ // return Ok (reversed);
56
+ // }
61
57
62
58
// The 404 Not Found route...
63
59
_ => {
64
60
* response. status_mut ( ) = StatusCode :: NOT_FOUND ;
65
61
}
66
62
} ;
67
63
68
- Box :: new ( future :: ok ( response) )
64
+ Ok ( response)
69
65
}
70
66
71
- fn main ( ) {
67
+
68
+ #[ tokio:: main]
69
+ async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
72
70
let addr = ( [ 127 , 0 , 0 , 1 ] , 3000 ) . into ( ) ;
73
71
72
+ let service = make_service_fn ( |_| {
73
+ async {
74
+ Ok :: < _ , hyper:: Error > ( service_fn ( echo) )
75
+ }
76
+ } ) ;
77
+
74
78
let server = Server :: bind ( & addr)
75
- . serve ( || service_fn ( echo) )
76
- . map_err ( |e| eprintln ! ( "server error: {}" , e) ) ;
79
+ . serve ( service) ;
77
80
78
81
println ! ( "Listening on http://{}" , addr) ;
79
- hyper:: rt:: run ( server) ;
82
+
83
+ server. await ?;
84
+
85
+ Ok ( ( ) )
80
86
}
0 commit comments