Skip to content

Commit 172ed68

Browse files
authored
Merge pull request #57 from fraktalio/feature/combineN_and_mergeN
combineN and mergeN introduced
2 parents 915578a + 02d3194 commit 172ed68

File tree

4 files changed

+630
-4
lines changed

4 files changed

+630
-4
lines changed

src/decider.rs

Lines changed: 282 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{DecideFunction, EvolveFunction, InitialStateFunction, Sum};
1+
use crate::{
2+
DecideFunction, Decider3, Decider4, Decider5, Decider6, EvolveFunction, InitialStateFunction,
3+
Sum, Sum3, Sum4, Sum5, Sum6,
4+
};
25

36
/// [Decider] represents the main decision-making algorithm.
47
/// It has three generic parameters `C`/`Command`, `S`/`State`, `E`/`Event` , representing the type of the values that Decider may contain or use.
@@ -309,6 +312,284 @@ impl<'a, C, S, E, Error> Decider<'a, C, S, E, Error> {
309312
initial_state: new_initial_state,
310313
}
311314
}
315+
316+
/// Combines three deciders into one bigger decider
317+
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+
// First combine self with decider2
334+
let combined = self.combine(decider2);
335+
336+
// Then combine with decider3 and map the types
337+
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+
/// Combines four deciders into one bigger decider
364+
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+
/// Combines five deciders into one bigger decider
424+
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+
/// Combines six deciders into one bigger decider
498+
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+
}
312593
}
313594

314595
/// Formalizes the `Event Computation` algorithm / event sourced system for the `decider` to handle commands based on the current events, and produce new events.

0 commit comments

Comments
 (0)