1use crate::{
2 DecideFunction, Decider3, Decider4, Decider5, Decider6, EvolveFunction, InitialStateFunction,
3 Sum, Sum3, Sum4, Sum5, Sum6,
4};
5
6pub struct Decider<'a, C: 'a, S: 'a, E: 'a, Error: 'a = ()> {
155 pub decide: DecideFunction<'a, C, S, E, Error>,
157 pub evolve: EvolveFunction<'a, S, E>,
159 pub initial_state: InitialStateFunction<'a, S>,
161}
162
163impl<'a, C, S, E, Error> Decider<'a, C, S, E, Error> {
164 pub fn map_state<S2, F1, F2>(self, f1: &'a F1, f2: &'a F2) -> Decider<'a, C, S2, E, Error>
167 where
168 F1: Fn(&S2) -> S + Send + Sync,
169 F2: Fn(&S) -> S2 + Send + Sync,
170 {
171 let new_decide = Box::new(move |c: &C, s2: &S2| {
172 let s = f1(s2);
173 (self.decide)(c, &s)
174 });
175
176 let new_evolve = Box::new(move |s2: &S2, e: &E| {
177 let s = f1(s2);
178 f2(&(self.evolve)(&s, e))
179 });
180
181 let new_initial_state = Box::new(move || f2(&(self.initial_state)()));
182
183 Decider {
184 decide: new_decide,
185 evolve: new_evolve,
186 initial_state: new_initial_state,
187 }
188 }
189
190 pub fn map_event<E2, F1, F2>(self, f1: &'a F1, f2: &'a F2) -> Decider<'a, C, S, E2, Error>
193 where
194 F1: Fn(&E2) -> E + Send + Sync,
195 F2: Fn(&E) -> E2 + Send + Sync,
196 {
197 let new_decide = Box::new(move |c: &C, s: &S| {
198 (self.decide)(c, s).map(|result| result.into_iter().map(|e: E| f2(&e)).collect())
199 });
200
201 let new_evolve = Box::new(move |s: &S, e2: &E2| {
202 let e = f1(e2);
203 (self.evolve)(s, &e)
204 });
205
206 let new_initial_state = Box::new(move || (self.initial_state)());
207
208 Decider {
209 decide: new_decide,
210 evolve: new_evolve,
211 initial_state: new_initial_state,
212 }
213 }
214
215 pub fn map_command<C2, F>(self, f: &'a F) -> Decider<'a, C2, S, E, Error>
218 where
219 F: Fn(&C2) -> C + Send + Sync,
220 {
221 let new_decide = Box::new(move |c2: &C2, s: &S| {
222 let c = f(c2);
223 (self.decide)(&c, s)
224 });
225
226 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
227
228 let new_initial_state = Box::new(move || (self.initial_state)());
229
230 Decider {
231 decide: new_decide,
232 evolve: new_evolve,
233 initial_state: new_initial_state,
234 }
235 }
236
237 pub fn map_error<Error2, F>(self, f: &'a F) -> Decider<'a, C, S, E, Error2>
240 where
241 F: Fn(&Error) -> Error2 + Send + Sync,
242 {
243 let new_decide = Box::new(move |c: &C, s: &S| (self.decide)(c, s).map_err(|e| f(&e)));
244
245 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
246
247 let new_initial_state = Box::new(move || (self.initial_state)());
248
249 Decider {
250 decide: new_decide,
251 evolve: new_evolve,
252 initial_state: new_initial_state,
253 }
254 }
255
256 #[allow(clippy::type_complexity)]
259 pub fn combine<C2, S2, E2>(
260 self,
261 decider2: Decider<'a, C2, S2, E2, Error>,
262 ) -> Decider<'a, Sum<C, C2>, (S, S2), Sum<E, E2>, Error>
263 where
264 S: Clone,
265 S2: Clone,
266 {
267 let new_decide = Box::new(move |c: &Sum<C, C2>, s: &(S, S2)| match c {
268 Sum::First(c) => {
269 let s1 = &s.0;
270 let events = (self.decide)(c, s1);
271 events.map(|result| {
272 result
273 .into_iter()
274 .map(|e: E| Sum::First(e))
275 .collect::<Vec<Sum<E, E2>>>()
276 })
277 }
278 Sum::Second(c) => {
279 let s2 = &s.1;
280 let events = (decider2.decide)(c, s2);
281 events.map(|result| {
282 result
283 .into_iter()
284 .map(|e: E2| Sum::Second(e))
285 .collect::<Vec<Sum<E, E2>>>()
286 })
287 }
288 });
289
290 let new_evolve = Box::new(move |s: &(S, S2), e: &Sum<E, E2>| match e {
291 Sum::First(e) => {
292 let s1 = &s.0;
293 let new_state = (self.evolve)(s1, e);
294 (new_state, s.1.to_owned())
295 }
296 Sum::Second(e) => {
297 let s2 = &s.1;
298 let new_state = (decider2.evolve)(s2, e);
299 (s.0.to_owned(), new_state)
300 }
301 });
302
303 let new_initial_state = Box::new(move || {
304 let s1 = (self.initial_state)();
305 let s2 = (decider2.initial_state)();
306 (s1, s2)
307 });
308
309 Decider {
310 decide: new_decide,
311 evolve: new_evolve,
312 initial_state: new_initial_state,
313 }
314 }
315
316 pub fn combine3<C2, S2, E2, C3, S3, E3>(
318 self,
319 decider2: Decider<'a, C2, S2, E2, Error>,
320 decider3: Decider<'a, C3, S3, E3, Error>,
321 ) -> Decider3<'a, C, C2, C3, S, S2, S3, E, E2, E3, Error>
322 where
323 S: Clone,
324 S2: Clone,
325 S3: Clone,
326 E: Clone,
327 E2: Clone,
328 E3: Clone,
329 C: Clone,
330 C2: Clone,
331 C3: Clone,
332 {
333 let combined = self.combine(decider2);
335
336 combined
338 .combine(decider3)
339 .map_state(
340 &|s: &(S, S2, S3)| ((s.0.clone(), s.1.clone()), s.2.clone()),
341 &|s: &((S, S2), S3)| (s.0 .0.clone(), s.0 .1.clone(), s.1.clone()),
342 )
343 .map_event(
344 &|e: &Sum3<E, E2, E3>| match e {
345 Sum3::First(ref e) => Sum::First(Sum::First(e.clone())),
346 Sum3::Second(ref e) => Sum::First(Sum::Second(e.clone())),
347 Sum3::Third(ref e) => Sum::Second(e.clone()),
348 },
349 &|e| match e {
350 Sum::First(Sum::First(e)) => Sum3::First(e.clone()),
351 Sum::First(Sum::Second(e)) => Sum3::Second(e.clone()),
352 Sum::Second(e) => Sum3::Third(e.clone()),
353 },
354 )
355 .map_command(&|c: &Sum3<C, C2, C3>| match c {
356 Sum3::First(c) => Sum::First(Sum::First(c.clone())),
357 Sum3::Second(c) => Sum::First(Sum::Second(c.clone())),
358 Sum3::Third(c) => Sum::Second(c.clone()),
359 })
360 }
361
362 #[allow(clippy::type_complexity)]
363 pub fn combine4<C2, S2, E2, C3, S3, E3, C4, S4, E4>(
365 self,
366 decider2: Decider<'a, C2, S2, E2, Error>,
367 decider3: Decider<'a, C3, S3, E3, Error>,
368 decider4: Decider<'a, C4, S4, E4, Error>,
369 ) -> Decider4<'a, C, C2, C3, C4, S, S2, S3, S4, E, E2, E3, E4, Error>
370 where
371 S: Clone,
372 S2: Clone,
373 S3: Clone,
374 S4: Clone,
375 E: Clone,
376 E2: Clone,
377 E3: Clone,
378 E4: Clone,
379 C: Clone,
380 C2: Clone,
381 C3: Clone,
382 C4: Clone,
383 {
384 let combined = self
385 .combine(decider2)
386 .combine(decider3)
387 .combine(decider4)
388 .map_state(
389 &|s: &(S, S2, S3, S4)| (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
390 &|s: &(((S, S2), S3), S4)| {
391 (
392 s.0 .0 .0.clone(),
393 s.0 .0 .1.clone(),
394 s.0 .1.clone(),
395 s.1.clone(),
396 )
397 },
398 )
399 .map_event(
400 &|e: &Sum4<E, E2, E3, E4>| match e {
401 Sum4::First(e) => Sum::First(Sum::First(Sum::First(e.clone()))),
402 Sum4::Second(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
403 Sum4::Third(e) => Sum::First(Sum::Second(e.clone())),
404 Sum4::Fourth(e) => Sum::Second(e.clone()),
405 },
406 &|e| match e {
407 Sum::First(Sum::First(Sum::First(e))) => Sum4::First(e.clone()),
408 Sum::First(Sum::First(Sum::Second(e))) => Sum4::Second(e.clone()),
409 Sum::First(Sum::Second(e)) => Sum4::Third(e.clone()),
410 Sum::Second(e) => Sum4::Fourth(e.clone()),
411 },
412 )
413 .map_command(&|c: &Sum4<C, C2, C3, C4>| match c {
414 Sum4::First(c) => Sum::First(Sum::First(Sum::First(c.clone()))),
415 Sum4::Second(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
416 Sum4::Third(c) => Sum::First(Sum::Second(c.clone())),
417 Sum4::Fourth(c) => Sum::Second(c.clone()),
418 });
419 combined
420 }
421
422 #[allow(clippy::type_complexity)]
423 pub fn combine5<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5>(
425 self,
426 decider2: Decider<'a, C2, S2, E2, Error>,
427 decider3: Decider<'a, C3, S3, E3, Error>,
428 decider4: Decider<'a, C4, S4, E4, Error>,
429 decider5: Decider<'a, C5, S5, E5, Error>,
430 ) -> Decider5<'a, C, C2, C3, C4, C5, S, S2, S3, S4, S5, E, E2, E3, E4, E5, Error>
431 where
432 S: Clone,
433 S2: Clone,
434 S3: Clone,
435 S4: Clone,
436 S5: Clone,
437 E: Clone,
438 E2: Clone,
439 E3: Clone,
440 E4: Clone,
441 E5: Clone,
442 C: Clone,
443 C2: Clone,
444 C3: Clone,
445 C4: Clone,
446 C5: Clone,
447 {
448 let combined = self
449 .combine(decider2)
450 .combine(decider3)
451 .combine(decider4)
452 .combine(decider5)
453 .map_state(
454 &|s: &(S, S2, S3, S4, S5)| {
455 (
456 (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
457 s.4.clone(),
458 )
459 },
460 &|s: &((((S, S2), S3), S4), S5)| {
461 (
462 s.0 .0 .0 .0.clone(),
463 s.0 .0 .0 .1.clone(),
464 s.0 .0 .1.clone(),
465 s.0 .1.clone(),
466 s.1.clone(),
467 )
468 },
469 )
470 .map_event(
471 &|e: &Sum5<E, E2, E3, E4, E5>| match e {
472 Sum5::First(e) => Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))),
473 Sum5::Second(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
474 Sum5::Third(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
475 Sum5::Fourth(e) => Sum::First(Sum::Second(e.clone())),
476 Sum5::Fifth(e) => Sum::Second(e.clone()),
477 },
478 &|e| match e {
479 Sum::First(Sum::First(Sum::First(Sum::First(e)))) => Sum5::First(e.clone()),
480 Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum5::Second(e.clone()),
481 Sum::First(Sum::First(Sum::Second(e))) => Sum5::Third(e.clone()),
482 Sum::First(Sum::Second(e)) => Sum5::Fourth(e.clone()),
483 Sum::Second(e) => Sum5::Fifth(e.clone()),
484 },
485 )
486 .map_command(&|c: &Sum5<C, C2, C3, C4, C5>| match c {
487 Sum5::First(c) => Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))),
488 Sum5::Second(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
489 Sum5::Third(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
490 Sum5::Fourth(c) => Sum::First(Sum::Second(c.clone())),
491 Sum5::Fifth(c) => Sum::Second(c.clone()),
492 });
493 combined
494 }
495
496 #[allow(clippy::type_complexity)]
497 pub fn combine6<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5, C6, S6, E6>(
499 self,
500 decider2: Decider<'a, C2, S2, E2, Error>,
501 decider3: Decider<'a, C3, S3, E3, Error>,
502 decider4: Decider<'a, C4, S4, E4, Error>,
503 decider5: Decider<'a, C5, S5, E5, Error>,
504 decider6: Decider<'a, C6, S6, E6, Error>,
505 ) -> Decider6<'a, C, C2, C3, C4, C5, C6, S, S2, S3, S4, S5, S6, E, E2, E3, E4, E5, E6, Error>
506 where
507 S: Clone,
508 S2: Clone,
509 S3: Clone,
510 S4: Clone,
511 S5: Clone,
512 S6: Clone,
513 E: Clone,
514 E2: Clone,
515 E3: Clone,
516 E4: Clone,
517 E5: Clone,
518 E6: Clone,
519 C: Clone,
520 C2: Clone,
521 C3: Clone,
522 C4: Clone,
523 C5: Clone,
524 C6: Clone,
525 {
526 let combined = self
527 .combine(decider2)
528 .combine(decider3)
529 .combine(decider4)
530 .combine(decider5)
531 .combine(decider6)
532 .map_state(
533 &|s: &(S, S2, S3, S4, S5, S6)| {
534 (
535 (
536 (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
537 s.4.clone(),
538 ),
539 s.5.clone(),
540 )
541 },
542 &|s: &(((((S, S2), S3), S4), S5), S6)| {
543 (
544 s.0 .0 .0 .0 .0.clone(),
545 s.0 .0 .0 .0 .1.clone(),
546 s.0 .0 .0 .1.clone(),
547 s.0 .0 .1.clone(),
548 s.0 .1.clone(),
549 s.1.clone(),
550 )
551 },
552 )
553 .map_event(
554 &|e: &Sum6<E, E2, E3, E4, E5, E6>| match e {
555 Sum6::First(e) => {
556 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))))
557 }
558 Sum6::Second(e) => {
559 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))))
560 }
561 Sum6::Third(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
562 Sum6::Fourth(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
563 Sum6::Fifth(e) => Sum::First(Sum::Second(e.clone())),
564 Sum6::Sixth(e) => Sum::Second(e.clone()),
565 },
566 &|e| match e {
567 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e))))) => {
568 Sum6::First(e.clone())
569 }
570 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e))))) => {
571 Sum6::Second(e.clone())
572 }
573 Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum6::Third(e.clone()),
574 Sum::First(Sum::First(Sum::Second(e))) => Sum6::Fourth(e.clone()),
575 Sum::First(Sum::Second(e)) => Sum6::Fifth(e.clone()),
576 Sum::Second(e) => Sum6::Sixth(e.clone()),
577 },
578 )
579 .map_command(&|c: &Sum6<C, C2, C3, C4, C5, C6>| match c {
580 Sum6::First(c) => {
581 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))))
582 }
583 Sum6::Second(c) => {
584 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))))
585 }
586 Sum6::Third(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
587 Sum6::Fourth(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
588 Sum6::Fifth(c) => Sum::First(Sum::Second(c.clone())),
589 Sum6::Sixth(c) => Sum::Second(c.clone()),
590 });
591 combined
592 }
593}
594
595pub trait EventComputation<C, S, E, Error = ()> {
597 fn compute_new_events(&self, current_events: &[E], command: &C) -> Result<Vec<E>, Error>;
599}
600
601pub trait StateComputation<C, S, E, Error = ()> {
603 fn compute_new_state(&self, current_state: Option<S>, command: &C) -> Result<S, Error>;
605}
606
607impl<C, S, E, Error> EventComputation<C, S, E, Error> for Decider<'_, C, S, E, Error> {
608 fn compute_new_events(&self, current_events: &[E], command: &C) -> Result<Vec<E>, Error> {
610 let current_state: S = current_events
611 .iter()
612 .fold((self.initial_state)(), |state, event| {
613 (self.evolve)(&state, event)
614 });
615 (self.decide)(command, ¤t_state)
616 }
617}
618
619impl<C, S, E, Error> StateComputation<C, S, E, Error> for Decider<'_, C, S, E, Error> {
620 fn compute_new_state(&self, current_state: Option<S>, command: &C) -> Result<S, Error> {
622 let effective_current_state = current_state.unwrap_or_else(|| (self.initial_state)());
623 let events = (self.decide)(command, &effective_current_state);
624 events.map(|result| {
625 result
626 .into_iter()
627 .fold(effective_current_state, |state, event| {
628 (self.evolve)(&state, &event)
629 })
630 })
631 }
632}