1use alloc::sync::Arc;
2
3use self::{optional::OptionalLayer, stack::Stack, then::Then};
4
5use super::{
6 AddData, BoxContextOperator, Context, ContextOperator, ContextOperatorExt, Insert, InsertData,
7 InsertWithData, Inspect, RefOperator,
8};
9
10pub mod cache;
13
14pub mod insert;
16
17pub mod inspect;
19
20pub mod data;
22
23pub mod stack;
25
26pub mod then;
28
29pub mod optional;
31
32pub trait Layer<In, P>
35where
36 P: ContextOperator<In>,
37{
38 type Operator: ContextOperator<In, Out = Self::Out>;
40
41 type Out;
43
44 fn layer(&self, operator: P) -> Self::Operator;
46}
47
48#[derive(Debug, Clone, Copy)]
50pub struct LayerFn<F>(F);
51
52impl<F, In, P, P2> Layer<In, P> for LayerFn<F>
53where
54 F: Fn(P) -> P2,
55 P: ContextOperator<In>,
56 P2: ContextOperator<In>,
57{
58 type Operator = P2;
59 type Out = P2::Out;
60
61 #[inline]
62 fn layer(&self, operator: P) -> Self::Operator {
63 (self.0)(operator)
64 }
65}
66
67pub fn layer_fn<F>(f: F) -> LayerFn<F> {
69 LayerFn(f)
70}
71
72pub trait LayerExt<In, P>: Layer<In, P>
74where
75 P: ContextOperator<In>,
76{
77 fn boxed(self) -> BoxLayer<P, In, Self::Out>
79 where
80 Self: Sized + Send + Sync + 'static,
81 Self::Operator: Send + 'static,
82 {
83 BoxLayer::new(self)
84 }
85
86 #[inline]
88 fn with<Outer>(self, outer: Outer) -> Stack<Self, Outer>
89 where
90 Outer: Layer<In, Self::Operator>,
91 Self: Sized,
92 {
93 Stack(self, outer)
94 }
95
96 fn insert_env<R, Out, F>(self, f: F) -> Stack<Self, Insert<F>>
101 where
102 F: Fn() -> R,
103 R: for<'a> RefOperator<'a, In, Output = Out>,
104 Out: Send + Sync + 'static,
105 Self: Sized,
106 {
107 self.with(Insert(f))
108 }
109
110 fn insert_env_if<R, Out, F>(self, enable: bool, f: F) -> Stack<Self, OptionalLayer<Insert<F>>>
114 where
115 F: Fn() -> R,
116 R: for<'a> RefOperator<'a, In, Output = Out>,
117 Out: Send + Sync + 'static,
118 Self: Sized,
119 {
120 self.with_if(if enable { Some(Insert(f)) } else { None })
121 }
122
123 fn insert_data<R, Out, F>(self, f: F) -> Stack<Self, InsertData<F>>
128 where
129 F: Fn() -> R,
130 R: for<'a> RefOperator<'a, In, Output = Option<Out>>,
131 Out: Send + Sync + 'static,
132 Self: Sized,
133 {
134 self.with(InsertData(f))
135 }
136
137 fn insert_data_if<R, Out, F>(
141 self,
142 enable: bool,
143 f: F,
144 ) -> Stack<Self, OptionalLayer<InsertData<F>>>
145 where
146 F: Fn() -> R,
147 R: for<'a> RefOperator<'a, In, Output = Option<Out>>,
148 Out: Send + Sync + 'static,
149 Self: Sized,
150 {
151 self.with_if(if enable { Some(InsertData(f)) } else { None })
152 }
153
154 fn insert<R, Env, Data, F>(self, f: F) -> Stack<Self, InsertWithData<F>>
159 where
160 F: Fn() -> R,
161 R: for<'a> RefOperator<'a, In, Output = (Env, Option<Data>)>,
162 Env: Send + Sync + 'static,
163 Data: Send + Sync + 'static,
164 Self: Sized,
165 {
166 self.with(InsertWithData(f))
167 }
168
169 fn insert_if<R, Env, Data, F>(
173 self,
174 enable: bool,
175 f: F,
176 ) -> Stack<Self, OptionalLayer<InsertWithData<F>>>
177 where
178 F: Fn() -> R,
179 R: for<'a> RefOperator<'a, In, Output = (Env, Option<Data>)>,
180 Env: Send + Sync + 'static,
181 Data: Send + Sync + 'static,
182 Self: Sized,
183 {
184 self.with_if(if enable {
185 Some(InsertWithData(f))
186 } else {
187 None
188 })
189 }
190
191 fn inspect<F>(self, f: F) -> Stack<Self, Inspect<F>>
193 where
194 F: Fn(&In, &Context) + Clone,
195 Self: Sized,
196 {
197 self.with(Inspect(f))
198 }
199
200 fn provide<D>(self, data: D) -> Stack<Self, AddData<D>>
202 where
203 D: Clone + Send + Sync + 'static,
204 Self: Sized,
205 {
206 self.with(AddData::with_data(data))
207 }
208
209 fn provide_if<D>(self, data: Option<D>) -> Stack<Self, OptionalLayer<AddData<D>>>
214 where
215 D: Clone + Send + Sync + 'static,
216 Self: Sized,
217 {
218 self.with_if(data.map(AddData::with_data))
219 }
220
221 fn provide_with<D>(
223 self,
224 provider: impl Fn() -> Option<D> + Send + Sync + 'static,
225 ) -> Stack<Self, AddData<D>>
226 where
227 D: Send + Sync + 'static,
228 Self: Sized,
229 {
230 self.with(AddData::new(provider))
231 }
232
233 fn provide_with_if<D>(
238 self,
239 enable: bool,
240 provider: impl Fn() -> Option<D> + Send + Sync + 'static,
241 ) -> Stack<Self, OptionalLayer<AddData<D>>>
242 where
243 D: Send + Sync + 'static,
244 Self: Sized,
245 {
246 self.with_if(if enable {
247 Some(AddData::new(provider))
248 } else {
249 None
250 })
251 }
252
253 #[allow(clippy::wrong_self_convention)]
256 #[deprecated(note = "use `data_from_context` instead")]
257 fn from_context<D>(self) -> Stack<Self, AddData<D>>
258 where
259 D: Send + Sync + 'static,
260 Self: Sized,
261 {
262 self.with(AddData::<D>::from_context())
263 }
264
265 fn data_from_context<D>(self) -> Stack<Self, AddData<D>>
267 where
268 D: Send + Sync + 'static,
269 Self: Sized,
270 {
271 self.with(AddData::<D>::from_context())
272 }
273
274 fn then_with<Out, F, Builder>(self, builder: Builder) -> Stack<Self, Then<Builder>>
276 where
277 Builder: Fn() -> F,
278 F: FnMut(Self::Out, &Context) -> Out + Clone,
279 Self: Sized,
280 {
281 self.with(Then(builder))
282 }
283
284 fn with_if<L>(self, layer: Option<L>) -> Stack<Self, OptionalLayer<L>>
286 where
287 L: Layer<In, Self::Operator>,
288 L::Operator: ContextOperator<In, Out = Self::Out>,
289 Self: Sized,
290 {
291 self.with(OptionalLayer(layer))
292 }
293}
294
295impl<In, P, L> LayerExt<In, P> for L
296where
297 P: ContextOperator<In>,
298 L: Layer<In, P>,
299{
300}
301
302pub struct BoxLayer<P, In, Out> {
304 inner: Arc<
305 dyn Layer<In, P, Operator = BoxContextOperator<In, Out>, Out = Out> + Send + Sync + 'static,
306 >,
307}
308
309impl<P, In, Out> BoxLayer<P, In, Out> {
310 pub fn new<L>(inner: L) -> Self
312 where
313 P: ContextOperator<In>,
314 L: Layer<In, P, Out = Out> + Send + Sync + 'static,
315 L::Operator: Send + 'static,
316 {
317 let layer = layer_fn(move |op: P| inner.layer(op).boxed());
318 Self {
319 inner: Arc::new(layer),
320 }
321 }
322}
323
324impl<P, In, Out> Layer<In, P> for BoxLayer<P, In, Out>
325where
326 P: ContextOperator<In>,
327{
328 type Operator = BoxContextOperator<In, Out>;
329
330 type Out = Out;
331
332 fn layer(&self, operator: P) -> Self::Operator {
333 self.inner.layer(operator)
334 }
335}