Sync Response::text() & Response::json() call their async version
This commit is contained in:
		| @@ -142,14 +142,6 @@ impl Decoder { | |||||||
|             Decoder::plain_text(body) |             Decoder::plain_text(body) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     pub(crate) fn content_length(&self) -> Option<u64> { |  | ||||||
|         match self.inner { |  | ||||||
|             Inner::PlainText(ref body) => body.content_length(), |  | ||||||
|             _ => None, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Stream for Decoder { | impl Stream for Decoder { | ||||||
|   | |||||||
| @@ -271,7 +271,7 @@ impl<T: Into<Body>> From<http::Response<T>> for Response { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// A JSON object. | /// A JSON object. | ||||||
| pub struct Json<T> { | struct Json<T> { | ||||||
|     concat: Concat2<Decoder>, |     concat: Concat2<Decoder>, | ||||||
|     _marker: PhantomData<T>, |     _marker: PhantomData<T>, | ||||||
| } | } | ||||||
| @@ -294,7 +294,7 @@ impl<T> fmt::Debug for Json<T> { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Text { | struct Text { | ||||||
|     concat: Concat2<Decoder>, |     concat: Concat2<Decoder>, | ||||||
|     encoding: &'static Encoding, |     encoding: &'static Encoding, | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,14 +3,10 @@ use std::fmt; | |||||||
| use std::io::{self, Read}; | use std::io::{self, Read}; | ||||||
| use std::net::SocketAddr; | use std::net::SocketAddr; | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| use std::borrow::Cow; |  | ||||||
|  |  | ||||||
| use encoding_rs::{Encoding, UTF_8}; |  | ||||||
| use futures::{Async, Poll, Stream}; | use futures::{Async, Poll, Stream}; | ||||||
| use http; | use http; | ||||||
| use mime::Mime; |  | ||||||
| use serde::de::DeserializeOwned; | use serde::de::DeserializeOwned; | ||||||
| use serde_json; |  | ||||||
|  |  | ||||||
| use cookie; | use cookie; | ||||||
| use client::KeepCoreThreadAlive; | use client::KeepCoreThreadAlive; | ||||||
| @@ -20,8 +16,8 @@ use {async_impl, StatusCode, Url, Version, wait}; | |||||||
| /// A Response to a submitted `Request`. | /// A Response to a submitted `Request`. | ||||||
| pub struct Response { | pub struct Response { | ||||||
|     inner: async_impl::Response, |     inner: async_impl::Response, | ||||||
|     body: async_impl::ReadableChunks<WaitBody>, |     body: Option<async_impl::ReadableChunks<WaitBody>>, | ||||||
|     content_length: Option<u64>, |     timeout: Option<Duration>, | ||||||
|     _thread_handle: KeepCoreThreadAlive, |     _thread_handle: KeepCoreThreadAlive, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -32,17 +28,11 @@ impl fmt::Debug for Response { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl Response { | impl Response { | ||||||
|     pub(crate) fn new(mut res: async_impl::Response, timeout: Option<Duration>, thread: KeepCoreThreadAlive) -> Response { |     pub(crate) fn new(res: async_impl::Response, timeout: Option<Duration>, thread: KeepCoreThreadAlive) -> Response { | ||||||
|         let body = mem::replace(res.body_mut(), async_impl::Decoder::empty()); |  | ||||||
|         let len = body.content_length(); |  | ||||||
|         let body = async_impl::ReadableChunks::new(WaitBody { |  | ||||||
|             inner: wait::stream(body, timeout) |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         Response { |         Response { | ||||||
|             inner: res, |             inner: res, | ||||||
|             body: body, |             body: None, | ||||||
|             content_length: len, |             timeout, | ||||||
|             _thread_handle: thread, |             _thread_handle: thread, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -212,21 +202,13 @@ impl Response { | |||||||
|     /// [`serde_json::from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html |     /// [`serde_json::from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn json<T: DeserializeOwned>(&mut self) -> ::Result<T> { |     pub fn json<T: DeserializeOwned>(&mut self) -> ::Result<T> { | ||||||
|         // There's 2 ways we could implement this: |         wait::timeout(self.inner.json(), self.timeout).map_err(|e| { | ||||||
|         // |             match e { | ||||||
|         // 1. Just using from_reader(self), making use of our blocking read adapter |                 wait::Waited::TimedOut => ::error::timedout(None), | ||||||
|         // 2. Just use self.inner.json().wait() |                 wait::Waited::Executor(e) => ::error::from(e), | ||||||
|         // |                 wait::Waited::Inner(e) => e, | ||||||
|         // Doing 1 is pretty easy, but it means we have the `serde_json` code |             } | ||||||
|         // in more than one place, doing basically the same thing. |         }) | ||||||
|         // |  | ||||||
|         // Doing 2 would mean `serde_json` is only in one place, but we'd |  | ||||||
|         // need to update the sync Response to lazily make a blocking read |  | ||||||
|         // adapter, so that our `inner` could possibly still have the original |  | ||||||
|         // body. |  | ||||||
|         // |  | ||||||
|         // Went for easier for now, just to get it working. |  | ||||||
|         serde_json::from_reader(self).map_err(::error::from) |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Get the response text. |     /// Get the response text. | ||||||
| @@ -278,38 +260,13 @@ impl Response { | |||||||
|     /// This consumes the body. Trying to read more, or use of `response.json()` |     /// This consumes the body. Trying to read more, or use of `response.json()` | ||||||
|     /// will return empty values. |     /// will return empty values. | ||||||
|     pub fn text_with_charset(&mut self, default_encoding: &str) -> ::Result<String> { |     pub fn text_with_charset(&mut self, default_encoding: &str) -> ::Result<String> { | ||||||
|         let len = self.content_length.unwrap_or(0); |         wait::timeout(self.inner.text_with_charset(default_encoding), self.timeout).map_err(|e| { | ||||||
|         let mut content = Vec::with_capacity(len as usize); |             match e { | ||||||
|         self.read_to_end(&mut content).map_err(::error::from)?; |                 wait::Waited::TimedOut => ::error::timedout(None), | ||||||
|         let content_type = self.headers().get(::header::CONTENT_TYPE) |                 wait::Waited::Executor(e) => ::error::from(e), | ||||||
|             .and_then(|value| { |                 wait::Waited::Inner(e) => e, | ||||||
|                 value.to_str().ok() |  | ||||||
|             }) |  | ||||||
|             .and_then(|value| { |  | ||||||
|                 value.parse::<Mime>().ok() |  | ||||||
|             }); |  | ||||||
|         let encoding_name = content_type |  | ||||||
|             .as_ref() |  | ||||||
|             .and_then(|mime| { |  | ||||||
|                 mime |  | ||||||
|                     .get_param("charset") |  | ||||||
|                     .map(|charset| charset.as_str()) |  | ||||||
|             }) |  | ||||||
|             .unwrap_or(default_encoding); |  | ||||||
|         let encoding = Encoding::for_label(encoding_name.as_bytes()).unwrap_or(UTF_8); |  | ||||||
|         // a block because of borrow checker |  | ||||||
|         { |  | ||||||
|             let (text, _, _) = encoding.decode(&content); |  | ||||||
|             match text { |  | ||||||
|                 Cow::Owned(s) => return Ok(s), |  | ||||||
|                 _ => (), |  | ||||||
|             } |             } | ||||||
|         } |         }) | ||||||
|         unsafe { |  | ||||||
|             // decoding returned Cow::Borrowed, meaning these bytes |  | ||||||
|             // are already valid utf8 |  | ||||||
|             Ok(String::from_utf8_unchecked(content)) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Copy the response body into a writer. |     /// Copy the response body into a writer. | ||||||
| @@ -357,12 +314,12 @@ impl Response { | |||||||
|     /// ``` |     /// ``` | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn error_for_status(self) -> ::Result<Self> { |     pub fn error_for_status(self) -> ::Result<Self> { | ||||||
|         let Response { body, content_length, inner, _thread_handle } = self; |         let Response { body, inner, timeout, _thread_handle } = self; | ||||||
|         inner.error_for_status().map(move |inner| { |         inner.error_for_status().map(move |inner| { | ||||||
|             Response { |             Response { | ||||||
|                 inner, |                 inner, | ||||||
|                 body, |                 body, | ||||||
|                 content_length, |                 timeout, | ||||||
|                 _thread_handle, |                 _thread_handle, | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
| @@ -393,7 +350,17 @@ impl Response { | |||||||
| impl Read for Response { | impl Read for Response { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||||||
|         self.body.read(buf) |         if self.body.is_none() { | ||||||
|  |             let body = mem::replace(self.inner.body_mut(), async_impl::Decoder::empty()); | ||||||
|  |             let body = async_impl::ReadableChunks::new(WaitBody { | ||||||
|  |                 inner: wait::stream(body, self.timeout) | ||||||
|  |             }); | ||||||
|  |             self.body = Some(body); | ||||||
|  |         } | ||||||
|  |         let mut body = self.body.take().unwrap(); | ||||||
|  |         let bytes = body.read(buf); | ||||||
|  |         self.body = Some(body); | ||||||
|  |         bytes | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user