rearch_effects/
state_transformers.rs

1use std::marker::PhantomData;
2
3use crate::StateTransformer;
4
5/// A [`StateTransformer`] that provides a `&T` as a part of the side effect's api.
6pub struct Ref<T>(T);
7impl<T: Send + 'static> StateTransformer for Ref<T> {
8    type Input = T;
9    fn from_input(input: Self::Input) -> Self {
10        Self(input)
11    }
12
13    type Inner = T;
14    fn as_inner(&mut self) -> &mut Self::Inner {
15        &mut self.0
16    }
17
18    type Output<'a> = &'a T;
19    fn as_output(&mut self) -> Self::Output<'_> {
20        &self.0
21    }
22}
23
24/// A [`StateTransformer`] that provides a `&mut T` as a part of the side effect's api.
25pub struct MutRef<T>(T);
26impl<T: Send + 'static> StateTransformer for MutRef<T> {
27    type Input = T;
28    fn from_input(input: Self::Input) -> Self {
29        Self(input)
30    }
31
32    type Inner = T;
33    fn as_inner(&mut self) -> &mut Self::Inner {
34        &mut self.0
35    }
36
37    type Output<'a> = &'a mut T;
38    fn as_output(&mut self) -> Self::Output<'_> {
39        &mut self.0
40    }
41}
42
43/// A [`StateTransformer`] that provides a `T` where `T: Clone` as a part of the side effect's api.
44pub struct Cloned<T>(T);
45impl<T: Clone + Send + 'static> StateTransformer for Cloned<T> {
46    type Input = T;
47    fn from_input(input: Self::Input) -> Self {
48        Self(input)
49    }
50
51    type Inner = T;
52    fn as_inner(&mut self) -> &mut Self::Inner {
53        &mut self.0
54    }
55
56    type Output<'a> = T;
57    fn as_output(&mut self) -> Self::Output<'_> {
58        self.0.clone()
59    }
60}
61
62/// A [`StateTransformer`] that provides a `&T` as a part of the side effect's api,
63/// but takes a lazily-evaluated function as input to initialize the side effect state.
64pub struct LazyRef<T, F = fn() -> T>(T, PhantomData<F>);
65impl<T: Send + 'static, F: 'static + Send + FnOnce() -> T> StateTransformer for LazyRef<T, F> {
66    type Input = F;
67    fn from_input(input: Self::Input) -> Self {
68        Self(input(), PhantomData)
69    }
70
71    type Inner = T;
72    fn as_inner(&mut self) -> &mut Self::Inner {
73        &mut self.0
74    }
75
76    type Output<'a> = &'a T;
77    fn as_output(&mut self) -> Self::Output<'_> {
78        &self.0
79    }
80}
81
82/// A [`StateTransformer`] that provides a `&mut T` as a part of the side effect's api,
83/// but takes a lazily-evaluated function as input to initialize the side effect state.
84pub struct LazyMutRef<T, F = fn() -> T>(T, PhantomData<F>);
85impl<T: Send + 'static, F: 'static + Send + Fn() -> T> StateTransformer for LazyMutRef<T, F> {
86    type Input = F;
87    fn from_input(input: Self::Input) -> Self {
88        Self(input(), PhantomData)
89    }
90
91    type Inner = T;
92    fn as_inner(&mut self) -> &mut Self::Inner {
93        &mut self.0
94    }
95
96    type Output<'a> = &'a mut T;
97    fn as_output(&mut self) -> Self::Output<'_> {
98        &mut self.0
99    }
100}
101
102/// A [`StateTransformer`] that provides a `T` where `T: Clone` as a part of the side effect's api,
103/// but takes a lazily-evaluated function as input to initialize the side effect state.
104pub struct LazyCloned<T, F = fn() -> T>(T, PhantomData<F>);
105impl<T: Clone + Send + 'static, F: 'static + Send + Fn() -> T> StateTransformer
106    for LazyCloned<T, F>
107{
108    type Input = F;
109    fn from_input(input: Self::Input) -> Self {
110        Self(input(), PhantomData)
111    }
112
113    type Inner = T;
114    fn as_inner(&mut self) -> &mut Self::Inner {
115        &mut self.0
116    }
117
118    type Output<'a> = T;
119    fn as_output(&mut self) -> Self::Output<'_> {
120        self.0.clone()
121    }
122}