diff --git a/ntex-io/CHANGES.md b/ntex-io/CHANGES.md index 500b4fb7..0708af69 100644 --- a/ntex-io/CHANGES.md +++ b/ntex-io/CHANGES.md @@ -1,6 +1,8 @@ # Changes -## [0.1.0-b.5] - 2021-12-xx +## [0.1.0-b.5] - 2021-12-24 + +* Use new ntex-service traits * Make `IoBoxed` into spearate type diff --git a/ntex-io/Cargo.toml b/ntex-io/Cargo.toml index c2c7eb20..c80c24db 100644 --- a/ntex-io/Cargo.toml +++ b/ntex-io/Cargo.toml @@ -25,11 +25,12 @@ tokio-traits = ["tok-io/net", "tok-io/rt"] tokio = ["tok-io/net", "tok-io/rt"] [dependencies] -bitflags = "1.3" ntex-codec = "0.6.0" ntex-bytes = "0.1.8" ntex-util = "0.1.4" -ntex-service = "0.3.0" +ntex-service = "0.3.0-b.0" + +bitflags = "1.3" fxhash = "0.2.1" log = "0.4" pin-project-lite = "0.2" diff --git a/ntex-rt/Cargo.toml b/ntex-rt/Cargo.toml index 676fbba6..98ba62c8 100644 --- a/ntex-rt/Cargo.toml +++ b/ntex-rt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ntex-rt" -version = "0.4.0-b.1" +version = "0.4.0-b.2" authors = ["ntex contributors "] description = "ntex runtime" keywords = ["network", "framework", "async", "futures"] @@ -23,7 +23,7 @@ tokio = ["tok-io", "ntex-io/tokio"] [dependencies] ntex-bytes = "0.1.8" -ntex-io = "0.1.0-b.3" +ntex-io = "0.1.0-b.5" ntex-util = "0.1.3" async-oneshot = "0.5.0" async-channel = "1.6.1" diff --git a/ntex-service/Cargo.toml b/ntex-service/Cargo.toml index ec1e74bb..54f5b6dd 100644 --- a/ntex-service/Cargo.toml +++ b/ntex-service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ntex-service" -version = "0.3.0" +version = "0.3.0-b.0" authors = ["ntex contributors "] description = "ntex service" keywords = ["network", "framework", "async", "futures"] diff --git a/ntex-service/src/and_then_apply_fn.rs b/ntex-service/src/and_then_apply_fn.rs deleted file mode 100644 index a4c3a525..00000000 --- a/ntex-service/src/and_then_apply_fn.rs +++ /dev/null @@ -1,348 +0,0 @@ -use std::{ - future::Future, marker::PhantomData, pin::Pin, rc::Rc, task::Context, task::Poll, -}; - -use crate::{Service, ServiceFactory}; - -/// `Apply` service combinator -pub(crate) struct AndThenApplyFn -where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From + From, -{ - srv: Rc<(A, B, F)>, - r: PhantomData (Fut, Req2, Res, Err)>, -} - -impl AndThenApplyFn -where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From + From, -{ - /// Create new `Apply` combinator - pub(crate) fn new(a: A, b: B, f: F) -> Self { - Self { - srv: Rc::new((a, b, f)), - r: PhantomData, - } - } -} - -impl Clone for AndThenApplyFn -where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From + From, -{ - fn clone(&self) -> Self { - AndThenApplyFn { - srv: self.srv.clone(), - r: PhantomData, - } - } -} - -impl Service for AndThenApplyFn -where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From + From, -{ - type Response = Res; - type Error = Err; - type Future = AndThenApplyFnFuture; - - fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { - let inner = self.srv.as_ref(); - let not_ready = inner.0.poll_ready(cx)?.is_pending(); - if inner.1.poll_ready(cx)?.is_pending() || not_ready { - Poll::Pending - } else { - Poll::Ready(Ok(())) - } - } - - fn shutdown(&self) { - let srv = self.srv.as_ref(); - - srv.0.shutdown(); - srv.1.shutdown(); - } - - fn call(&self, req: A::Request) -> Self::Future { - let fut = self.srv.as_ref().0.call(req); - AndThenApplyFnFuture { - state: State::A { - fut, - b: Some(self.srv.clone()), - }, - } - } -} - -pin_project_lite::pin_project! { - pub(crate) struct AndThenApplyFnFuture - where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From, - Err: From, - { - #[pin] - state: State, - } -} - -pin_project_lite::pin_project! { - #[project = StateProject] - enum State - where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From, - Err: From, - { - A { #[pin] fut: A::Future, b: Option> }, - B { #[pin] fut: Fut }, - Empty, - } -} - -impl Future for AndThenApplyFnFuture -where - A: Service, - B: Service, - F: Fn(A::Response, &B) -> Fut, - Fut: Future>, - Err: From + From, -{ - type Output = Result; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let mut this = self.as_mut().project(); - - match this.state.as_mut().project() { - StateProject::A { fut, b } => match fut.poll(cx)? { - Poll::Ready(res) => { - let b = b.take().unwrap(); - this.state.set(State::Empty); - let b = b.as_ref(); - let fut = (&b.2)(res, &b.1); - this.state.set(State::B { fut }); - self.poll(cx) - } - Poll::Pending => Poll::Pending, - }, - StateProject::B { fut } => fut.poll(cx).map(|r| { - this.state.set(State::Empty); - r - }), - StateProject::Empty => { - panic!("future must not be polled after it returned `Poll::Ready`") - } - } - } -} - -/// `AndThenApplyFn` service factory -pub(crate) struct AndThenApplyFnFactory { - srv: Rc<(A, B, F)>, - r: PhantomData<(Fut, Res, Err)>, -} - -impl AndThenApplyFnFactory -where - A: ServiceFactory, - B: ServiceFactory, - F: Fn(A::Response, &B::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - /// Create new `ApplyNewService` new service instance - pub(crate) fn new(a: A, b: B, f: F) -> Self { - Self { - srv: Rc::new((a, b, f)), - r: PhantomData, - } - } -} - -impl Clone for AndThenApplyFnFactory { - fn clone(&self) -> Self { - Self { - srv: self.srv.clone(), - r: PhantomData, - } - } -} - -impl ServiceFactory - for AndThenApplyFnFactory -where - A: ServiceFactory, - A::Config: Clone, - B: ServiceFactory, - F: Fn(A::Response, &B::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - type Request = A::Request; - type Response = Res; - type Error = Err; - type Service = AndThenApplyFn; - type Config = A::Config; - type InitError = A::InitError; - type Future = AndThenApplyFnFactoryResponse; - - fn new_service(&self, cfg: A::Config) -> Self::Future { - let srv = &*self.srv; - AndThenApplyFnFactoryResponse { - a: None, - b: None, - f: srv.2.clone(), - fut_a: srv.0.new_service(cfg.clone()), - fut_b: srv.1.new_service(cfg), - } - } -} - -pin_project_lite::pin_project! { - pub(crate) struct AndThenApplyFnFactoryResponse - where - A: ServiceFactory, - B: ServiceFactory, - F: Fn(A::Response, &B::Service) -> Fut, - Fut: Future>, - Err: From, - Err: From, - { - #[pin] - fut_b: B::Future, - #[pin] - fut_a: A::Future, - f: F, - a: Option, - b: Option, - } -} - -impl Future - for AndThenApplyFnFactoryResponse -where - A: ServiceFactory, - B: ServiceFactory, - F: Fn(A::Response, &B::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - type Output = - Result, A::InitError>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - - if this.a.is_none() { - if let Poll::Ready(service) = this.fut_a.poll(cx)? { - *this.a = Some(service); - } - } - - if this.b.is_none() { - if let Poll::Ready(service) = this.fut_b.poll(cx)? { - *this.b = Some(service); - } - } - - if this.a.is_some() && this.b.is_some() { - Poll::Ready(Ok(AndThenApplyFn { - srv: Rc::new(( - this.a.take().unwrap(), - this.b.take().unwrap(), - this.f.clone(), - )), - r: PhantomData, - })) - } else { - Poll::Pending - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use crate::{fn_service, pipeline, pipeline_factory, Service, ServiceFactory}; - use ntex_util::future::{lazy, Ready}; - - #[derive(Clone)] - struct Srv; - impl Service for Srv { - type Request = (); - type Response = (); - type Error = (); - type Future = Ready<(), ()>; - - fn poll_ready(&self, _: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&self, _: Self::Request) -> Self::Future { - Ready::Ok(()) - } - } - - #[ntex::test] - async fn test_service() { - let srv = pipeline(Ready::<_, ()>::Ok) - .and_then_apply_fn(Srv, |req: &'static str, s| { - let f = s.call(()); - async move { f.await.map(move |res| (req, res)) } - }) - .clone(); - let res = lazy(|cx| srv.poll_ready(cx)).await; - assert_eq!(res, Poll::Ready(Ok(()))); - - let res = srv.call("srv").await; - assert!(res.is_ok()); - assert_eq!(res.unwrap(), ("srv", ())); - - let res = lazy(|cx| srv.poll_shutdown(cx, false)).await; - assert_eq!(res, Poll::Ready(())); - } - - #[ntex::test] - async fn test_service_factory() { - let new_srv = - pipeline_factory(|| Ready::<_, ()>::Ok(fn_service(Ready::<_, ()>::Ok))) - .and_then_apply_fn( - || Ready::Ok(Srv), - |req: &'static str, s| { - let f = s.call(()); - async move { f.await.map(move |res| (req, res)) } - }, - ) - .clone(); - let srv = new_srv.new_service(()).await.unwrap(); - let res = lazy(|cx| srv.poll_ready(cx)).await; - assert_eq!(res, Poll::Ready(Ok(()))); - - let res = srv.call("srv").await; - assert!(res.is_ok()); - assert_eq!(res.unwrap(), ("srv", ())); - } -} diff --git a/ntex-service/src/lib.rs b/ntex-service/src/lib.rs index 471f317b..65d6c0ea 100644 --- a/ntex-service/src/lib.rs +++ b/ntex-service/src/lib.rs @@ -1,4 +1,4 @@ -//#![deny(rust_2018_idioms, warnings)] +#![deny(rust_2018_idioms, warnings)] #![allow(clippy::type_complexity)] use std::future::Future; @@ -6,7 +6,6 @@ use std::rc::Rc; use std::task::{self, Context, Poll}; mod and_then; -// mod and_then_apply_fn; mod apply; pub mod boxed; mod fn_service; diff --git a/ntex-tls/Cargo.toml b/ntex-tls/Cargo.toml index 032dbc35..39277b63 100644 --- a/ntex-tls/Cargo.toml +++ b/ntex-tls/Cargo.toml @@ -26,9 +26,9 @@ rustls = ["tls_rust"] [dependencies] ntex-bytes = "0.1.8" -ntex-io = "0.1.0-b.3" -ntex-util = "0.1.3" -ntex-service = "0.3.0" +ntex-io = "0.1.0-b.5" +ntex-util = "0.1.4" +ntex-service = "0.3.0-b.0" pin-project-lite = "0.2" # openssl diff --git a/ntex/CHANGES.md b/ntex/CHANGES.md index 74efa8a7..768f7795 100644 --- a/ntex/CHANGES.md +++ b/ntex/CHANGES.md @@ -1,6 +1,8 @@ # Changes -## [0.5.0-b.3] - 2021-12-23 +## [0.5.0-b.3] - 2021-12-24 + +* Use new ntex-service traits * Remove websocket support from http::client diff --git a/ntex/Cargo.toml b/ntex/Cargo.toml index 3a187825..c0a43361 100644 --- a/ntex/Cargo.toml +++ b/ntex/Cargo.toml @@ -41,13 +41,13 @@ url = ["url-pkg"] [dependencies] ntex-codec = "0.6.0" ntex-router = "0.5.1" -ntex-service = "0.3.0" +ntex-service = "0.3.0-b.0" ntex-macros = "0.1.3" ntex-util = "0.1.4" ntex-bytes = "0.1.8" -ntex-tls = "0.1.0-b.2" +ntex-tls = "0.1.0-b.3" ntex-io = "0.1.0-b.5" -ntex-rt = { version = "0.4.0-b.1", default-features = false, features = ["tokio"] } +ntex-rt = { version = "0.4.0-b.2", default-features = false, features = ["tokio"] } base64 = "0.13" bitflags = "1.3"