2020-07-22 12:32:13 +09:00
|
|
|
use std::cell::RefCell;
|
2019-11-14 18:38:24 +06:00
|
|
|
use std::future::Future;
|
2019-03-09 09:01:02 -08:00
|
|
|
use std::marker::PhantomData;
|
2019-11-14 18:38:24 +06:00
|
|
|
use std::pin::Pin;
|
2020-07-19 23:05:36 +02:00
|
|
|
use std::rc::Rc;
|
2020-07-22 12:32:13 +09:00
|
|
|
use std::task::{Context, Poll};
|
2019-03-09 09:01:02 -08:00
|
|
|
|
2019-11-18 14:30:04 +06:00
|
|
|
use crate::{Service, ServiceFactory};
|
2019-05-12 06:03:50 -07:00
|
|
|
|
2019-12-10 21:34:51 +06:00
|
|
|
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory
|
2020-01-16 16:58:11 -08:00
|
|
|
pub fn apply_cfg<F, C, T, R, S, E>(
|
|
|
|
srv: T,
|
|
|
|
f: F,
|
|
|
|
) -> impl ServiceFactory<
|
|
|
|
Config = C,
|
|
|
|
Request = S::Request,
|
|
|
|
Response = S::Response,
|
|
|
|
Error = S::Error,
|
|
|
|
Service = S,
|
|
|
|
InitError = E,
|
|
|
|
Future = R,
|
|
|
|
> + Clone
|
2019-03-12 16:32:10 -07:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T) -> R,
|
2019-05-12 06:03:50 -07:00
|
|
|
T: Service,
|
2019-11-19 14:51:40 +06:00
|
|
|
R: Future<Output = Result<S, E>>,
|
2019-05-12 06:03:50 -07:00
|
|
|
S: Service,
|
2019-03-12 16:32:10 -07:00
|
|
|
{
|
2019-05-12 06:03:50 -07:00
|
|
|
ApplyConfigService {
|
2020-07-19 23:05:36 +02:00
|
|
|
srv: Rc::new(RefCell::new((srv, f))),
|
2019-05-12 06:03:50 -07:00
|
|
|
_t: PhantomData,
|
|
|
|
}
|
2019-03-09 09:01:02 -08:00
|
|
|
}
|
|
|
|
|
2019-12-10 21:34:51 +06:00
|
|
|
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory
|
|
|
|
///
|
|
|
|
/// Service1 get constructed from `T` factory.
|
2019-11-14 18:38:24 +06:00
|
|
|
pub fn apply_cfg_factory<F, C, T, R, S>(
|
2019-12-10 21:34:51 +06:00
|
|
|
factory: T,
|
2019-06-06 14:28:07 +06:00
|
|
|
f: F,
|
2020-01-16 16:58:11 -08:00
|
|
|
) -> impl ServiceFactory<
|
|
|
|
Config = C,
|
|
|
|
Request = S::Request,
|
|
|
|
Response = S::Response,
|
|
|
|
Error = S::Error,
|
|
|
|
Service = S,
|
|
|
|
InitError = T::InitError,
|
|
|
|
> + Clone
|
2019-06-06 14:28:07 +06:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
2019-11-14 18:38:24 +06:00
|
|
|
T: ServiceFactory<Config = ()>,
|
2019-08-27 05:28:15 +06:00
|
|
|
T::InitError: From<T::Error>,
|
2019-11-14 18:38:24 +06:00
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
S: Service,
|
|
|
|
{
|
2019-11-18 14:30:04 +06:00
|
|
|
ApplyConfigServiceFactory {
|
2020-07-19 23:05:36 +02:00
|
|
|
srv: Rc::new(RefCell::new((factory, f))),
|
2019-06-06 14:28:07 +06:00
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-10 21:34:51 +06:00
|
|
|
/// Convert `Fn(Config, &mut Server) -> Future<Service>` fn to NewService\
|
2020-01-16 16:58:11 -08:00
|
|
|
struct ApplyConfigService<F, C, T, R, S, E>
|
2019-03-09 09:01:02 -08:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T) -> R,
|
2019-05-12 06:03:50 -07:00
|
|
|
T: Service,
|
2019-11-14 18:38:24 +06:00
|
|
|
R: Future<Output = Result<S, E>>,
|
2019-05-12 06:03:50 -07:00
|
|
|
S: Service,
|
2019-03-09 09:01:02 -08:00
|
|
|
{
|
2020-07-19 23:05:36 +02:00
|
|
|
srv: Rc<RefCell<(T, F)>>,
|
2019-05-12 06:03:50 -07:00
|
|
|
_t: PhantomData<(C, R, S)>,
|
2019-03-09 09:01:02 -08:00
|
|
|
}
|
|
|
|
|
2019-11-14 18:38:24 +06:00
|
|
|
impl<F, C, T, R, S, E> Clone for ApplyConfigService<F, C, T, R, S, E>
|
2019-03-09 09:01:02 -08:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T) -> R,
|
2019-05-12 06:03:50 -07:00
|
|
|
T: Service,
|
2019-11-14 18:38:24 +06:00
|
|
|
R: Future<Output = Result<S, E>>,
|
2019-05-12 06:03:50 -07:00
|
|
|
S: Service,
|
2019-03-09 09:01:02 -08:00
|
|
|
{
|
|
|
|
fn clone(&self) -> Self {
|
2019-05-12 06:03:50 -07:00
|
|
|
ApplyConfigService {
|
|
|
|
srv: self.srv.clone(),
|
|
|
|
_t: PhantomData,
|
2019-03-09 09:01:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-14 18:38:24 +06:00
|
|
|
impl<F, C, T, R, S, E> ServiceFactory for ApplyConfigService<F, C, T, R, S, E>
|
2019-03-09 09:01:02 -08:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T) -> R,
|
2019-05-12 06:03:50 -07:00
|
|
|
T: Service,
|
2019-11-19 14:51:40 +06:00
|
|
|
R: Future<Output = Result<S, E>>,
|
2019-05-12 06:03:50 -07:00
|
|
|
S: Service,
|
2019-03-09 09:01:02 -08:00
|
|
|
{
|
2019-05-12 06:03:50 -07:00
|
|
|
type Config = C;
|
2019-03-12 16:32:10 -07:00
|
|
|
type Request = S::Request;
|
|
|
|
type Response = S::Response;
|
|
|
|
type Error = S::Error;
|
2019-05-12 06:03:50 -07:00
|
|
|
type Service = S;
|
2019-03-09 09:01:02 -08:00
|
|
|
|
2019-11-14 18:38:24 +06:00
|
|
|
type InitError = E;
|
2019-11-19 14:51:40 +06:00
|
|
|
type Future = R;
|
2019-03-09 09:01:02 -08:00
|
|
|
|
2019-12-02 21:27:48 +06:00
|
|
|
fn new_service(&self, cfg: C) -> Self::Future {
|
2020-07-19 23:05:36 +02:00
|
|
|
let (t, f) = &mut *self.srv.borrow_mut();
|
|
|
|
f(cfg, t)
|
2019-03-09 09:01:02 -08:00
|
|
|
}
|
|
|
|
}
|
2019-06-06 14:28:07 +06:00
|
|
|
|
|
|
|
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService
|
2020-01-16 16:58:11 -08:00
|
|
|
struct ApplyConfigServiceFactory<F, C, T, R, S>
|
2019-06-06 14:28:07 +06:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
2019-11-14 18:38:24 +06:00
|
|
|
T: ServiceFactory<Config = ()>,
|
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
S: Service,
|
|
|
|
{
|
2020-07-19 23:05:36 +02:00
|
|
|
srv: Rc<RefCell<(T, F)>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
_t: PhantomData<(C, R, S)>,
|
|
|
|
}
|
|
|
|
|
2019-11-18 14:30:04 +06:00
|
|
|
impl<F, C, T, R, S> Clone for ApplyConfigServiceFactory<F, C, T, R, S>
|
2019-06-06 14:28:07 +06:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
2019-11-14 18:38:24 +06:00
|
|
|
T: ServiceFactory<Config = ()>,
|
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
S: Service,
|
|
|
|
{
|
|
|
|
fn clone(&self) -> Self {
|
2019-11-18 14:30:04 +06:00
|
|
|
Self {
|
2019-06-06 14:28:07 +06:00
|
|
|
srv: self.srv.clone(),
|
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-18 14:30:04 +06:00
|
|
|
impl<F, C, T, R, S> ServiceFactory for ApplyConfigServiceFactory<F, C, T, R, S>
|
2019-06-06 14:28:07 +06:00
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
2019-11-14 18:38:24 +06:00
|
|
|
T: ServiceFactory<Config = ()>,
|
2019-08-27 05:28:15 +06:00
|
|
|
T::InitError: From<T::Error>,
|
2019-11-19 14:51:40 +06:00
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
S: Service,
|
|
|
|
{
|
|
|
|
type Config = C;
|
|
|
|
type Request = S::Request;
|
|
|
|
type Response = S::Response;
|
|
|
|
type Error = S::Error;
|
|
|
|
type Service = S;
|
|
|
|
|
2019-11-14 18:38:24 +06:00
|
|
|
type InitError = T::InitError;
|
2019-11-18 14:30:04 +06:00
|
|
|
type Future = ApplyConfigServiceFactoryResponse<F, C, T, R, S>;
|
2019-06-06 14:28:07 +06:00
|
|
|
|
2019-12-02 21:27:48 +06:00
|
|
|
fn new_service(&self, cfg: C) -> Self::Future {
|
2019-11-18 14:30:04 +06:00
|
|
|
ApplyConfigServiceFactoryResponse {
|
2019-12-02 21:27:48 +06:00
|
|
|
cfg: Some(cfg),
|
2019-12-05 12:37:26 +06:00
|
|
|
store: self.srv.clone(),
|
2020-07-19 23:05:36 +02:00
|
|
|
state: State::A(self.srv.borrow().0.new_service(())),
|
2019-06-06 14:28:07 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-05 12:37:26 +06:00
|
|
|
#[pin_project::pin_project]
|
2020-01-16 16:58:11 -08:00
|
|
|
struct ApplyConfigServiceFactoryResponse<F, C, T, R, S>
|
2019-12-05 12:37:26 +06:00
|
|
|
where
|
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
|
|
|
T: ServiceFactory<Config = ()>,
|
|
|
|
T::InitError: From<T::Error>,
|
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
|
|
|
S: Service,
|
|
|
|
{
|
|
|
|
cfg: Option<C>,
|
2020-07-19 23:05:36 +02:00
|
|
|
store: Rc<RefCell<(T, F)>>,
|
2019-12-05 12:37:26 +06:00
|
|
|
#[pin]
|
|
|
|
state: State<T, R, S>,
|
|
|
|
}
|
|
|
|
|
2020-06-06 06:42:45 +09:00
|
|
|
#[pin_project::pin_project(project = StateProj)]
|
2019-12-05 12:37:26 +06:00
|
|
|
enum State<T, R, S>
|
|
|
|
where
|
|
|
|
T: ServiceFactory<Config = ()>,
|
|
|
|
T::InitError: From<T::Error>,
|
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
|
|
|
S: Service,
|
|
|
|
{
|
|
|
|
A(#[pin] T::Future),
|
|
|
|
B(T::Service),
|
|
|
|
C(#[pin] R),
|
2019-06-06 14:28:07 +06:00
|
|
|
}
|
|
|
|
|
2019-11-18 14:30:04 +06:00
|
|
|
impl<F, C, T, R, S> Future for ApplyConfigServiceFactoryResponse<F, C, T, R, S>
|
|
|
|
where
|
2019-12-02 21:27:48 +06:00
|
|
|
F: FnMut(C, &mut T::Service) -> R,
|
2019-11-18 14:30:04 +06:00
|
|
|
T: ServiceFactory<Config = ()>,
|
|
|
|
T::InitError: From<T::Error>,
|
2019-11-19 14:51:40 +06:00
|
|
|
R: Future<Output = Result<S, T::InitError>>,
|
2019-06-06 14:28:07 +06:00
|
|
|
S: Service,
|
|
|
|
{
|
2019-11-14 18:38:24 +06:00
|
|
|
type Output = Result<S, T::InitError>;
|
2019-06-06 14:28:07 +06:00
|
|
|
|
2019-11-19 14:51:40 +06:00
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
|
let mut this = self.as_mut().project();
|
2019-11-18 14:30:04 +06:00
|
|
|
|
2019-12-05 12:37:26 +06:00
|
|
|
match this.state.as_mut().project() {
|
2020-06-06 06:42:45 +09:00
|
|
|
StateProj::A(fut) => match fut.poll(cx)? {
|
2019-12-05 12:37:26 +06:00
|
|
|
Poll::Pending => Poll::Pending,
|
|
|
|
Poll::Ready(srv) => {
|
|
|
|
this.state.set(State::B(srv));
|
|
|
|
self.poll(cx)
|
2019-06-06 14:28:07 +06:00
|
|
|
}
|
2019-12-05 12:37:26 +06:00
|
|
|
},
|
2020-06-06 06:42:45 +09:00
|
|
|
StateProj::B(srv) => match srv.poll_ready(cx)? {
|
2019-12-05 12:37:26 +06:00
|
|
|
Poll::Ready(_) => {
|
2020-07-19 23:05:36 +02:00
|
|
|
{
|
|
|
|
let (_, f) = &mut *this.store.borrow_mut();
|
|
|
|
let fut = f(this.cfg.take().unwrap(), srv);
|
|
|
|
this.state.set(State::C(fut));
|
|
|
|
}
|
2019-12-05 12:37:26 +06:00
|
|
|
self.poll(cx)
|
2019-08-27 05:28:15 +06:00
|
|
|
}
|
2019-12-05 12:37:26 +06:00
|
|
|
Poll::Pending => Poll::Pending,
|
|
|
|
},
|
2020-06-06 06:42:45 +09:00
|
|
|
StateProj::C(fut) => fut.poll(cx),
|
2019-06-06 14:28:07 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|