diff --git a/.travis.yml b/.travis.yml index 15c6e324e..d91bcbb60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - nightly-2019-04-16 + - nightly-2019-04-25 before_script: | rustup component add rustfmt clippy diff --git a/Cargo.toml b/Cargo.toml index 948abe37c..1197d1ccd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,10 +14,10 @@ version = "0.1.1" [dependencies] cookie = { version="0.11", features = ["percent-encode"] } -futures-preview = "0.3.0-alpha.14" +futures-preview = "0.3.0-alpha.15" fnv = "1.0.6" http = "0.1" -http-service = "0.1.5" +http-service = "0.2.0" pin-utils = "0.1.0-alpha.4" route-recognizer = "0.1.12" serde = "1.0.90" @@ -31,7 +31,7 @@ serde_urlencoded = "0.5.5" [dependencies.http-service-hyper] optional = true -version = "0.1.1" +version = "0.2.0" [dependencies.multipart] default-features = false @@ -46,5 +46,5 @@ hyper = ["http-service-hyper"] basic-cookies = "0.1.3" juniper = "0.10.0" structopt = "0.2.15" -http-service-mock = "0.1.1" +http-service-mock = "0.2.0" serde = { version = "1.0.90", features = ["derive"] } diff --git a/examples/body_types.rs b/examples/body_types.rs index f3b41f88f..6d0af2724 100644 --- a/examples/body_types.rs +++ b/examples/body_types.rs @@ -1,4 +1,4 @@ -#![feature(async_await, futures_api, await_macro)] +#![feature(async_await, await_macro)] use serde::{Deserialize, Serialize}; use tide::{ diff --git a/examples/catch_all.rs b/examples/catch_all.rs index 8fb5a203d..753bcd4af 100644 --- a/examples/catch_all.rs +++ b/examples/catch_all.rs @@ -1,4 +1,4 @@ -#![feature(async_await, futures_api)] +#![feature(async_await)] use tide::Context; diff --git a/examples/cookies.rs b/examples/cookies.rs index 7f9041bb0..bc47d9a97 100644 --- a/examples/cookies.rs +++ b/examples/cookies.rs @@ -1,4 +1,4 @@ -#![feature(async_await, futures_api)] +#![feature(async_await)] use cookie::Cookie; use tide::{cookies::CookiesExt, middleware::CookiesMiddleware, Context}; diff --git a/examples/graphql.rs b/examples/graphql.rs index 5d3d834d6..d16b9c517 100644 --- a/examples/graphql.rs +++ b/examples/graphql.rs @@ -3,7 +3,7 @@ // // [the Juniper book]: https://graphql-rust.github.io/ -#![feature(async_await, futures_api, await_macro)] +#![feature(async_await, await_macro)] use http::status::StatusCode; use juniper::graphql_object; diff --git a/examples/messages.rs b/examples/messages.rs index ef7058308..191622e9d 100644 --- a/examples/messages.rs +++ b/examples/messages.rs @@ -1,4 +1,4 @@ -#![feature(async_await, futures_api, await_macro)] +#![feature(async_await, await_macro)] use http::status::StatusCode; use serde::{Deserialize, Serialize}; diff --git a/examples/multipart-form/main.rs b/examples/multipart-form/main.rs index 699162fcf..abfd68059 100644 --- a/examples/multipart-form/main.rs +++ b/examples/multipart-form/main.rs @@ -1,4 +1,4 @@ -#![feature(async_await, futures_api, await_macro)] +#![feature(async_await, await_macro)] use serde::{Deserialize, Serialize}; use std::io::Read; diff --git a/src/app.rs b/src/app.rs index 9726edd9c..f0402f986 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,4 @@ -use futures::future::{self, FutureObj}; +use futures::future::{self, BoxFuture}; use http_service::HttpService; use std::sync::Arc; @@ -227,7 +227,7 @@ impl App { .ok_or(std::io::ErrorKind::InvalidInput)?; println!("Server is listening on: http://{}", addr); - http_service_hyper::serve(self.into_http_service(), addr); + http_service_hyper::run(self.into_http_service(), addr); Ok(()) } } @@ -246,7 +246,7 @@ pub struct Server { impl HttpService for Server { type Connection = (); type ConnectionFuture = future::Ready>; - type Fut = FutureObj<'static, Result>; + type Fut = BoxFuture<'static, Result>; fn connect(&self) -> Self::ConnectionFuture { future::ok(()) @@ -289,7 +289,7 @@ mod tests { app: &'a App, path: &'a str, method: http::Method, - ) -> FutureObj<'a, Response> { + ) -> BoxFuture<'a, Response> { let Selection { endpoint, params } = app.router.route(path, method.clone()); let data = Arc::new(Data::default()); diff --git a/src/endpoint.rs b/src/endpoint.rs index 7be5b8d28..1b3e062de 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -1,4 +1,4 @@ -use futures::future::{Future, FutureObj}; +use futures::future::{BoxFuture, Future}; use crate::{response::IntoResponse, Context, Response}; @@ -58,7 +58,7 @@ pub trait Endpoint: Send + Sync + 'static { } pub(crate) type DynEndpoint = - dyn (Fn(Context) -> FutureObj<'static, Response>) + 'static + Send + Sync; + dyn (Fn(Context) -> BoxFuture<'static, Response>) + 'static + Send + Sync; impl Endpoint for F where @@ -66,7 +66,7 @@ where Fut: Future + Send + 'static, Fut::Output: IntoResponse, { - type Fut = FutureObj<'static, Response>; + type Fut = BoxFuture<'static, Response>; fn call(&self, cx: Context) -> Self::Fut { let fut = (self)(cx); box_async! { diff --git a/src/error.rs b/src/error.rs index 068cfc04b..920fd4353 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,9 +1,11 @@ +use core::pin::Pin; +use futures::future::Future; use http::{HttpTryFrom, Response, StatusCode}; use http_service::Body; use crate::response::IntoResponse; -pub(crate) type BoxTryFuture = futures::future::FutureObj<'static, EndpointResult>; +pub(crate) type BoxTryFuture = Pin> + Send + 'static>>; /// A convenient `Result` instantiation appropriate for most endpoints. pub type EndpointResult> = Result; diff --git a/src/forms.rs b/src/forms.rs index 3e4d35442..8f38dfde6 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -1,4 +1,3 @@ -use futures::future::FutureObj; use http_service::Body; use multipart::server::Multipart; use std::io::Cursor; diff --git a/src/lib.rs b/src/lib.rs index 8fae19ae1..0e0e0c70b 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(futures_api, async_await, await_macro, existential_type)] +#![feature(async_await, await_macro, 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. @@ -18,7 +18,7 @@ macro_rules! box_async { {$($t:tt)*} => { - FutureObj::new(Box::new(async move { $($t)* })) + ::futures::future::FutureExt::boxed(async move { $($t)* }) }; } diff --git a/src/middleware/cookies.rs b/src/middleware/cookies.rs index ea0e97b2e..2c03e404e 100644 --- a/src/middleware/cookies.rs +++ b/src/middleware/cookies.rs @@ -1,5 +1,5 @@ use crate::cookies::CookieData; -use futures::future::FutureObj; +use futures::future::BoxFuture; use http::header::HeaderValue; use crate::{ @@ -30,7 +30,7 @@ impl Middleware for CookiesMiddleware { &'a self, mut cx: Context, next: Next<'a, Data>, - ) -> FutureObj<'a, Response> { + ) -> BoxFuture<'a, Response> { box_async! { let cookie_data = cx .extensions_mut() diff --git a/src/middleware/default_headers.rs b/src/middleware/default_headers.rs index 8be5645ae..42c1d33e8 100644 --- a/src/middleware/default_headers.rs +++ b/src/middleware/default_headers.rs @@ -1,4 +1,4 @@ -use futures::future::FutureObj; +use futures::future::BoxFuture; use http::{ header::{HeaderValue, IntoHeaderName}, @@ -40,7 +40,7 @@ impl DefaultHeaders { } impl Middleware for DefaultHeaders { - fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> FutureObj<'a, Response> { + fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> BoxFuture<'a, Response> { box_async! { let mut res = await!(next.run(cx)); diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 4243c3569..bf375c08f 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -2,7 +2,7 @@ use slog::{info, o, Drain}; use slog_async; use slog_term; -use futures::future::FutureObj; +use futures::future::BoxFuture; use crate::{ middleware::{Middleware, Next}, @@ -35,7 +35,7 @@ impl Default for RootLogger { /// Stores information during request phase and logs information once the response /// is generated. impl Middleware for RootLogger { - fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> FutureObj<'a, Response> { + fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> BoxFuture<'a, Response> { box_async! { let path = cx.uri().path().to_owned(); let method = cx.method().as_str().to_owned(); diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index d48c1e16f..35714c228 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -1,4 +1,4 @@ -use futures::future::FutureObj; +use futures::future::BoxFuture; use std::sync::Arc; use crate::{endpoint::DynEndpoint, Context, Response}; @@ -16,14 +16,14 @@ pub trait Middleware: 'static + Send + Sync { &'a self, cx: Context, next: Next<'a, AppData>, - ) -> FutureObj<'a, Response>; + ) -> BoxFuture<'a, Response>; } impl Middleware for F where - F: Send + Sync + 'static + for<'a> Fn(Context, Next<'a, Data>) -> FutureObj<'a, Response>, + F: Send + Sync + 'static + for<'a> Fn(Context, Next<'a, Data>) -> BoxFuture<'a, Response>, { - fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> FutureObj<'a, Response> { + fn handle<'a>(&'a self, cx: Context, next: Next<'a, Data>) -> BoxFuture<'a, Response> { (self)(cx, next) } } @@ -36,7 +36,7 @@ pub struct Next<'a, AppData> { impl<'a, AppData: 'static> Next<'a, AppData> { /// Asynchronously execute the remaining middleware chain. - pub fn run(mut self, cx: Context) -> FutureObj<'a, Response> { + pub fn run(mut self, cx: Context) -> BoxFuture<'a, Response> { if let Some((current, next)) = self.next_middleware.split_first() { self.next_middleware = next; current.handle(cx, self) diff --git a/src/router.rs b/src/router.rs index d403241f5..5d442cc67 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1,5 +1,5 @@ use fnv::FnvHashMap; -use futures::future::FutureObj; +use futures::future::{BoxFuture, FutureExt}; use http_service::Body; use route_recognizer::{Match, Params, Router as MethodRouter}; @@ -33,10 +33,7 @@ impl Router { self.method_map .entry(method) .or_insert_with(MethodRouter::new) - .add( - path, - Box::new(move |cx| FutureObj::new(Box::new(ep.call(cx)))), - ) + .add(path, Box::new(move |cx| ep.call(cx).boxed())) } pub(crate) fn route(&self, path: &str, method: http::Method) -> Selection<'_, AppData> { @@ -63,7 +60,7 @@ impl Router { } } -fn not_found_endpoint(_cx: Context) -> FutureObj<'static, Response> { +fn not_found_endpoint(_cx: Context) -> BoxFuture<'static, Response> { box_async! { http::Response::builder().status(http::StatusCode::NOT_FOUND).body(Body::empty()).unwrap() } diff --git a/tests/wildcard.rs b/tests/wildcard.rs index f0de6278a..e1fd2d93f 100644 --- a/tests/wildcard.rs +++ b/tests/wildcard.rs @@ -1,4 +1,4 @@ -#![feature(futures_api, async_await)] +#![feature(async_await)] use futures::executor::block_on; use http_service::Body;