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
use futures::{future::BoxFuture, FutureExt};
use std::{
marker::PhantomData,
task::{Context, Poll},
time::Duration,
};
use tower::{limit::RateLimit, Service, ServiceBuilder, ServiceExt};
use crate::ExchangeError;
pub mod layer;
pub mod traits;
pub use layer::ExcLayer;
pub use traits::{Adaptor, ExcService, IntoExc, Request};
#[derive(Debug)]
pub struct Exc<C, Req> {
channel: C,
_req: PhantomData<fn() -> Req>,
}
impl<C, Req> Clone for Exc<C, Req>
where
C: Clone,
{
fn clone(&self) -> Self {
Self::new(self.channel.clone())
}
}
impl<C, Req> Exc<C, Req> {
pub fn new(channel: C) -> Self {
Self {
channel,
_req: PhantomData,
}
}
pub async fn request(&mut self, request: Req) -> Result<C::Response, C::Error>
where
C: Service<Req>,
{
ServiceExt::<Req>::oneshot(&mut self.channel, request).await
}
pub fn into_rate_limited(self, num: u64, per: Duration) -> RateLimit<Self> {
ServiceBuilder::default().rate_limit(num, per).service(self)
}
}
impl<C, Req, R> Service<R> for Exc<C, Req>
where
R: Request,
R::Response: Send + 'static,
Req: Adaptor<R>,
C: Service<Req, Response = Req::Response>,
C::Error: Into<ExchangeError>,
C::Future: Send + 'static,
{
type Response = R::Response;
type Error = ExchangeError;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn poll_ready(
&mut self,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>> {
self.channel.poll_ready(cx).map_err(|err| err.into())
}
fn call(&mut self, req: R) -> Self::Future {
let request = Req::from_request(req);
match request {
Ok(req) => {
let res = self.channel.call(req);
async move {
let resp = res.await.map_err(|err| err.into())?;
let resp = Req::into_response(resp)?;
Ok(resp)
}
.left_future()
}
Err(err) => futures::future::ready(Err(err)).right_future(),
}
.boxed()
}
}
#[derive(Debug)]
pub struct ExcMut<'a, S: ?Sized> {
pub(crate) inner: &'a mut S,
}
impl<'a, S, R> Service<R> for ExcMut<'a, S>
where
R: Request,
S: ExcService<R>,
{
type Response = R::Response;
type Error = ExchangeError;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx).map_err(|err| err.into())
}
fn call(&mut self, req: R) -> Self::Future {
self.inner.call(req)
}
}