1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::optics::*,
11 classes::{
12 CloneableFn,
13 profunctor::{
14 Choice,
15 Profunctor,
16 Strong,
17 },
18 },
19 impl_kind,
20 kinds::*,
21 },
22 fp_macros::*,
23 };
24
25 #[document_type_parameters(
27 "The lifetime of the functions.",
28 "The cloneable function brand.",
29 "The type of the value produced by the preview function.",
30 "The type of the value consumed by the setter.",
31 "The source type of the structure.",
32 "The target type of the structure."
33 )]
34 pub struct Stall<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, S: 'a, T: 'a> {
35 pub get: <FunctionBrand as CloneableFn>::Of<'a, S, Result<A, T>>,
37 pub set: <FunctionBrand as CloneableFn>::Of<'a, (S, B), T>,
39 }
40
41 #[document_type_parameters(
42 "The lifetime of the functions.",
43 "The cloneable function brand.",
44 "The type of the value produced by the preview function.",
45 "The type of the value consumed by the setter.",
46 "The source type of the structure.",
47 "The target type of the structure."
48 )]
49 impl<'a, FunctionBrand: CloneableFn, A: 'a, B: 'a, S: 'a, T: 'a>
50 Stall<'a, FunctionBrand, A, B, S, T>
51 {
52 #[document_signature]
54 #[document_parameters("The preview function.", "The setter function.")]
56 #[document_returns("A new instance of the type.")]
58 #[document_examples]
60 pub fn new(
76 get: <FunctionBrand as CloneableFn>::Of<'a, S, Result<A, T>>,
77 set: <FunctionBrand as CloneableFn>::Of<'a, (S, B), T>,
78 ) -> Self {
79 Stall {
80 get,
81 set,
82 }
83 }
84 }
85
86 impl_kind! {
87 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> for StallBrand<FunctionBrand, A, B> {
88 #[document_default]
89 type Of<'a, S: 'a, T: 'a>: 'a = Stall<'a, FunctionBrand, A, B, S, T>;
90 }
91 }
92
93 #[document_type_parameters(
94 "The cloneable function brand.",
95 "The type of the value produced by the preview function.",
96 "The type of the value consumed by the setter."
97 )]
98 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Profunctor
99 for StallBrand<FunctionBrand, A, B>
100 {
101 #[document_signature]
103 #[document_type_parameters(
104 "The lifetime of the functions.",
105 "The source type of the new structure.",
106 "The target type of the new structure.",
107 "The source type of the original structure.",
108 "The target type of the original structure."
109 )]
110 #[document_parameters(
112 "The function to apply to the input.",
113 "The function to apply to the output.",
114 "The stall instance to transform."
115 )]
116 #[document_returns("A transformed `Stall` instance.")]
117 #[document_examples]
119 fn dimap<'a, S: 'a, T: 'a, U: 'a, V: 'a>(
147 st: impl Fn(S) -> T + 'a,
148 uv: impl Fn(U) -> V + 'a,
149 puv: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, T, U>),
150 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, V>) {
151 let get = puv.get;
152 let set = puv.set;
153 let st = <FunctionBrand as CloneableFn>::new(st);
154 let uv = <FunctionBrand as CloneableFn>::new(uv);
155 let st_2 = st.clone();
156 let uv_2 = uv.clone();
157 Stall::new(
158 <FunctionBrand as CloneableFn>::new(move |s: S| {
159 (*get)((*st)(s)).map_err(|u| (*uv)(u))
160 }),
161 <FunctionBrand as CloneableFn>::new(move |(s, b): (S, B)| {
162 (*uv_2)((*set)(((*st_2)(s), b)))
163 }),
164 )
165 }
166 }
167
168 #[document_type_parameters(
169 "The cloneable function brand.",
170 "The type of the value produced by the preview function.",
171 "The type of the value consumed by the setter."
172 )]
173 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Strong
174 for StallBrand<FunctionBrand, A, B>
175 {
176 #[document_signature]
178 #[document_type_parameters(
179 "The lifetime of the functions.",
180 "The source type of the structure.",
181 "The target type of the structure.",
182 "The type of the other component."
183 )]
184 #[document_parameters("The stall instance to transform.")]
186 #[document_returns("A transformed `Stall` instance that operates on tuples.")]
187 #[document_examples]
189 fn first<'a, S: 'a, T: 'a, C: 'a>(
212 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
213 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, (S, C), (T, C)>) {
214 let get = pab.get;
215 let set = pab.set;
216 Stall::new(
217 <FunctionBrand as CloneableFn>::new(move |(s, c): (S, C)| {
218 (*get)(s).map_err(|t| (t, c))
219 }),
220 <FunctionBrand as CloneableFn>::new(move |((s, c), b): ((S, C), B)| {
221 ((*set)((s, b)), c)
222 }),
223 )
224 }
225 }
226
227 #[document_type_parameters(
228 "The cloneable function brand.",
229 "The type of the value produced by the preview function.",
230 "The type of the value consumed by the setter."
231 )]
232 impl<FunctionBrand: CloneableFn + 'static, A: 'static, B: 'static> Choice
233 for StallBrand<FunctionBrand, A, B>
234 {
235 #[document_signature]
237 #[document_type_parameters(
238 "The lifetime of the functions.",
239 "The source type of the structure.",
240 "The target type of the structure.",
241 "The type of the other component."
242 )]
243 #[document_parameters("The stall instance to transform.")]
245 #[document_returns(
246 "A transformed `Stall` instance that operates on the left component of a `Result`."
247 )]
248 #[document_examples]
250 fn left<'a, S: 'a, T: 'a, C: 'a>(
273 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
274 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, Result<C, S>, Result<C, T>>)
275 {
276 let get = pab.get;
277 let set = pab.set;
278 Stall::new(
279 <FunctionBrand as CloneableFn>::new(move |r: Result<C, S>| match r {
280 Err(s) => (*get)(s).map_err(Err),
281 Ok(c) => Err(Ok(c)),
282 }),
283 <FunctionBrand as CloneableFn>::new(move |(r, b): (Result<C, S>, B)| match r {
284 Err(s) => Err((*set)((s, b))),
285 Ok(c) => Ok(c),
286 }),
287 )
288 }
289
290 #[document_signature]
292 #[document_type_parameters(
293 "The lifetime of the functions.",
294 "The source type of the structure.",
295 "The target type of the structure.",
296 "The type of the other component."
297 )]
298 #[document_parameters("The stall instance to transform.")]
300 #[document_returns(
301 "A transformed `Stall` instance that operates on the right component of a `Result`."
302 )]
303 #[document_examples]
305 fn right<'a, S: 'a, T: 'a, C: 'a>(
328 pab: Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, S, T>)
329 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a, U: 'a>: 'a; )>::Of<'a, Result<S, C>, Result<T, C>>)
330 {
331 let get = pab.get;
332 let set = pab.set;
333 Stall::new(
334 <FunctionBrand as CloneableFn>::new(move |r: Result<S, C>| match r {
335 Ok(s) => (*get)(s).map_err(Ok),
336 Err(c) => Err(Err(c)),
337 }),
338 <FunctionBrand as CloneableFn>::new(move |(r, b): (Result<S, C>, B)| match r {
339 Ok(s) => Ok((*set)((s, b))),
340 Err(c) => Err(c),
341 }),
342 )
343 }
344 }
345}
346pub use inner::*;