tower_fallback/
service.rs1use 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 pub fn primary(&self) -> &S1 {
40 &self.svc1
41 }
42}
43
44impl<S1, S2, Request> Service<Request> for Fallback<S1, S2>
45where
46 S1: Service<Request>,
47 S2: Service<Request, Response = <S1 as Service<Request>>::Response>,
48 S1::Error: Into<BoxedError>,
49 S2::Error: Into<BoxedError>,
50 S2: Clone,
51 Request: Clone,
52{
53 type Response = <S1 as Service<Request>>::Response;
54 type Error = BoxedError;
55 type Future = ResponseFuture<S1, S2, Request>;
56
57 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
58 self.svc1.poll_ready(cx).map_err(Into::into)
59 }
60
61 fn call(&mut self, request: Request) -> Self::Future {
62 let request2 = request.clone();
63 ResponseFuture::new(self.svc1.call(request), request2, self.svc2.clone())
64 }
65}