From 9cd971d8f3d7a53395c541fb4fb55b02c91a15d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Akkurt?= Date: Fri, 6 Jul 2018 18:45:32 +0300 Subject: [PATCH] docs(client): improve client_json example --- examples/client_json.rs | 53 +++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/examples/client_json.rs b/examples/client_json.rs index 24a8c597..14b81dbf 100644 --- a/examples/client_json.rs +++ b/examples/client_json.rs @@ -11,14 +11,32 @@ use hyper::rt::{self, Future, Stream}; fn main() { let url = "http://jsonplaceholder.typicode.com/users".parse().unwrap(); + let fut = fetch_json(url) + // use the parsed vector + .map(|users| { + // print users + println!("users: {:#?}", users); + + // print the sum of ids + let sum = users.iter().fold(0, |acc, user| acc + user.id); + println!("sum of ids: {}", sum); + }) + // if there was an error print it + .map_err(|e| { + match e { + FetchError::Http(e) => eprintln!("http error: {}", e), + FetchError::Json(e) => eprintln!("json parsing error: {}", e), + } + }); + // Run the runtime with the future trying to fetch, parse and print json. // // Note that in more complicated use cases, the runtime should probably // run on its own, and futures should just be spawned into it. - rt::run(fetch_json(url)); + rt::run(fut); } -fn fetch_json(url: hyper::Uri) -> impl Future { +fn fetch_json(url: hyper::Uri) -> impl Future, Error=FetchError> { let client = Client::new(); client @@ -29,22 +47,37 @@ fn fetch_json(url: hyper::Uri) -> impl Future { // asynchronously concatenate chunks of the body res.into_body().concat2() }) + .from_err::() // use the body after concatenation - .map(|body| { + .and_then(|body| { // try to parse as json with serde_json - let users: Vec = serde_json::from_slice(&body).expect("parse json"); + let users = serde_json::from_slice(&body)?; - // pretty print result - println!("{:#?}", users); - }) - // If there was an error, let the user know... - .map_err(|err| { - eprintln!("Error {}", err); + Ok(users) }) + .from_err() } #[derive(Deserialize, Debug)] struct User { id: i32, name: String, +} + +// Define a type so we can return multile types of errors +enum FetchError { + Http(hyper::Error), + Json(serde_json::Error), +} + +impl From for FetchError { + fn from(err: hyper::Error) -> FetchError { + FetchError::Http(err) + } +} + +impl From for FetchError { + fn from(err: serde_json::Error) -> FetchError { + FetchError::Json(err) + } } \ No newline at end of file