1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-30 17:44:34 +01:00

remove futures-util from service deps (#235)

This commit is contained in:
Rob Ede 2020-12-27 18:24:57 +00:00 committed by GitHub
parent 8a58a341a4
commit ba44ea7d0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 159 additions and 86 deletions

View File

@ -8,9 +8,11 @@
* Migrate pin projections to `pin-project-lite`. [#233] * Migrate pin projections to `pin-project-lite`. [#233]
* Remove `AndThenApplyFn` and Pipeline `and_then_apply_fn`. Use the * Remove `AndThenApplyFn` and Pipeline `and_then_apply_fn`. Use the
`.and_then(apply_fn(...))` construction. [#233] `.and_then(apply_fn(...))` construction. [#233]
* Move non-vital methods to `ServiceExt` and `ServiceFactoryExt` extension traits. [#235]
[#232]: https://github.com/actix/actix-net/pull/232 [#232]: https://github.com/actix/actix-net/pull/232
[#233]: https://github.com/actix/actix-net/pull/233 [#233]: https://github.com/actix/actix-net/pull/233
[#235]: https://github.com/actix/actix-net/pull/235
## 1.0.6 - 2020-08-09 ## 1.0.6 - 2020-08-09

View File

@ -17,10 +17,9 @@ name = "actix_service"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
pin-project-lite = "0.2"
futures-util = { version = "0.3.7", default-features = false }
futures-core = { version = "0.3.7", default-features = false } futures-core = { version = "0.3.7", default-features = false }
pin-project-lite = "0.2"
[dev-dependencies] [dev-dependencies]
actix-rt = "1.0.0" actix-rt = "1.0.0"
criterion = "0.3" futures-util = { version = "0.3.7", default-features = false }

View File

@ -279,9 +279,11 @@ mod tests {
task::{Context, Poll}, task::{Context, Poll},
}; };
use futures_util::future::{lazy, ok, ready, Ready}; use futures_util::future::lazy;
use crate::{fn_factory, pipeline, pipeline_factory, Service, ServiceFactory}; use crate::{
fn_factory, ok, pipeline, pipeline_factory, ready, Ready, Service, ServiceFactory,
};
struct Srv1(Rc<Cell<usize>>); struct Srv1(Rc<Cell<usize>>);

View File

@ -211,10 +211,10 @@ where
mod tests { mod tests {
use core::task::Poll; use core::task::Poll;
use futures_util::future::{lazy, ok, Ready}; use futures_util::future::lazy;
use super::*; use super::*;
use crate::{pipeline, pipeline_factory, Service, ServiceFactory}; use crate::{ok, pipeline, pipeline_factory, Ready, Service, ServiceFactory};
#[derive(Clone)] #[derive(Clone)]
struct Srv; struct Srv;

View File

@ -6,8 +6,6 @@ use core::{
task::{Context, Poll}, task::{Context, Poll},
}; };
use futures_util::future::FutureExt;
use crate::{Service, ServiceFactory}; use crate::{Service, ServiceFactory};
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>; pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
@ -103,11 +101,11 @@ where
type Future = BoxFuture<Result<Self::Service, Self::InitError>>; type Future = BoxFuture<Result<Self::Service, Self::InitError>>;
fn new_service(&self, cfg: Cfg) -> Self::Future { fn new_service(&self, cfg: Cfg) -> Self::Future {
Box::pin( let fut = self.factory.new_service(cfg);
self.factory Box::pin(async {
.new_service(cfg) let res = fut.await;
.map(|res| res.map(ServiceWrapper::boxed)), res.map(ServiceWrapper::boxed)
) })
} }
} }

70
actix-service/src/ext.rs Normal file
View File

@ -0,0 +1,70 @@
use crate::{dev, Service, ServiceFactory};
pub trait ServiceExt<Req>: Service<Req> {
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
///
/// This function is similar to the `Option::map` or `Iterator::map` where
/// it will change the type of the underlying service.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it, similar to the existing `map` methods in the
/// standard library.
fn map<F, R>(self, f: F) -> dev::Map<Self, F, Req, R>
where
Self: Sized,
F: FnMut(Self::Response) -> R,
{
dev::Map::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
///
/// This function is similar to the `Result::map_err` where it will change
/// the error type of the underlying service. For example, this can be useful to
/// ensure that services have the same error type.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it.
fn map_err<F, E>(self, f: F) -> dev::MapErr<Self, Req, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E,
{
dev::MapErr::new(self, f)
}
}
impl<S, Req> ServiceExt<Req> for S where S: Service<Req> {}
pub trait ServiceFactoryExt<Req>: ServiceFactory<Req> {
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
fn map<F, R>(self, f: F) -> crate::map::MapServiceFactory<Self, F, Req, R>
where
Self: Sized,
F: FnMut(Self::Response) -> R + Clone,
{
crate::map::MapServiceFactory::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, Req, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E + Clone,
{
crate::map_err::MapErrServiceFactory::new(self, f)
}
/// Map this factory's init error to a different error, returning a new service.
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, Req, E>
where
Self: Sized,
F: Fn(Self::InitError) -> E + Clone,
{
crate::map_init_err::MapInitErr::new(self, f)
}
}
impl<S, Req> ServiceFactoryExt<Req> for S where S: ServiceFactory<Req> {}

View File

@ -1,8 +1,6 @@
use core::{future::Future, marker::PhantomData, task::Poll}; use core::{future::Future, marker::PhantomData, task::Poll};
use futures_util::future::{ok, Ready}; use crate::{ok, IntoService, IntoServiceFactory, Ready, Service, ServiceFactory};
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
/// Create `ServiceFactory` for function that can act as a `Service` /// Create `ServiceFactory` for function that can act as a `Service`
pub fn fn_service<F, Fut, Req, Res, Err, Cfg>( pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(
@ -357,10 +355,10 @@ where
mod tests { mod tests {
use core::task::Poll; use core::task::Poll;
use futures_util::future::{lazy, ok}; use futures_util::future::lazy;
use super::*; use super::*;
use crate::{Service, ServiceFactory}; use crate::{ok, Service, ServiceFactory};
#[actix_rt::test] #[actix_rt::test]
async fn test_fn_service() { async fn test_fn_service() {

View File

@ -19,23 +19,29 @@ mod and_then;
mod apply; mod apply;
mod apply_cfg; mod apply_cfg;
pub mod boxed; pub mod boxed;
mod ext;
mod fn_service; mod fn_service;
mod map; mod map;
mod map_config; mod map_config;
mod map_err; mod map_err;
mod map_init_err; mod map_init_err;
mod pipeline; mod pipeline;
mod ready;
mod then; mod then;
mod transform; mod transform;
mod transform_err; mod transform_err;
pub use self::apply::{apply_fn, apply_fn_factory}; pub use self::apply::{apply_fn, apply_fn_factory};
pub use self::apply_cfg::{apply_cfg, apply_cfg_factory}; pub use self::apply_cfg::{apply_cfg, apply_cfg_factory};
pub use self::ext::{ServiceExt, ServiceFactoryExt};
pub use self::fn_service::{fn_factory, fn_factory_with_config, fn_service}; pub use self::fn_service::{fn_factory, fn_factory_with_config, fn_service};
pub use self::map_config::{map_config, unit_config}; pub use self::map_config::{map_config, unit_config};
pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory}; pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory};
pub use self::transform::{apply, Transform}; pub use self::transform::{apply, Transform};
#[allow(unused_imports)]
use self::ready::{err, ok, ready, Ready};
/// An asynchronous operation from `Request` to a `Response`. /// An asynchronous operation from `Request` to a `Response`.
/// ///
/// The `Service` trait models a request/response interaction, receiving requests and returning /// The `Service` trait models a request/response interaction, receiving requests and returning
@ -110,39 +116,6 @@ pub trait Service<Req> {
/// Calling `call` without calling `poll_ready` is permitted. The /// Calling `call` without calling `poll_ready` is permitted. The
/// implementation must be resilient to this fact. /// implementation must be resilient to this fact.
fn call(&mut self, req: Req) -> Self::Future; fn call(&mut self, req: Req) -> Self::Future;
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
///
/// This function is similar to the `Option::map` or `Iterator::map` where
/// it will change the type of the underlying service.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it, similar to the existing `map` methods in the
/// standard library.
fn map<F, R>(self, f: F) -> crate::dev::Map<Self, F, Req, R>
where
Self: Sized,
F: FnMut(Self::Response) -> R,
{
crate::dev::Map::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
///
/// This function is similar to the `Result::map_err` where it will change
/// the error type of the underlying service. For example, this can be useful to
/// ensure that services have the same error type.
///
/// Note that this function consumes the receiving service and returns a
/// wrapped version of it.
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, Req, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E,
{
crate::dev::MapErr::new(self, f)
}
} }
/// Factory for creating `Service`s. /// Factory for creating `Service`s.
@ -175,34 +148,6 @@ pub trait ServiceFactory<Req> {
/// Create and return a new service asynchronously. /// Create and return a new service asynchronously.
fn new_service(&self, cfg: Self::Config) -> Self::Future; fn new_service(&self, cfg: Self::Config) -> Self::Future;
/// Map this service's output to a different type, returning a new service
/// of the resulting type.
fn map<F, R>(self, f: F) -> crate::map::MapServiceFactory<Self, F, Req, R>
where
Self: Sized,
F: FnMut(Self::Response) -> R + Clone,
{
crate::map::MapServiceFactory::new(self, f)
}
/// Map this service's error to a different error, returning a new service.
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, Req, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E + Clone,
{
crate::map_err::MapErrServiceFactory::new(self, f)
}
/// Map this factory's init error to a different error, returning a new service.
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, Req, E>
where
Self: Sized,
F: Fn(Self::InitError) -> E + Clone,
{
crate::map_init_err::MapInitErr::new(self, f)
}
} }
impl<'a, S, Req> Service<Req> for &'a mut S impl<'a, S, Req> Service<Req> for &'a mut S

View File

@ -199,10 +199,12 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use futures_util::future::{lazy, ok, Ready}; use futures_util::future::lazy;
use super::*; use super::*;
use crate::{IntoServiceFactory, Service, ServiceFactory}; use crate::{
ok, IntoServiceFactory, Ready, Service, ServiceExt, ServiceFactory, ServiceFactoryExt,
};
struct Srv; struct Srv;

View File

@ -203,10 +203,13 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use futures_util::future::{err, lazy, ok, Ready}; use futures_util::future::lazy;
use super::*; use super::*;
use crate::{IntoServiceFactory, Service, ServiceFactory}; use crate::{
err, ok, IntoServiceFactory, Ready, Service, ServiceExt, ServiceFactory,
ServiceFactoryExt,
};
struct Srv; struct Srv;

View File

@ -0,0 +1,54 @@
//! When MSRV is 1.48, replace with `core::future::Ready` and `core::future::ready()`.
use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
/// Future for the [`ready`](ready()) function.
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T> {
val: Option<T>,
}
impl<T> Ready<T> {
/// Unwraps the value from this immediately ready future.
#[inline]
pub fn into_inner(mut self) -> T {
self.val.take().unwrap()
}
}
impl<T> Unpin for Ready<T> {}
impl<T> Future for Ready<T> {
type Output = T;
#[inline]
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
let val = self.val.take().expect("Ready can not be polled twice.");
Poll::Ready(val)
}
}
/// Creates a future that is immediately ready with a value.
#[allow(dead_code)]
pub(crate) fn ready<T>(val: T) -> Ready<T> {
Ready { val: Some(val) }
}
/// Create a future that is immediately ready with a success value.
#[allow(dead_code)]
pub(crate) fn ok<T, E>(val: T) -> Ready<Result<T, E>> {
Ready { val: Some(Ok(val)) }
}
/// Create a future that is immediately ready with an error value.
#[allow(dead_code)]
pub(crate) fn err<T, E>(err: E) -> Ready<Result<T, E>> {
Ready {
val: Some(Err(err)),
}
}

View File

@ -254,9 +254,9 @@ mod tests {
task::{Context, Poll}, task::{Context, Poll},
}; };
use futures_util::future::{err, lazy, ok, ready, Ready}; use futures_util::future::lazy;
use crate::{pipeline, pipeline_factory, Service, ServiceFactory}; use crate::{err, ok, pipeline, pipeline_factory, ready, Ready, Service, ServiceFactory};
#[derive(Clone)] #[derive(Clone)]
struct Srv1(Rc<Cell<usize>>); struct Srv1(Rc<Cell<usize>>);