1#[cfg(feature = "not-send-futures")]
2use std::rc::Rc;
3#[cfg(not(feature = "not-send-futures"))]
4use std::sync::Arc;
5
6use crate::{
7 DecideFunction, Decider3, Decider4, Decider5, Decider6, EvolveFunction, InitialStateFunction,
8 Sum, Sum3, Sum4, Sum5, Sum6,
9};
10
11pub struct Decider<'a, C: 'a, S: 'a, E: 'a, Error: 'a = ()> {
160 pub decide: DecideFunction<'a, C, S, E, Error>,
162 pub evolve: EvolveFunction<'a, S, E>,
164 pub initial_state: InitialStateFunction<'a, S>,
166}
167
168impl<'a, C, S, E, Error> Decider<'a, C, S, E, Error> {
169 #[cfg(not(feature = "not-send-futures"))]
172 pub fn map_state<S2, F1, F2>(self, f1: F1, f2: F2) -> Decider<'a, C, S2, E, Error>
173 where
174 F1: Fn(&S2) -> S + Send + Sync + 'a,
175 F2: Fn(&S) -> S2 + Send + Sync + 'a,
176 {
177 let f1 = Arc::new(f1);
178 let f2 = Arc::new(f2);
179
180 let new_decide = {
181 let f1 = Arc::clone(&f1);
182 Box::new(move |c: &C, s2: &S2| {
183 let s = f1(s2);
184 (self.decide)(c, &s)
185 })
186 };
187
188 let new_evolve = {
189 let f2 = Arc::clone(&f2);
190 Box::new(move |s2: &S2, e: &E| {
191 let s = f1(s2);
192 f2(&(self.evolve)(&s, e))
193 })
194 };
195
196 let new_initial_state = { Box::new(move || f2(&(self.initial_state)())) };
197
198 Decider {
199 decide: new_decide,
200 evolve: new_evolve,
201 initial_state: new_initial_state,
202 }
203 }
204
205 #[cfg(feature = "not-send-futures")]
208 pub fn map_state<S2, F1, F2>(self, f1: F1, f2: F2) -> Decider<'a, C, S2, E, Error>
209 where
210 F1: Fn(&S2) -> S + 'a,
211 F2: Fn(&S) -> S2 + 'a,
212 {
213 let f1 = Rc::new(f1);
214 let f2 = Rc::new(f2);
215
216 let new_decide = {
217 let f1 = Rc::clone(&f1);
218 Box::new(move |c: &C, s2: &S2| {
219 let s = f1(s2);
220 (self.decide)(c, &s)
221 })
222 };
223
224 let new_evolve = {
225 let f2 = Rc::clone(&f2);
226 Box::new(move |s2: &S2, e: &E| {
227 let s = f1(s2);
228 f2(&(self.evolve)(&s, e))
229 })
230 };
231
232 let new_initial_state = { Box::new(move || f2(&(self.initial_state)())) };
233
234 Decider {
235 decide: new_decide,
236 evolve: new_evolve,
237 initial_state: new_initial_state,
238 }
239 }
240 #[cfg(not(feature = "not-send-futures"))]
243 pub fn map_event<E2, F1, F2>(self, f1: F1, f2: F2) -> Decider<'a, C, S, E2, Error>
244 where
245 F1: Fn(&E2) -> E + Send + Sync + 'a,
246 F2: Fn(&E) -> E2 + Send + Sync + 'a,
247 {
248 let new_decide = Box::new(move |c: &C, s: &S| {
249 (self.decide)(c, s).map(|result| result.into_iter().map(|e: E| f2(&e)).collect())
250 });
251
252 let new_evolve = Box::new(move |s: &S, e2: &E2| {
253 let e = f1(e2);
254 (self.evolve)(s, &e)
255 });
256
257 let new_initial_state = Box::new(move || (self.initial_state)());
258
259 Decider {
260 decide: new_decide,
261 evolve: new_evolve,
262 initial_state: new_initial_state,
263 }
264 }
265
266 #[cfg(feature = "not-send-futures")]
269 pub fn map_event<E2, F1, F2>(self, f1: F1, f2: F2) -> Decider<'a, C, S, E2, Error>
270 where
271 F1: Fn(&E2) -> E + 'a,
272 F2: Fn(&E) -> E2 + 'a,
273 {
274 let new_decide = Box::new(move |c: &C, s: &S| {
275 (self.decide)(c, s).map(|result| result.into_iter().map(|e: E| f2(&e)).collect())
276 });
277
278 let new_evolve = Box::new(move |s: &S, e2: &E2| {
279 let e = f1(e2);
280 (self.evolve)(s, &e)
281 });
282
283 let new_initial_state = Box::new(move || (self.initial_state)());
284
285 Decider {
286 decide: new_decide,
287 evolve: new_evolve,
288 initial_state: new_initial_state,
289 }
290 }
291
292 #[cfg(not(feature = "not-send-futures"))]
295 pub fn map_command<C2, F>(self, f: F) -> Decider<'a, C2, S, E, Error>
296 where
297 F: Fn(&C2) -> C + Send + Sync + 'a,
298 {
299 let new_decide = Box::new(move |c2: &C2, s: &S| {
300 let c = f(c2);
301 (self.decide)(&c, s)
302 });
303
304 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
305
306 let new_initial_state = Box::new(move || (self.initial_state)());
307
308 Decider {
309 decide: new_decide,
310 evolve: new_evolve,
311 initial_state: new_initial_state,
312 }
313 }
314
315 #[cfg(feature = "not-send-futures")]
318 pub fn map_command<C2, F>(self, f: F) -> Decider<'a, C2, S, E, Error>
319 where
320 F: Fn(&C2) -> C + 'a,
321 {
322 let new_decide = Box::new(move |c2: &C2, s: &S| {
323 let c = f(c2);
324 (self.decide)(&c, s)
325 });
326
327 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
328
329 let new_initial_state = Box::new(move || (self.initial_state)());
330
331 Decider {
332 decide: new_decide,
333 evolve: new_evolve,
334 initial_state: new_initial_state,
335 }
336 }
337
338 #[cfg(not(feature = "not-send-futures"))]
341 pub fn map_error<Error2, F>(self, f: F) -> Decider<'a, C, S, E, Error2>
342 where
343 F: Fn(&Error) -> Error2 + Send + Sync + 'a,
344 {
345 let new_decide = Box::new(move |c: &C, s: &S| (self.decide)(c, s).map_err(|e| f(&e)));
346
347 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
348
349 let new_initial_state = Box::new(move || (self.initial_state)());
350
351 Decider {
352 decide: new_decide,
353 evolve: new_evolve,
354 initial_state: new_initial_state,
355 }
356 }
357
358 #[cfg(feature = "not-send-futures")]
361 pub fn map_error<Error2, F>(self, f: F) -> Decider<'a, C, S, E, Error2>
362 where
363 F: Fn(&Error) -> Error2 + 'a,
364 {
365 let new_decide = Box::new(move |c: &C, s: &S| (self.decide)(c, s).map_err(|e| f(&e)));
366
367 let new_evolve = Box::new(move |s: &S, e: &E| (self.evolve)(s, e));
368
369 let new_initial_state = Box::new(move || (self.initial_state)());
370
371 Decider {
372 decide: new_decide,
373 evolve: new_evolve,
374 initial_state: new_initial_state,
375 }
376 }
377
378 #[allow(clippy::type_complexity)]
381 pub fn combine<C2, S2, E2>(
382 self,
383 decider2: Decider<'a, C2, S2, E2, Error>,
384 ) -> Decider<'a, Sum<C, C2>, (S, S2), Sum<E, E2>, Error>
385 where
386 S: Clone,
387 S2: Clone,
388 {
389 let new_decide = Box::new(move |c: &Sum<C, C2>, s: &(S, S2)| match c {
390 Sum::First(c) => {
391 let s1 = &s.0;
392 let events = (self.decide)(c, s1);
393 events.map(|result| {
394 result
395 .into_iter()
396 .map(|e: E| Sum::First(e))
397 .collect::<Vec<Sum<E, E2>>>()
398 })
399 }
400 Sum::Second(c) => {
401 let s2 = &s.1;
402 let events = (decider2.decide)(c, s2);
403 events.map(|result| {
404 result
405 .into_iter()
406 .map(|e: E2| Sum::Second(e))
407 .collect::<Vec<Sum<E, E2>>>()
408 })
409 }
410 });
411
412 let new_evolve = Box::new(move |s: &(S, S2), e: &Sum<E, E2>| match e {
413 Sum::First(e) => {
414 let s1 = &s.0;
415 let new_state = (self.evolve)(s1, e);
416 (new_state, s.1.to_owned())
417 }
418 Sum::Second(e) => {
419 let s2 = &s.1;
420 let new_state = (decider2.evolve)(s2, e);
421 (s.0.to_owned(), new_state)
422 }
423 });
424
425 let new_initial_state = Box::new(move || {
426 let s1 = (self.initial_state)();
427 let s2 = (decider2.initial_state)();
428 (s1, s2)
429 });
430
431 Decider {
432 decide: new_decide,
433 evolve: new_evolve,
434 initial_state: new_initial_state,
435 }
436 }
437
438 pub fn combine3<C2, S2, E2, C3, S3, E3>(
440 self,
441 decider2: Decider<'a, C2, S2, E2, Error>,
442 decider3: Decider<'a, C3, S3, E3, Error>,
443 ) -> Decider3<'a, C, C2, C3, S, S2, S3, E, E2, E3, Error>
444 where
445 S: Clone,
446 S2: Clone,
447 S3: Clone,
448 E: Clone,
449 E2: Clone,
450 E3: Clone,
451 C: Clone,
452 C2: Clone,
453 C3: Clone,
454 {
455 let combined = self.combine(decider2);
457
458 combined
460 .combine(decider3)
461 .map_state(
462 |s: &(S, S2, S3)| ((s.0.clone(), s.1.clone()), s.2.clone()),
463 |s: &((S, S2), S3)| (s.0 .0.clone(), s.0 .1.clone(), s.1.clone()),
464 )
465 .map_event(
466 |e: &Sum3<E, E2, E3>| match e {
467 Sum3::First(ref e) => Sum::First(Sum::First(e.clone())),
468 Sum3::Second(ref e) => Sum::First(Sum::Second(e.clone())),
469 Sum3::Third(ref e) => Sum::Second(e.clone()),
470 },
471 |e: &Sum<Sum<E, E2>, E3>| match e {
472 Sum::First(Sum::First(e)) => Sum3::First(e.clone()),
473 Sum::First(Sum::Second(e)) => Sum3::Second(e.clone()),
474 Sum::Second(e) => Sum3::Third(e.clone()),
475 },
476 )
477 .map_command(|c: &Sum3<C, C2, C3>| match c {
478 Sum3::First(c) => Sum::First(Sum::First(c.clone())),
479 Sum3::Second(c) => Sum::First(Sum::Second(c.clone())),
480 Sum3::Third(c) => Sum::Second(c.clone()),
481 })
482 }
483
484 #[allow(clippy::type_complexity)]
485 pub fn combine4<C2, S2, E2, C3, S3, E3, C4, S4, E4>(
487 self,
488 decider2: Decider<'a, C2, S2, E2, Error>,
489 decider3: Decider<'a, C3, S3, E3, Error>,
490 decider4: Decider<'a, C4, S4, E4, Error>,
491 ) -> Decider4<'a, C, C2, C3, C4, S, S2, S3, S4, E, E2, E3, E4, Error>
492 where
493 S: Clone,
494 S2: Clone,
495 S3: Clone,
496 S4: Clone,
497 E: Clone,
498 E2: Clone,
499 E3: Clone,
500 E4: Clone,
501 C: Clone,
502 C2: Clone,
503 C3: Clone,
504 C4: Clone,
505 {
506 let combined = self
507 .combine(decider2)
508 .combine(decider3)
509 .combine(decider4)
510 .map_state(
511 |s: &(S, S2, S3, S4)| (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
512 |s: &(((S, S2), S3), S4)| {
513 (
514 s.0 .0 .0.clone(),
515 s.0 .0 .1.clone(),
516 s.0 .1.clone(),
517 s.1.clone(),
518 )
519 },
520 )
521 .map_event(
522 |e: &Sum4<E, E2, E3, E4>| match e {
523 Sum4::First(e) => Sum::First(Sum::First(Sum::First(e.clone()))),
524 Sum4::Second(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
525 Sum4::Third(e) => Sum::First(Sum::Second(e.clone())),
526 Sum4::Fourth(e) => Sum::Second(e.clone()),
527 },
528 |e: &Sum<Sum<Sum<E, E2>, E3>, E4>| match e {
529 Sum::First(Sum::First(Sum::First(e))) => Sum4::First(e.clone()),
530 Sum::First(Sum::First(Sum::Second(e))) => Sum4::Second(e.clone()),
531 Sum::First(Sum::Second(e)) => Sum4::Third(e.clone()),
532 Sum::Second(e) => Sum4::Fourth(e.clone()),
533 },
534 )
535 .map_command(|c: &Sum4<C, C2, C3, C4>| match c {
536 Sum4::First(c) => Sum::First(Sum::First(Sum::First(c.clone()))),
537 Sum4::Second(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
538 Sum4::Third(c) => Sum::First(Sum::Second(c.clone())),
539 Sum4::Fourth(c) => Sum::Second(c.clone()),
540 });
541 combined
542 }
543
544 #[allow(clippy::type_complexity)]
545 pub fn combine5<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5>(
547 self,
548 decider2: Decider<'a, C2, S2, E2, Error>,
549 decider3: Decider<'a, C3, S3, E3, Error>,
550 decider4: Decider<'a, C4, S4, E4, Error>,
551 decider5: Decider<'a, C5, S5, E5, Error>,
552 ) -> Decider5<'a, C, C2, C3, C4, C5, S, S2, S3, S4, S5, E, E2, E3, E4, E5, Error>
553 where
554 S: Clone,
555 S2: Clone,
556 S3: Clone,
557 S4: Clone,
558 S5: Clone,
559 E: Clone,
560 E2: Clone,
561 E3: Clone,
562 E4: Clone,
563 E5: Clone,
564 C: Clone,
565 C2: Clone,
566 C3: Clone,
567 C4: Clone,
568 C5: Clone,
569 {
570 let combined = self
571 .combine(decider2)
572 .combine(decider3)
573 .combine(decider4)
574 .combine(decider5)
575 .map_state(
576 |s: &(S, S2, S3, S4, S5)| {
577 (
578 (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
579 s.4.clone(),
580 )
581 },
582 |s: &((((S, S2), S3), S4), S5)| {
583 (
584 s.0 .0 .0 .0.clone(),
585 s.0 .0 .0 .1.clone(),
586 s.0 .0 .1.clone(),
587 s.0 .1.clone(),
588 s.1.clone(),
589 )
590 },
591 )
592 .map_event(
593 |e: &Sum5<E, E2, E3, E4, E5>| match e {
594 Sum5::First(e) => Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))),
595 Sum5::Second(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
596 Sum5::Third(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
597 Sum5::Fourth(e) => Sum::First(Sum::Second(e.clone())),
598 Sum5::Fifth(e) => Sum::Second(e.clone()),
599 },
600 |e: &Sum<Sum<Sum<Sum<E, E2>, E3>, E4>, E5>| match e {
601 Sum::First(Sum::First(Sum::First(Sum::First(e)))) => Sum5::First(e.clone()),
602 Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum5::Second(e.clone()),
603 Sum::First(Sum::First(Sum::Second(e))) => Sum5::Third(e.clone()),
604 Sum::First(Sum::Second(e)) => Sum5::Fourth(e.clone()),
605 Sum::Second(e) => Sum5::Fifth(e.clone()),
606 },
607 )
608 .map_command(|c: &Sum5<C, C2, C3, C4, C5>| match c {
609 Sum5::First(c) => Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))),
610 Sum5::Second(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
611 Sum5::Third(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
612 Sum5::Fourth(c) => Sum::First(Sum::Second(c.clone())),
613 Sum5::Fifth(c) => Sum::Second(c.clone()),
614 });
615 combined
616 }
617
618 #[allow(clippy::type_complexity)]
619 pub fn combine6<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5, C6, S6, E6>(
621 self,
622 decider2: Decider<'a, C2, S2, E2, Error>,
623 decider3: Decider<'a, C3, S3, E3, Error>,
624 decider4: Decider<'a, C4, S4, E4, Error>,
625 decider5: Decider<'a, C5, S5, E5, Error>,
626 decider6: Decider<'a, C6, S6, E6, Error>,
627 ) -> Decider6<'a, C, C2, C3, C4, C5, C6, S, S2, S3, S4, S5, S6, E, E2, E3, E4, E5, E6, Error>
628 where
629 S: Clone,
630 S2: Clone,
631 S3: Clone,
632 S4: Clone,
633 S5: Clone,
634 S6: Clone,
635 E: Clone,
636 E2: Clone,
637 E3: Clone,
638 E4: Clone,
639 E5: Clone,
640 E6: Clone,
641 C: Clone,
642 C2: Clone,
643 C3: Clone,
644 C4: Clone,
645 C5: Clone,
646 C6: Clone,
647 {
648 let combined = self
649 .combine(decider2)
650 .combine(decider3)
651 .combine(decider4)
652 .combine(decider5)
653 .combine(decider6)
654 .map_state(
655 |s: &(S, S2, S3, S4, S5, S6)| {
656 (
657 (
658 (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
659 s.4.clone(),
660 ),
661 s.5.clone(),
662 )
663 },
664 |s: &(((((S, S2), S3), S4), S5), S6)| {
665 (
666 s.0 .0 .0 .0 .0.clone(),
667 s.0 .0 .0 .0 .1.clone(),
668 s.0 .0 .0 .1.clone(),
669 s.0 .0 .1.clone(),
670 s.0 .1.clone(),
671 s.1.clone(),
672 )
673 },
674 )
675 .map_event(
676 |e: &Sum6<E, E2, E3, E4, E5, E6>| match e {
677 Sum6::First(e) => {
678 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))))
679 }
680 Sum6::Second(e) => {
681 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))))
682 }
683 Sum6::Third(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
684 Sum6::Fourth(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
685 Sum6::Fifth(e) => Sum::First(Sum::Second(e.clone())),
686 Sum6::Sixth(e) => Sum::Second(e.clone()),
687 },
688 |e: &Sum<Sum<Sum<Sum<Sum<E, E2>, E3>, E4>, E5>, E6>| match e {
689 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e))))) => {
690 Sum6::First(e.clone())
691 }
692 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e))))) => {
693 Sum6::Second(e.clone())
694 }
695 Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum6::Third(e.clone()),
696 Sum::First(Sum::First(Sum::Second(e))) => Sum6::Fourth(e.clone()),
697 Sum::First(Sum::Second(e)) => Sum6::Fifth(e.clone()),
698 Sum::Second(e) => Sum6::Sixth(e.clone()),
699 },
700 )
701 .map_command(|c: &Sum6<C, C2, C3, C4, C5, C6>| match c {
702 Sum6::First(c) => {
703 Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))))
704 }
705 Sum6::Second(c) => {
706 Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))))
707 }
708 Sum6::Third(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
709 Sum6::Fourth(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
710 Sum6::Fifth(c) => Sum::First(Sum::Second(c.clone())),
711 Sum6::Sixth(c) => Sum::Second(c.clone()),
712 });
713 combined
714 }
715}
716
717pub trait EventComputation<C, S, E, Error = ()> {
719 fn compute_new_events(&self, current_events: &[E], command: &C) -> Result<Vec<E>, Error>;
721}
722
723pub trait StateComputation<C, S, E, Error = ()> {
725 fn compute_new_state(&self, current_state: Option<S>, command: &C) -> Result<S, Error>;
727}
728
729impl<C, S, E, Error> EventComputation<C, S, E, Error> for Decider<'_, C, S, E, Error> {
730 fn compute_new_events(&self, current_events: &[E], command: &C) -> Result<Vec<E>, Error> {
732 let current_state: S = current_events
733 .iter()
734 .fold((self.initial_state)(), |state, event| {
735 (self.evolve)(&state, event)
736 });
737 (self.decide)(command, ¤t_state)
738 }
739}
740
741impl<C, S, E, Error> StateComputation<C, S, E, Error> for Decider<'_, C, S, E, Error> {
742 fn compute_new_state(&self, current_state: Option<S>, command: &C) -> Result<S, Error> {
744 let effective_current_state = current_state.unwrap_or_else(|| (self.initial_state)());
745 let events = (self.decide)(command, &effective_current_state);
746 events.map(|result| {
747 result
748 .into_iter()
749 .fold(effective_current_state, |state, event| {
750 (self.evolve)(&state, &event)
751 })
752 })
753 }
754}