diff --git a/.travis.yml b/.travis.yml index d91bcbb60..3e4d10906 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - nightly-2019-04-25 + - nightly-2019-05-09 before_script: | rustup component add rustfmt clippy diff --git a/Cargo.toml b/Cargo.toml index f1a6e1933..e333ed6b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,8 @@ repository = "https://github.com/rustasync/tide" version = "0.2.0" [dependencies] -cookie = { version="0.11", features = ["percent-encode"] } -futures-preview = "0.3.0-alpha.15" +cookie = { version = "0.11", features = ["percent-encode"] } +futures-preview = "0.3.0-alpha.16" fnv = "1.0.6" http = "0.1" http-service = "0.2.0" @@ -54,3 +54,6 @@ juniper = "0.10.0" structopt = "0.2.15" http-service-mock = "0.2.0" serde = { version = "1.0.90", features = ["derive"] } + +[patch.crates-io] +http-service = { git = "https://github.com/taiki-e/http-service", branch = "await" } diff --git a/examples/body_types.rs b/examples/body_types.rs index 3c996bda2..e757cf942 100644 --- a/examples/body_types.rs +++ b/examples/body_types.rs @@ -1,4 +1,4 @@ -#![feature(async_await, await_macro)] +#![feature(async_await)] use serde::{Deserialize, Serialize}; use tide::{ @@ -14,25 +14,25 @@ struct Message { } async fn echo_string(mut cx: Context<()>) -> String { - let msg = await!(cx.body_string()).unwrap(); + let msg = cx.body_string().await.unwrap(); println!("String: {}", msg); msg } async fn echo_bytes(mut cx: Context<()>) -> Vec { - let msg = await!(cx.body_bytes()).unwrap(); + let msg = cx.body_bytes().await.unwrap(); println!("Bytes: {:?}", msg); msg } async fn echo_json(mut cx: Context<()>) -> EndpointResult { - let msg = await!(cx.body_json()).client_err()?; + let msg = cx.body_json().await.client_err()?; println!("JSON: {:?}", msg); Ok(response::json(msg)) } async fn echo_form(mut cx: Context<()>) -> EndpointResult { - let msg = await!(cx.body_form())?; + let msg = cx.body_form().await?; println!("Form: {:?}", msg); Ok(forms::form(msg)) } diff --git a/examples/graphql.rs b/examples/graphql.rs index 1758c278a..d1b20be14 100644 --- a/examples/graphql.rs +++ b/examples/graphql.rs @@ -3,7 +3,7 @@ // // [the Juniper book]: https://graphql-rust.github.io/ -#![feature(async_await, await_macro)] +#![feature(async_await)] use http::status::StatusCode; use juniper::graphql_object; @@ -46,7 +46,7 @@ type Schema = juniper::RootNode<'static, Query, Mutation>; // Finally, we'll bridge between Tide and Juniper. `GraphQLRequest` from Juniper implements // `Deserialize`, so we use `Json` extractor to deserialize the request body. async fn handle_graphql(mut cx: Context) -> EndpointResult { - let query: juniper::http::GraphQLRequest = await!(cx.body_json()).client_err()?; + let query: juniper::http::GraphQLRequest = cx.body_json().await.client_err()?; let response = query.execute(&Schema::new(Query, Mutation), cx.state()); let status = if response.is_ok() { StatusCode::OK diff --git a/examples/messages.rs b/examples/messages.rs index 87473c902..22a48b74d 100644 --- a/examples/messages.rs +++ b/examples/messages.rs @@ -1,4 +1,4 @@ -#![feature(async_await, await_macro)] +#![feature(async_await)] use http::status::StatusCode; use serde::{Deserialize, Serialize}; @@ -40,12 +40,12 @@ impl Database { } async fn new_message(mut cx: Context) -> EndpointResult { - let msg = await!(cx.body_json()).client_err()?; + let msg = cx.body_json().await.client_err()?; Ok(cx.state().insert(msg).to_string()) } async fn set_message(mut cx: Context) -> EndpointResult<()> { - let msg = await!(cx.body_json()).client_err()?; + let msg = cx.body_json().await.client_err()?; let id = cx.param("id").client_err()?; if cx.state().set(id, msg) { diff --git a/examples/multipart-form/main.rs b/examples/multipart-form/main.rs index 4f26e4d2c..79e9bc0d2 100644 --- a/examples/multipart-form/main.rs +++ b/examples/multipart-form/main.rs @@ -1,4 +1,4 @@ -#![feature(async_await, await_macro)] +#![feature(async_await)] use serde::{Deserialize, Serialize}; use std::io::Read; @@ -19,7 +19,8 @@ async fn upload_file(mut cx: Context<()>) -> EndpointResult { file: None, }; - await!(cx.body_multipart())? + cx.body_multipart() + .await? .foreach_entry(|mut entry| match entry.headers.name.as_str() { "file" => { let mut vec = Vec::new(); diff --git a/src/app.rs b/src/app.rs index 57ce067a3..e95006b66 100644 --- a/src/app.rs +++ b/src/app.rs @@ -45,7 +45,7 @@ use crate::{ /// segments as parameters to endpoints: /// /// ```rust, no_run -/// #![feature(async_await, futures_api)] +/// #![feature(async_await)] /// /// use tide::error::ResultExt; /// @@ -75,7 +75,7 @@ use crate::{ /// # Application state /// /// ```rust, no_run, ignore -/// #![feature(async_await, futures_api, await_macro)] +/// #![feature(async_await)] /// /// use tide::{Context, EndpointResult, error::ResultExt, response, App}; /// use http::StatusCode; @@ -99,7 +99,7 @@ use crate::{ /// } /// /// async fn new_message(cx: Context) -> EndpointResult { -/// let msg = await!(cx.body_json()).client_err()?; +/// let msg = cx.body_json().await.client_err()?; /// /// let mut messages = cx.app_data().messages(); /// let id = messages.len(); @@ -285,7 +285,7 @@ impl HttpService for Server { next.run(cx) }; - Ok(await!(fut)) + Ok(fut.await) } } } diff --git a/src/context.rs b/src/context.rs index a00de9a28..51513db39 100644 --- a/src/context.rs +++ b/src/context.rs @@ -89,7 +89,7 @@ impl Context { /// Any I/O error encountered while reading the body is immediately returned /// as an `Err`. pub async fn body_bytes(&mut self) -> std::io::Result> { - await!(self.take_body().into_vec()) + self.take_body().into_vec().await } /// Reads the entire request body into a string. @@ -104,7 +104,7 @@ impl Context { /// /// If the body cannot be interpreted as valid UTF-8, an `Err` is returned. pub async fn body_string(&mut self) -> std::io::Result { - let body_bytes = await!(self.body_bytes())?; + let body_bytes = self.body_bytes().await?; Ok(String::from_utf8(body_bytes).map_err(|_| std::io::ErrorKind::InvalidData)?) } @@ -118,7 +118,7 @@ impl Context { /// If the body cannot be interpreted as valid json for the target type `T`, /// an `Err` is returned. pub async fn body_json(&mut self) -> std::io::Result { - let body_bytes = await!(self.body_bytes())?; + let body_bytes = self.body_bytes().await?; Ok(serde_json::from_slice(&body_bytes).map_err(|_| std::io::ErrorKind::InvalidData)?) } diff --git a/src/endpoint.rs b/src/endpoint.rs index 81fdbb542..f4adbfcf8 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -14,13 +14,13 @@ use crate::{response::IntoResponse, Context, Response}; /// /// Endpoints are implemented as asynchronous functions that make use of language features /// currently only available in Rust Nightly. For this reason, we have to explicitly enable -/// those features with `#![feature(async_await, futures_api)]`. To keep examples concise, +/// those features with `#![feature(async_await)]`. To keep examples concise, /// the attribute will be omitted in most of the documentation. /// /// A simple endpoint that is invoked on a `GET` request and returns a `String`: /// /// ```rust, no_run -/// # #![feature(async_await, futures_api)] +/// # #![feature(async_await)] /// async fn hello(_cx: tide::Context<()>) -> String { /// String::from("hello") /// } @@ -35,7 +35,6 @@ use crate::{response::IntoResponse, Context, Response}; /// An endpoint with similar functionality that does not make use of the `async` keyword would look something like this: /// /// ```rust, no_run -/// # #![feature(futures_api)] /// # use core::future::Future; /// fn hello(_cx: tide::Context<()>) -> impl Future { /// futures::future::ready(String::from("hello")) @@ -70,7 +69,7 @@ where fn call(&self, cx: Context) -> Self::Fut { let fut = (self)(cx); box_async! { - await!(fut).into_response() + fut.await.into_response() } } } diff --git a/src/forms.rs b/src/forms.rs index 8497bbceb..b7338dab5 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -20,7 +20,7 @@ impl ExtractForms for Context { fn body_form(&mut self) -> BoxTryFuture { let body = self.take_body(); box_async! { - let body = await!(body.into_vec()).client_err()?; + let body = body.into_vec().await.client_err()?; Ok(serde_urlencoded::from_bytes(&body).map_err(|e| err_fmt!("could not decode form: {}", e)).client_err()?) } } @@ -36,7 +36,7 @@ impl ExtractForms for Context { let body = self.take_body(); box_async! { - let body = await!(body.into_vec()).client_err()?; + let body = body.into_vec().await.client_err()?; let boundary = boundary.ok_or_else(|| err_fmt!("no boundary found")).client_err()?; Ok(Multipart::with_body(Cursor::new(body), boundary)) } diff --git a/src/lib.rs b/src/lib.rs index 0e0e0c70b..043473e9b 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ #![cfg_attr(feature = "nightly", feature(external_doc))] #![cfg_attr(feature = "nightly", doc(include = "../README.md"))] #![cfg_attr(test, deny(warnings))] -#![feature(async_await, await_macro, existential_type)] +#![feature(async_await, existential_type)] #![allow(unused_variables)] #![deny(nonstandard_style, rust_2018_idioms, future_incompatible)] // TODO: Remove this after clippy bug due to async await is resolved. diff --git a/src/middleware/cookies.rs b/src/middleware/cookies.rs index 42845c319..c0c272097 100644 --- a/src/middleware/cookies.rs +++ b/src/middleware/cookies.rs @@ -40,7 +40,7 @@ impl Middleware for CookiesMiddleware { let cookie_jar = cookie_data.content.clone(); cx.extensions_mut().insert(cookie_data); - let mut res = await!(next.run(cx)); + let mut res = next.run(cx).await; let headers = res.headers_mut(); for cookie in cookie_jar.read().unwrap().delta() { let hv = HeaderValue::from_str(cookie.encoded().to_string().as_str()); diff --git a/src/middleware/default_headers.rs b/src/middleware/default_headers.rs index 42c1d33e8..9050099c6 100644 --- a/src/middleware/default_headers.rs +++ b/src/middleware/default_headers.rs @@ -42,7 +42,7 @@ impl DefaultHeaders { impl Middleware for DefaultHeaders { fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> BoxFuture<'a, Response> { box_async! { - let mut res = await!(next.run(cx)); + let mut res = next.run(cx).await; let headers = res.headers_mut(); for (key, value) in self.headers.iter() { diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index bf375c08f..48afe22e3 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -40,7 +40,7 @@ impl Middleware for RootLogger { let path = cx.uri().path().to_owned(); let method = cx.method().as_str().to_owned(); - let res = await!(next.run(cx)); + let res = next.run(cx).await; let status = res.status(); info!(self.inner_logger, "{} {} {}", method, path, status.as_str()); res