eternal/http/
cloneable.rs

1use std::cell::UnsafeCell;
2use std::rc::Rc;
3use std::task::{Context, Poll};
4
5use kayrx::service::Service;
6
7#[doc(hidden)]
8/// Service that allows to turn non-clone service to a service with `Clone` impl
9pub(crate) struct CloneableService<T>(Rc<UnsafeCell<T>>);
10
11impl<T> CloneableService<T> {
12    pub(crate) fn new(service: T) -> Self
13    where
14        T: Service,
15    {
16        Self(Rc::new(UnsafeCell::new(service)))
17    }
18}
19
20impl<T> Clone for CloneableService<T> {
21    fn clone(&self) -> Self {
22        Self(self.0.clone())
23    }
24}
25
26impl<T> Service for CloneableService<T>
27where
28    T: Service,
29{
30    type Request = T::Request;
31    type Response = T::Response;
32    type Error = T::Error;
33    type Future = T::Future;
34
35    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
36        unsafe { &mut *self.0.as_ref().get() }.poll_ready(cx)
37    }
38
39    fn call(&mut self, req: T::Request) -> Self::Future {
40        unsafe { &mut *self.0.as_ref().get() }.call(req)
41    }
42}