1use crate::core::*;
2use std::marker::PhantomData;
3use std::sync::Arc;
4
5pub struct Layer<In, E, Out> {
12 pub build: Effect<In, E, Env>,
13 _phantom: PhantomData<Out>,
14}
15
16impl<In, E, Out> Clone for Layer<In, E, Out> {
17 fn clone(&self) -> Self {
18 Self {
19 build: self.build.clone(),
20 _phantom: PhantomData,
21 }
22 }
23}
24
25impl<In, E, Out> Layer<In, E, Out>
26where
27 In: Clone + Send + Sync + 'static,
28 E: Send + Sync + 'static,
29 Out: Send + Sync + 'static,
30{
31 pub fn new(build: Effect<In, E, Env>) -> Self {
33 Self {
34 build,
35 _phantom: PhantomData,
36 }
37 }
38
39 pub fn succeed<T>(val: T) -> Layer<In, E, T>
41 where
42 T: Send + Sync + Clone + 'static,
43 In: Send + Sync, E: Send + Sync,
45 {
46 Layer {
47 build: Effect::sync(move || {
48 let mut env = Env::new();
49 env.insert(val.clone());
50 env
51 }),
52 _phantom: PhantomData,
53 }
54 }
55
56 pub fn provide_to<A>(self, effect: Effect<Env, E, A>) -> Effect<In, E, A>
58 where
60 A: Send + Sync + 'static,
61 {
63 self.build.flat_map(move |env| {
66 let provided = effect.clone().provide(env);
67 Effect {
69 inner: Arc::new(move |_env: EnvRef<In>, ctx| {
70 let provided = provided.clone();
71 Box::pin(async move { (provided.inner)(EnvRef { value: () }, ctx).await })
72 }),
73 }
74 })
75 }
76}