tower_fallback/
service.rs
1use std::task::{Context, Poll};
2
3use tower::Service;
4
5use super::future::ResponseFuture;
6use crate::BoxedError;
7
8#[derive(Debug)]
10pub struct Fallback<S1, S2>
11where
12 S2: Clone,
13{
14 svc1: S1,
15 svc2: S2,
16}
17
18impl<S1: Clone, S2: Clone> Clone for Fallback<S1, S2> {
19 fn clone(&self) -> Self {
20 Self {
21 svc1: self.svc1.clone(),
22 svc2: self.svc2.clone(),
23 }
24 }
25}
26
27impl<S1, S2: Clone> Fallback<S1, S2> {
28 pub fn new(svc1: S1, svc2: S2) -> Self {
32 Self { svc1, svc2 }
33 }
34}
35
36impl<S1, S2, Request> Service<Request> for Fallback<S1, S2>
37where
38 S1: Service<Request>,
39 S2: Service<Request, Response = <S1 as Service<Request>>::Response>,
40 S1::Error: Into<BoxedError>,
41 S2::Error: Into<BoxedError>,
42 S2: Clone,
43 Request: Clone,
44{
45 type Response = <S1 as Service<Request>>::Response;
46 type Error = BoxedError;
47 type Future = ResponseFuture<S1, S2, Request>;
48
49 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
50 self.svc1.poll_ready(cx).map_err(Into::into)
51 }
52
53 fn call(&mut self, request: Request) -> Self::Future {
54 let request2 = request.clone();
55 ResponseFuture::new(self.svc1.call(request), request2, self.svc2.clone())
56 }
57}