apache_dubbo/utils/
boxed_clone.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18use futures_util::future::BoxFuture;
19use std::{
20    fmt,
21    task::{Context, Poll},
22};
23use tower::ServiceExt;
24use tower_layer::{layer_fn, LayerFn};
25use tower_service::Service;
26
27pub struct BoxCloneService<T, U, E>(
28    Box<
29        dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
30            + Send
31            + Sync,
32    >,
33);
34
35impl<T, U, E> BoxCloneService<T, U, E> {
36    /// Create a new `BoxCloneService`.
37    pub fn new<S>(inner: S) -> Self
38    where
39        S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
40        S::Future: Send + 'static,
41    {
42        let inner = inner.map_future(|f| Box::pin(f) as _);
43        BoxCloneService(Box::new(inner))
44    }
45
46    /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxCloneService`]
47    /// middleware.
48    ///
49    /// [`Layer`]: crate::Layer
50    pub fn layer<S>() -> LayerFn<fn(S) -> Self>
51    where
52        S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
53        S::Future: Send + 'static,
54    {
55        layer_fn(Self::new)
56    }
57}
58
59impl<T, U, E> Service<T> for BoxCloneService<T, U, E> {
60    type Response = U;
61    type Error = E;
62    type Future = BoxFuture<'static, Result<U, E>>;
63
64    #[inline]
65    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
66        self.0.poll_ready(cx)
67    }
68
69    #[inline]
70    fn call(&mut self, request: T) -> Self::Future {
71        self.0.call(request)
72    }
73}
74
75impl<T, U, E> Clone for BoxCloneService<T, U, E> {
76    fn clone(&self) -> Self {
77        Self(self.0.clone_box())
78    }
79}
80
81trait CloneService<R>: Service<R> {
82    fn clone_box(
83        &self,
84    ) -> Box<
85        dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
86            + Send
87            + Sync,
88    >;
89}
90
91impl<R, T> CloneService<R> for T
92where
93    T: Service<R> + Send + Sync + Clone + 'static,
94{
95    fn clone_box(
96        &self,
97    ) -> Box<
98        dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future>
99            + Send
100            + Sync,
101    > {
102        Box::new(self.clone())
103    }
104}
105
106impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
107    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
108        fmt.debug_struct("BoxCloneService").finish()
109    }
110}