From 271e6506626d030b8cb80eaaaadb5c5e5b39effe Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 21 Nov 2020 15:47:49 -0800 Subject: [PATCH] Merge into_json_deserialize into into_json. --- src/response.rs | 83 ++++++++++++++++++++------------------------ src/test/simple.rs | 4 +-- src/test/timeout.rs | 4 +-- tests/https-agent.rs | 2 +- 4 files changed, 43 insertions(+), 50 deletions(-) diff --git a/src/response.rs b/src/response.rs index 09e00cc..f5997e3 100644 --- a/src/response.rs +++ b/src/response.rs @@ -25,8 +25,7 @@ pub const DEFAULT_CHARACTER_SET: &str = "utf-8"; /// /// The `Response` is used to read response headers and decide what to do with the body. /// Note that the socket connection is open and the body not read until one of -/// [`into_reader()`](#method.into_reader), [`into_json()`](#method.into_json), -/// [`into_json_deserialize()`](#method.into_json_deserialize) or +/// [`into_reader()`](#method.into_reader), [`into_json()`](#method.into_json), or /// [`into_string()`](#method.into_string) consumes the response. /// /// ``` @@ -343,47 +342,13 @@ impl Response { } } - /// Turn this response into a (serde) JSON value of the response body. + /// Read the body of this response into a serde_json::Value, or any other type that + // implements the [serde::Deserialize] trait. /// - /// Requires feature `ureq = { version = "*", features = ["json"] }` + /// You must use either a type annotation as shown below (`message: Message`), or the + /// [turbofish operator] (`::`) so Rust knows what type you are trying to read. /// - /// Example: - /// - /// ``` - /// # fn main() -> Result<(), ureq::Error> { - /// # ureq::is_test(true); - /// let json: serde_json::Value = ureq::get("http://example.com/hello_world.json") - /// .call()? - /// .into_json()?; - /// - /// assert_eq!(json["hello"], "world"); - /// # Ok(()) - /// # } - /// ``` - #[cfg(feature = "json")] - pub fn into_json(self) -> io::Result { - use crate::stream::io_err_timeout; - use std::error::Error; - - let reader = self.into_reader(); - serde_json::from_reader(reader).map_err(|e| { - // This is to unify TimedOut io::Error in the API. - // We make a clone of the original error since serde_json::Error doesn't - // let us get the wrapped error instance back. - if let Some(ioe) = e.source().and_then(|s| s.downcast_ref::()) { - if ioe.kind() == ErrorKind::TimedOut { - return io_err_timeout(ioe.to_string()); - } - } - - io::Error::new( - ErrorKind::InvalidData, - format!("Failed to read JSON: {}", e), - ) - }) - } - - /// Turn the body of this response into a type that implements the [serde::Deserialize] trait. + /// [turbofish operator]: https://matematikaadit.github.io/posts/rust-turbofish.html /// /// Requires feature `ureq = { version = "*", features = ["json"] }` /// @@ -402,16 +367,44 @@ impl Response { /// let message: Message = /// ureq::get("http://example.com/hello_world.json") /// .call()? - /// .into_json_deserialize()?; + /// .into_json()?; /// /// assert_eq!(message.hello, "world"); /// # Ok(()) /// # } /// ``` + /// + /// Or, if you don't want to define a struct to read your JSON into, you can + /// use the convenient `serde_json::Value` type to parse arbitrary or unknown + /// JSON. + /// + /// ``` + /// # fn main() -> Result<(), ureq::Error> { + /// # ureq::is_test(true); + /// let json: serde_json::Value = ureq::get("http://example.com/hello_world.json") + /// .call()? + /// .into_json()?; + /// + /// assert_eq!(json["hello"], "world"); + /// # Ok(()) + /// # } + /// ``` #[cfg(feature = "json")] - pub fn into_json_deserialize(self) -> io::Result { + pub fn into_json(self) -> io::Result { + use crate::stream::io_err_timeout; + use std::error::Error; + let reader = self.into_reader(); serde_json::from_reader(reader).map_err(|e| { + // This is to unify TimedOut io::Error in the API. + // We make a clone of the original error since serde_json::Error doesn't + // let us get the wrapped error instance back. + if let Some(ioe) = e.source().and_then(|s| s.downcast_ref::()) { + if ioe.kind() == ErrorKind::TimedOut { + return io_err_timeout(ioe.to_string()); + } + } + io::Error::new( ErrorKind::InvalidData, format!("Failed to read JSON: {}", e), @@ -714,7 +707,7 @@ mod tests { \r\n\ {\"hello\":\"world\"}"; let resp = s.parse::().unwrap(); - let v = resp.into_json().unwrap(); + let v: serde_json::Value = resp.into_json().unwrap(); let compare = "{\"hello\":\"world\"}" .parse::() .unwrap(); @@ -735,7 +728,7 @@ mod tests { \r\n\ {\"hello\":\"world\"}"; let resp = s.parse::().unwrap(); - let v = resp.into_json_deserialize::().unwrap(); + let v: Hello = resp.into_json::().unwrap(); assert_eq!(v.hello, "world"); } diff --git a/src/test/simple.rs b/src/test/simple.rs index 498c672..369fe62 100644 --- a/src/test/simple.rs +++ b/src/test/simple.rs @@ -75,7 +75,7 @@ fn body_as_json() { ) }); let resp = get("test://host/body_as_json").call().unwrap(); - let json = resp.into_json().unwrap(); + let json: serde_json::Value = resp.into_json().unwrap(); assert_eq!(json["hello"], "world"); } @@ -98,7 +98,7 @@ fn body_as_json_deserialize() { ) }); let resp = get("test://host/body_as_json_deserialize").call().unwrap(); - let json = resp.into_json_deserialize::().unwrap(); + let json: Hello = resp.into_json().unwrap(); assert_eq!(json.hello, "world"); } diff --git a/src/test/timeout.rs b/src/test/timeout.rs index 358e4ec..ab9d034 100644 --- a/src/test/timeout.rs +++ b/src/test/timeout.rs @@ -138,9 +138,9 @@ fn overall_timeout_reading_json() { let timeout = Duration::from_millis(500); let agent = builder().timeout(timeout).build(); - let resp = agent.get(&url).call().unwrap(); + let result: Result = agent.get(&url).call().unwrap().into_json(); - match resp.into_json() { + match result { Ok(_) => Err("successful response".to_string()), Err(e) => match e.kind() { io::ErrorKind::TimedOut => Ok(()), diff --git a/tests/https-agent.rs b/tests/https-agent.rs index 9195a74..e23d852 100644 --- a/tests/https-agent.rs +++ b/tests/https-agent.rs @@ -18,7 +18,7 @@ fn agent_set_header() { .call() .unwrap(); assert_eq!(resp.status(), 200); - let json = resp.into_json_deserialize::().unwrap(); + let json: HttpBin = resp.into_json().unwrap(); // println!("{:?}", json); assert_eq!("value", json.headers.get("Header").unwrap()); }