Simplify async 'Response' methods.

This commit is contained in:
Sergio Benitez 2020-02-01 17:30:19 -08:00
parent 431b963774
commit 58f81d392e
1 changed files with 34 additions and 46 deletions

View File

@ -5,7 +5,6 @@ use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt};
use futures_util::future::FutureExt;
use crate::response::{Responder, ResultFuture}; use crate::response::{Responder, ResultFuture};
use crate::http::{Header, HeaderMap, Status, ContentType, Cookie}; use crate::http::{Header, HeaderMap, Status, ContentType, Cookie};
@ -68,30 +67,26 @@ impl<T> Body<T> {
impl<T: AsyncRead + Unpin> Body<T> { impl<T: AsyncRead + Unpin> Body<T> {
/// Attempts to read `self` into a `Vec` and returns it. If reading fails, /// Attempts to read `self` into a `Vec` and returns it. If reading fails,
/// returns `None`. /// returns `None`.
pub fn into_bytes(self) -> impl Future<Output=Option<Vec<u8>>> { pub async fn into_bytes(self) -> Option<Vec<u8>> {
Box::pin(async move { let mut vec = Vec::new();
let mut vec = Vec::new(); let mut body = self.into_inner();
let mut body = self.into_inner(); if let Err(e) = body.read_to_end(&mut vec).await {
if let Err(e) = body.read_to_end(&mut vec).await { error_!("Error reading body: {:?}", e);
error_!("Error reading body: {:?}", e); return None;
return None; }
}
Some(vec) Some(vec)
})
} }
/// Attempts to read `self` into a `String` and returns it. If reading or /// Attempts to read `self` into a `String` and returns it. If reading or
/// conversion fails, returns `None`. /// conversion fails, returns `None`.
pub fn into_string(self) -> impl Future<Output = Option<String>> { pub async fn into_string(self) -> Option<String> {
self.into_bytes().map(|bytes| { self.into_bytes().await.and_then(|bytes| match String::from_utf8(bytes) {
bytes.and_then(|bytes| match String::from_utf8(bytes) { Ok(string) => Some(string),
Ok(string) => Some(string), Err(e) => {
Err(e) => { error_!("Body is invalid UTF-8: {}", e);
error_!("Body is invalid UTF-8: {}", e); None
None }
}
})
}) })
} }
} }
@ -242,8 +237,7 @@ impl<'r> ResponseBuilder<'r> {
/// # }) /// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn raw_status(&mut self, code: u16, reason: &'static str) pub fn raw_status(&mut self, code: u16, reason: &'static str) -> &mut ResponseBuilder<'r> {
-> &mut ResponseBuilder<'r> {
self.response.set_raw_status(code, reason); self.response.set_raw_status(code, reason);
self self
} }
@ -339,9 +333,8 @@ impl<'r> ResponseBuilder<'r> {
/// # }) /// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn raw_header<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) pub fn raw_header<'a, 'b, N, V>(&mut self, name: N, value: V) -> &mut ResponseBuilder<'r>
-> &mut ResponseBuilder<'r> where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>, 'a: 'r, 'b: 'r
where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>
{ {
self.response.set_raw_header(name, value); self.response.set_raw_header(name, value);
self self
@ -370,9 +363,8 @@ impl<'r> ResponseBuilder<'r> {
/// # }) /// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn raw_header_adjoin<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) pub fn raw_header_adjoin<'a, 'b, N, V>(&mut self, name: N, value: V) -> &mut ResponseBuilder<'r>
-> &mut ResponseBuilder<'r> where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>, 'a: 'r, 'b: 'r
where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>
{ {
self.response.adjoin_raw_header(name, value); self.response.adjoin_raw_header(name, value);
self self
@ -611,6 +603,7 @@ impl<'r> ResponseBuilder<'r> {
impl<'r> Future for ResponseBuilder<'r> { impl<'r> Future for ResponseBuilder<'r> {
type Output = Response<'r>; type Output = Response<'r>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut(); let this = self.get_mut();
if this.fut.is_none() { if this.fut.is_none() {
@ -624,6 +617,7 @@ impl<'r> Future for ResponseBuilder<'r> {
response response
})); }));
} }
this.fut.as_mut().expect("this.fut.is_none() checked and assigned Some").as_mut().poll(cx) this.fut.as_mut().expect("this.fut.is_none() checked and assigned Some").as_mut().poll(cx)
} }
} }
@ -996,15 +990,12 @@ impl<'r> Response<'r> {
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// # }) /// # })
/// ``` /// ```
#[inline(always)] // NOTE: We _could_ return an impl Future bounded by the looser `r instead!
pub fn body_string(&mut self) -> impl Future<Output = Option<String>> + 'r { pub async fn body_string(&mut self) -> Option<String> {
let body = self.take_body(); match self.take_body() {
Box::pin(async move { Some(body) => body.into_string().await,
match body { None => None,
Some(body) => body.into_string().await, }
None => None,
}
})
} }
/// Consumes `self's` body and reads it into a `Vec` of `u8` bytes. If /// Consumes `self's` body and reads it into a `Vec` of `u8` bytes. If
@ -1026,15 +1017,12 @@ impl<'r> Response<'r> {
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// # }) /// # })
/// ``` /// ```
#[inline(always)] // NOTE: We _could_ return an impl Future bounded by the looser `r instead!
pub fn body_bytes(&mut self) -> impl Future<Output = Option<Vec<u8>>> + 'r { pub async fn body_bytes(&mut self) -> Option<Vec<u8>> {
let body = self.take_body(); match self.take_body() {
Box::pin(async move { Some(body) => body.into_bytes().await,
match body { None => None,
Some(body) => body.into_bytes().await, }
None => None,
}
})
} }
/// Moves the body of `self` out and returns it, if there is one, leaving no /// Moves the body of `self` out and returns it, if there is one, leaving no