1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

use super::Service;

/// 装箱的[`Future`]特征对象。
///
/// 此类型别名表示一个装箱的[`Future`],可以跨线程移动。
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

/// 装箱的[`Service`]特征对象。
///
/// [`BoxService`]将服务转换为特征对象并装箱,允许服务的[`Future`]是动态的。
///
/// 如果需要一个实现[`Clone`]的装箱服务,考虑使用[`BoxCloneService`]或[`ArcService`]。
pub struct BoxService<Req, Res, Err> {
    service: Box<dyn AnyService<Req, Response = Res, Error = Err>>,
}

impl<Req, Res, Err> BoxService<Req, Res, Err> {
    /// 将服务转换为[`Service`]特征对象并装箱。
    pub fn new<S>(service: S) -> Self
    where
        S: Service<Req, Response = Res, Error = Err> + 'static,
    {
        Self {
            service: Box::new(service),
        }
    }
}

impl<Req, Res, Err> Service<Req> for BoxService<Req, Res, Err> {
    type Response = Res;
    type Error = Err;

    fn call(&self, req: Req) -> impl Future<Output = Result<Self::Response, Self::Error>> + Send {
        self.service.call(req)
    }
}

impl<Req, Res, Err> std::fmt::Debug for BoxService<Req, Res, Err> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("BoxService").finish()
    }
}

/// 装箱的[`Service`]特征对象。
///
/// [`ArcService`]将服务转换为特征对象并装箱,允许服务的[`Future`]是动态的,
/// 并允许共享服务。
///
/// 这与[`BoxService`]类似,只是[`ArcService`]实现了[`Clone`]。
pub struct ArcService<Req, Res, Err> {
    service: Arc<dyn AnyService<Req, Response = Res, Error = Err>>,
}

impl<Req, Res, Err> ArcService<Req, Res, Err> {
    /// 将服务转换为[`Service`]特征对象并装箱。
    pub fn new<S>(service: S) -> Self
    where
        S: Service<Req, Response = Res, Error = Err> + 'static,
    {
        Self {
            service: Arc::new(service),
        }
    }
}

impl<Req, Res, Err> Service<Req> for ArcService<Req, Res, Err> {
    type Response = Res;
    type Error = Err;

    fn call(&self, req: Req) -> impl Future<Output = Result<Self::Response, Self::Error>> + Send {
        self.service.call(req)
    }
}

impl<Req, Res, Err> Clone for ArcService<Req, Res, Err> {
    fn clone(&self) -> Self {
        Self {
            service: Arc::clone(&self.service),
        }
    }
}

impl<Req, Res, Err> std::fmt::Debug for ArcService<Req, Res, Err> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("ArcService").finish()
    }
}

/// 装箱的[`Service`]特征对象。
///
/// [`BoxCloneService`]将服务转换为特征对象并装箱,允许服务的[`Future`]是动态的,
/// 并允许克隆服务。
///
/// 这与[`BoxService`]类似,只是[`BoxCloneService`]实现了[`Clone`]。
pub struct BoxCloneService<Req, Res, Err> {
    service: Box<dyn CloneService<Req, Response = Res, Error = Err>>,
}

impl<Req, Res, Err> BoxCloneService<Req, Res, Err> {
    /// 将服务转换为[`Service`]特征对象并装箱。
    pub fn new<S>(service: S) -> Self
    where
        S: Service<Req, Response = Res, Error = Err> + Clone + 'static,
    {
        Self {
            service: Box::new(service),
        }
    }
}

impl<Req, Res, Err> Service<Req> for BoxCloneService<Req, Res, Err> {
    type Response = Res;
    type Error = Err;

    fn call(&self, req: Req) -> impl Future<Output = Result<Self::Response, Self::Error>> + Send {
        self.service.call(req)
    }
}

impl<Req, Res, Err> Clone for BoxCloneService<Req, Res, Err> {
    fn clone(&self) -> Self {
        Self {
            service: self.service.clone_box(),
        }
    }
}

impl<Req, Res, Err> std::fmt::Debug for BoxCloneService<Req, Res, Err> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("BoxCloneService").finish()
    }
}

trait CloneService<Req>: AnyService<Req> {
    fn clone_box(
        &self,
    ) -> Box<dyn CloneService<Req, Response = Self::Response, Error = Self::Error>>;
}

impl<S, Req> CloneService<Req> for S
where
    S: Service<Req> + ?Sized + Clone + 'static,
{
    fn clone_box(
        &self,
    ) -> Box<dyn CloneService<Req, Response = Self::Response, Error = Self::Error>> {
        Box::new(self.clone())
    }
}

trait AnyService<Req>: Send + Sync {
    type Response;
    type Error;

    fn call<'a>(&'a self, req: Req) -> BoxFuture<'a, Result<Self::Response, Self::Error>>
    where
        Req: 'a;
}

impl<S, Req> AnyService<Req> for S
where
    S: Service<Req> + ?Sized,
{
    type Response = S::Response;
    type Error = S::Error;

    fn call<'a>(&'a self, req: Req) -> BoxFuture<'a, Result<Self::Response, Self::Error>>
    where
        Req: 'a,
    {
        Box::pin(Service::call(self, req))
    }
}