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