flowly_service/
lib.rs

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}