1mod abort;
2mod and_then;
3mod chain;
4mod finally;
5mod flatten;
6mod map;
7mod maybe;
8mod optional;
9mod pass;
10mod spawn;
11mod stub;
12
13use std::marker::PhantomData;
14
15use futures::{Stream, TryFuture};
16
17pub trait Service<In> {
18 type Out;
19
20 fn handle(self, input: impl Stream<Item = In> + Send) -> impl Stream<Item = Self::Out> + Send;
21}
22
23pub trait ServiceExt<I>: Service<I> {
24 #[inline]
25 fn flow<U>(self, service: U) -> impl Service<I, Out = U::Out>
26 where
27 Self: Sized,
28 U: Service<Self::Out>,
29 {
30 chain::Chain {
31 service1: self,
32 service2: service,
33 }
34 }
35
36 #[inline]
37 fn maybe_flow<U>(self, service: Option<U>) -> impl Service<I, Out = Self::Out>
38 where
39 Self: Sized,
40 U: Service<Self::Out, Out = Self::Out>,
41 {
42 self.flow(maybe::Maybe { service })
43 }
44
45 #[inline]
46 fn spawn(self, buffer: usize) -> spawn::Spawn<Self>
47 where
48 Self: Sized,
49 {
50 spawn::Spawn {
51 service: self,
52 buffer,
53 }
54 }
55
56 #[inline]
57 fn map<U, F>(self, map: F) -> impl Service<I, Out = U>
58 where
59 Self: Sized,
60 F: Send + FnMut(Self::Out) -> U,
61 {
62 self.flow(map::MapEachFn {
63 map,
64 m: PhantomData,
65 })
66 }
67
68 #[inline]
69 fn abort_token(self, token: impl futures::Future + Send) -> impl Service<I, Out = Self::Out>
70 where
71 Self: Sized,
72 {
73 abort::AbortFn {
74 token,
75 service: self,
76 }
77 }
78}
79
80impl<I, T: Service<I>> ServiceExt<I> for T {}
81
82pub trait TryService<I, E>: Service<Result<I, E>, Out = Result<Self::Ok, Self::Error>> {
83 type Ok;
84 type Error;
85
86 fn try_handle(
87 self,
88 input: impl Stream<Item = Result<I, E>> + Send,
89 ) -> impl Stream<Item = Result<Self::Ok, Self::Error>> + Send;
90}
91
92impl<S, I, IE, O, OE> TryService<I, IE> for S
93where
94 S: Service<Result<I, IE>, Out = Result<O, OE>>,
95{
96 type Ok = O;
97 type Error = OE;
98
99 fn try_handle(
100 self,
101 input: impl Stream<Item = Result<I, IE>> + Send,
102 ) -> impl Stream<Item = Result<Self::Ok, Self::Error>> + Send {
103 self.handle(input)
104 }
105}
106
107pub trait TryServiceExt<I, E>: TryService<I, E> {
108 #[inline]
109 fn map_ok<C: FnMut(Self::Ok) -> U + Send, U>(
110 self,
111 map: C,
112 ) -> impl Service<Result<I, E>, Out = Result<U, Self::Error>>
113 where
114 Self: Sized,
115 {
116 self.flow(map::MapOk {
117 map,
118 m: PhantomData,
119 })
120 }
121
122 #[inline]
123 fn and_then<C: FnMut(Self::Ok) -> F + Send, F>(
124 self,
125 f: C,
126 ) -> impl Service<Result<I, E>, Out = Result<F::Ok, Self::Error>>
127 where
128 Self: Sized,
129 F: TryFuture<Error = Self::Error> + Send,
130 {
131 self.flow(and_then::AndThenFn { f })
132 }
133
134 #[inline]
135 fn finally<C, F>(self, f: C) -> impl Service<Result<I, E>, Out = Self::Out>
136 where
137 Self: Sized,
138 Self::Ok: Send,
139 Self::Error: Send,
140 F: Future<Output = Result<(), Self::Error>> + Send,
141 C: Send + FnMut() -> F,
142 {
143 self.flow(finally::Finally { f })
144 }
145
146 #[inline]
147 fn except<C, F>(self, f: C) -> impl Service<Result<I, E>, Out = Self::Out>
148 where
149 Self: Sized,
150 Self::Ok: Send,
151 Self::Error: Send,
152 F: Future<Output = Result<(), Self::Error>> + Send,
153 C: Send + FnMut(Self::Error) -> F,
154 {
155 self.flow(finally::Except { f })
156 }
157
158 #[inline]
159 fn stub(self) -> impl Service<Result<I, E>, Out = Result<(), Self::Error>>
160 where
161 Self: Sized,
162 Self::Ok: Send,
163 Self::Error: Send,
164 {
165 self.flow(stub::Stub)
166 }
167
168 fn try_flatten_map<C, O, F, S>(
169 self,
170 f: C,
171 ) -> impl Service<Result<I, E>, Out = Result<O, Self::Error>>
172 where
173 Self: Sized,
174 Self::Ok: Send,
175 Self::Error: Send,
176 O: Send,
177 E: Send,
178 I: Send,
179 F: Future<Output = Result<S, Self::Error>> + Send,
180 C: FnMut(Self::Ok) -> F + Send,
181 S: Stream<Item = Result<O, Self::Error>> + Send,
182 {
183 self.flow(flatten::TryFlattenMap { f })
184 }
185}
186
187pub fn flow() -> pass::Pass {
188 pass::Pass
189}