xitca_service/pipeline/
enum.rs1use core::{
2 convert::Infallible,
3 error::Error,
4 fmt::{self, Debug, Display, Formatter},
5};
6
7use crate::{ready::ReadyService, service::Service};
8
9pub enum Pipeline<F, S> {
11 First(F),
12 Second(S),
13}
14
15impl<F, S> Clone for Pipeline<F, S>
16where
17 F: Clone,
18 S: Clone,
19{
20 fn clone(&self) -> Self {
21 match *self {
22 Self::First(ref p) => Self::First(p.clone()),
23 Self::Second(ref p) => Self::Second(p.clone()),
24 }
25 }
26}
27
28impl<F, S> Pipeline<F, S>
29where
30 F: From<S>,
31{
32 pub fn into_first(self) -> F {
33 match self {
34 Self::First(f) => f,
35 Self::Second(s) => F::from(s),
36 }
37 }
38}
39
40impl<F, S> Pipeline<F, S>
41where
42 S: From<F>,
43{
44 pub fn into_second(self) -> S {
45 match self {
46 Self::First(f) => S::from(f),
47 Self::Second(s) => s,
48 }
49 }
50}
51
52impl<F, S> Debug for Pipeline<F, S>
53where
54 F: Debug,
55 S: Debug,
56{
57 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
58 match *self {
59 Self::First(ref p) => Debug::fmt(p, f),
60 Self::Second(ref p) => Debug::fmt(p, f),
61 }
62 }
63}
64
65impl<F, S> Display for Pipeline<F, S>
66where
67 F: Display,
68 S: Display,
69{
70 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
71 match *self {
72 Self::First(ref p) => Display::fmt(p, f),
73 Self::Second(ref p) => Display::fmt(p, f),
74 }
75 }
76}
77
78impl<F, S> From<Infallible> for Pipeline<F, S> {
80 fn from(e: Infallible) -> Self {
81 match e {}
82 }
83}
84
85impl<F, S, Req> Service<Req> for Pipeline<F, S>
86where
87 F: Service<Req>,
88 S: Service<Req, Response = F::Response, Error = F::Error>,
89{
90 type Response = F::Response;
91 type Error = F::Error;
92
93 async fn call(&self, req: Req) -> Result<Self::Response, Self::Error> {
94 match *self {
95 Self::First(ref f) => f.call(req).await,
96 Self::Second(ref s) => s.call(req).await,
97 }
98 }
99}
100
101impl<F, S> ReadyService for Pipeline<F, S>
102where
103 F: ReadyService,
104 S: ReadyService,
105{
106 type Ready = Pipeline<F::Ready, S::Ready>;
107
108 #[inline]
109 async fn ready(&self) -> Self::Ready {
110 match *self {
111 Self::First(ref f) => Pipeline::First(f.ready().await),
112 Self::Second(ref s) => Pipeline::Second(s.ready().await),
113 }
114 }
115}
116
117impl<F, S> Error for Pipeline<F, S>
118where
119 F: Error,
120 S: Error,
121{
122 fn source(&self) -> Option<&(dyn Error + 'static)> {
123 match *self {
124 Self::First(ref f) => Error::source(f),
125 Self::Second(ref f) => Error::source(f),
126 }
127 }
128}