Skip to content

Commit

Permalink
add combinator for boxing ServiceFactory::Future (#118)
Browse files Browse the repository at this point in the history
* add combinator for boxing ServiceFactory::Future

* fix lint

* fix typo
  • Loading branch information
fakeshadow authored Dec 1, 2021
1 parent 0f81d07 commit 0c7980c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
32 changes: 32 additions & 0 deletions service/src/factory/boxed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use alloc::boxed::Box;

use crate::BoxFuture;

use super::ServiceFactory;

pub struct BoxedServiceFactory<F> {
factory: F,
}

impl<F> BoxedServiceFactory<F> {
pub(super) fn new(factory: F) -> Self {
Self { factory }
}
}

impl<F, Req> ServiceFactory<Req> for BoxedServiceFactory<F>
where
F: ServiceFactory<Req>,
F::Future: 'static,
{
type Response = F::Response;
type Error = F::Error;
type Config = F::Config;
type Service = F::Service;
type InitError = F::InitError;
type Future = BoxFuture<'static, Self::Service, Self::InitError>;

fn new_service(&self, cfg: Self::Config) -> Self::Future {
Box::pin(self.factory.new_service(cfg))
}
}
20 changes: 20 additions & 0 deletions service/src/factory/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use alloc::boxed::Box;
use crate::transform::Transform;

use super::{
boxed::BoxedServiceFactory,
pipeline::{marker, PipelineServiceFactory},
ServiceFactory, ServiceFactoryObject,
};
Expand Down Expand Up @@ -34,6 +35,16 @@ pub trait ServiceFactoryExt<Req>: ServiceFactory<Req> {
PipelineServiceFactory::new(self, err)
}

/// Box `<Self as ServiceFactory<_>>::Future` to reduce it's stack size.
///
/// *. This combinator does not box `Self` or `Self::Service`.
fn boxed_future(self) -> BoxedServiceFactory<Self>
where
Self: Sized,
{
BoxedServiceFactory::new(self)
}

/// Chain another service factory who's service takes `Self`'s `Service::Future` output as
/// `Service::Request`.
///
Expand All @@ -48,6 +59,10 @@ pub trait ServiceFactoryExt<Req>: ServiceFactory<Req> {
PipelineServiceFactory::new(self, factory)
}

/// Chain another service factory who's service takes `Self`'s `Service::Response` output as
/// `Service::Request`.
///
/// *. Unlike `then` combinator both `F` and `Self`'s readiness are checked beforehand.
fn and_then<F>(self, factory: F) -> PipelineServiceFactory<Self, F, marker::AndThen>
where
F: ServiceFactory<Self::Response>,
Expand All @@ -74,6 +89,11 @@ pub trait ServiceFactoryExt<Req>: ServiceFactory<Req> {
PipelineServiceFactory::new(self, transform)
}

/// Box self and cast it to a trait object.
///
/// This would erase `Self::Service` type and it's GAT nature.
///
/// See [crate::service::ServiceObject] for detail.
fn into_object(self) -> ServiceFactoryObject<Req, Self::Response, Self::Error, Self::Config, Self::InitError>
where
Self: Sized + 'static,
Expand Down
1 change: 1 addition & 0 deletions service/src/factory/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub(crate) mod pipeline;

mod and_then;
mod boxed;
mod ext;
mod function;
mod map;
Expand Down

0 comments on commit 0c7980c

Please sign in to comment.