1
+ #![ feature( async_await) ]
1
2
#![ deny( warnings) ]
2
3
extern crate hyper;
3
4
#[ macro_use]
@@ -6,78 +7,39 @@ extern crate serde;
6
7
extern crate serde_json;
7
8
8
9
use hyper:: Client ;
9
- use hyper :: rt :: { self , Future , Stream } ;
10
+ use futures_util :: TryStreamExt ;
10
11
11
- fn main ( ) {
12
- let url = "http://jsonplaceholder.typicode.com/users" . parse ( ) . unwrap ( ) ;
13
-
14
- let fut = fetch_json ( url)
15
- // use the parsed vector
16
- . map ( |users| {
17
- // print users
18
- println ! ( "users: {:#?}" , users) ;
19
-
20
- // print the sum of ids
21
- let sum = users. iter ( ) . fold ( 0 , |acc, user| acc + user. id ) ;
22
- println ! ( "sum of ids: {}" , sum) ;
23
- } )
24
- // if there was an error print it
25
- . map_err ( |e| {
26
- match e {
27
- FetchError :: Http ( e) => eprintln ! ( "http error: {}" , e) ,
28
- FetchError :: Json ( e) => eprintln ! ( "json parsing error: {}" , e) ,
29
- }
30
- } ) ;
12
+ // A simple type alias so as to DRY.
13
+ type Result < T > = std:: result:: Result < T , Box < dyn std:: error:: Error + Send + Sync > > ;
31
14
32
- // Run the runtime with the future trying to fetch, parse and print json.
33
- //
34
- // Note that in more complicated use cases, the runtime should probably
35
- // run on its own, and futures should just be spawned into it.
36
- rt:: run ( fut) ;
15
+ #[ hyper:: rt:: main]
16
+ async fn main ( ) -> Result < ( ) > {
17
+ let url = "http://jsonplaceholder.typicode.com/users" . parse ( ) . unwrap ( ) ;
18
+ let users = fetch_json ( url) . await ?;
19
+ // print users
20
+ println ! ( "users: {:#?}" , users) ;
21
+
22
+ // print the sum of ids
23
+ let sum = users. iter ( ) . fold ( 0 , |acc, user| acc + user. id ) ;
24
+ println ! ( "sum of ids: {}" , sum) ;
25
+ Ok ( ( ) )
37
26
}
38
27
39
- fn fetch_json ( url : hyper:: Uri ) -> impl Future < Item = Vec < User > , Error = FetchError > {
28
+ async fn fetch_json ( url : hyper:: Uri ) -> Result < Vec < User > > {
40
29
let client = Client :: new ( ) ;
41
30
42
- client
43
- // Fetch the url...
44
- . get ( url)
45
- // And then, if we get a response back...
46
- . and_then ( |res| {
47
- // asynchronously concatenate chunks of the body
48
- res. into_body ( ) . concat2 ( )
49
- } )
50
- . from_err :: < FetchError > ( )
51
- // use the body after concatenation
52
- . and_then ( |body| {
53
- // try to parse as json with serde_json
54
- let users = serde_json:: from_slice ( & body) ?;
31
+ // Fetch the url...
32
+ let res = client. get ( url) . await ?;
33
+ // asynchronously concatenate chunks of the body
34
+ let body = res. into_body ( ) . try_concat ( ) . await ?;
35
+ // try to parse as json with serde_json
36
+ let users = serde_json:: from_slice ( & body) ?;
55
37
56
- Ok ( users)
57
- } )
58
- . from_err ( )
38
+ Ok ( users)
59
39
}
60
40
61
41
#[ derive( Deserialize , Debug ) ]
62
42
struct User {
63
43
id : i32 ,
64
44
name : String ,
65
45
}
66
-
67
- // Define a type so we can return multiple types of errors
68
- enum FetchError {
69
- Http ( hyper:: Error ) ,
70
- Json ( serde_json:: Error ) ,
71
- }
72
-
73
- impl From < hyper:: Error > for FetchError {
74
- fn from ( err : hyper:: Error ) -> FetchError {
75
- FetchError :: Http ( err)
76
- }
77
- }
78
-
79
- impl From < serde_json:: Error > for FetchError {
80
- fn from ( err : serde_json:: Error ) -> FetchError {
81
- FetchError :: Json ( err)
82
- }
83
- }
0 commit comments