Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

combineN and mergeN introduced #57

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
283 changes: 282 additions & 1 deletion src/decider.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{DecideFunction, EvolveFunction, InitialStateFunction, Sum};
use crate::{
DecideFunction, Decider3, Decider4, Decider5, Decider6, EvolveFunction, InitialStateFunction,
Sum, Sum3, Sum4, Sum5, Sum6,
};

/// [Decider] represents the main decision-making algorithm.
/// It has three generic parameters `C`/`Command`, `S`/`State`, `E`/`Event` , representing the type of the values that Decider may contain or use.
Expand Down Expand Up @@ -309,6 +312,284 @@ impl<'a, C, S, E, Error> Decider<'a, C, S, E, Error> {
initial_state: new_initial_state,
}
}

/// Combines three deciders into one bigger decider
pub fn combine3<C2, S2, E2, C3, S3, E3>(
self,
decider2: Decider<'a, C2, S2, E2, Error>,
decider3: Decider<'a, C3, S3, E3, Error>,
) -> Decider3<'a, C, C2, C3, S, S2, S3, E, E2, E3, Error>
where
S: Clone,
S2: Clone,
S3: Clone,
E: Clone,
E2: Clone,
E3: Clone,
C: Clone,
C2: Clone,
C3: Clone,
{
// First combine self with decider2
let combined = self.combine(decider2);

// Then combine with decider3 and map the types
combined
.combine(decider3)
.map_state(
&|s: &(S, S2, S3)| ((s.0.clone(), s.1.clone()), s.2.clone()),
&|s: &((S, S2), S3)| (s.0 .0.clone(), s.0 .1.clone(), s.1.clone()),
)
.map_event(
&|e: &Sum3<E, E2, E3>| match e {
Sum3::First(ref e) => Sum::First(Sum::First(e.clone())),
Sum3::Second(ref e) => Sum::First(Sum::Second(e.clone())),
Sum3::Third(ref e) => Sum::Second(e.clone()),
},
&|e| match e {
Sum::First(Sum::First(e)) => Sum3::First(e.clone()),
Sum::First(Sum::Second(e)) => Sum3::Second(e.clone()),
Sum::Second(e) => Sum3::Third(e.clone()),
},
)
.map_command(&|c: &Sum3<C, C2, C3>| match c {
Sum3::First(c) => Sum::First(Sum::First(c.clone())),
Sum3::Second(c) => Sum::First(Sum::Second(c.clone())),
Sum3::Third(c) => Sum::Second(c.clone()),
})
}

#[allow(clippy::type_complexity)]
/// Combines four deciders into one bigger decider
pub fn combine4<C2, S2, E2, C3, S3, E3, C4, S4, E4>(
self,
decider2: Decider<'a, C2, S2, E2, Error>,
decider3: Decider<'a, C3, S3, E3, Error>,
decider4: Decider<'a, C4, S4, E4, Error>,
) -> Decider4<'a, C, C2, C3, C4, S, S2, S3, S4, E, E2, E3, E4, Error>
where
S: Clone,
S2: Clone,
S3: Clone,
S4: Clone,
E: Clone,
E2: Clone,
E3: Clone,
E4: Clone,
C: Clone,
C2: Clone,
C3: Clone,
C4: Clone,
{
let combined = self
.combine(decider2)
.combine(decider3)
.combine(decider4)
.map_state(
&|s: &(S, S2, S3, S4)| (((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
&|s: &(((S, S2), S3), S4)| {
(
s.0 .0 .0.clone(),
s.0 .0 .1.clone(),
s.0 .1.clone(),
s.1.clone(),
)
},
)
.map_event(
&|e: &Sum4<E, E2, E3, E4>| match e {
Sum4::First(e) => Sum::First(Sum::First(Sum::First(e.clone()))),
Sum4::Second(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
Sum4::Third(e) => Sum::First(Sum::Second(e.clone())),
Sum4::Fourth(e) => Sum::Second(e.clone()),
},
&|e| match e {
Sum::First(Sum::First(Sum::First(e))) => Sum4::First(e.clone()),
Sum::First(Sum::First(Sum::Second(e))) => Sum4::Second(e.clone()),
Sum::First(Sum::Second(e)) => Sum4::Third(e.clone()),
Sum::Second(e) => Sum4::Fourth(e.clone()),
},
)
.map_command(&|c: &Sum4<C, C2, C3, C4>| match c {
Sum4::First(c) => Sum::First(Sum::First(Sum::First(c.clone()))),
Sum4::Second(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
Sum4::Third(c) => Sum::First(Sum::Second(c.clone())),
Sum4::Fourth(c) => Sum::Second(c.clone()),
});
combined
}

#[allow(clippy::type_complexity)]
/// Combines five deciders into one bigger decider
pub fn combine5<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5>(
self,
decider2: Decider<'a, C2, S2, E2, Error>,
decider3: Decider<'a, C3, S3, E3, Error>,
decider4: Decider<'a, C4, S4, E4, Error>,
decider5: Decider<'a, C5, S5, E5, Error>,
) -> Decider5<'a, C, C2, C3, C4, C5, S, S2, S3, S4, S5, E, E2, E3, E4, E5, Error>
where
S: Clone,
S2: Clone,
S3: Clone,
S4: Clone,
S5: Clone,
E: Clone,
E2: Clone,
E3: Clone,
E4: Clone,
E5: Clone,
C: Clone,
C2: Clone,
C3: Clone,
C4: Clone,
C5: Clone,
{
let combined = self
.combine(decider2)
.combine(decider3)
.combine(decider4)
.combine(decider5)
.map_state(
&|s: &(S, S2, S3, S4, S5)| {
(
(((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
s.4.clone(),
)
},
&|s: &((((S, S2), S3), S4), S5)| {
(
s.0 .0 .0 .0.clone(),
s.0 .0 .0 .1.clone(),
s.0 .0 .1.clone(),
s.0 .1.clone(),
s.1.clone(),
)
},
)
.map_event(
&|e: &Sum5<E, E2, E3, E4, E5>| match e {
Sum5::First(e) => Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))),
Sum5::Second(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
Sum5::Third(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
Sum5::Fourth(e) => Sum::First(Sum::Second(e.clone())),
Sum5::Fifth(e) => Sum::Second(e.clone()),
},
&|e| match e {
Sum::First(Sum::First(Sum::First(Sum::First(e)))) => Sum5::First(e.clone()),
Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum5::Second(e.clone()),
Sum::First(Sum::First(Sum::Second(e))) => Sum5::Third(e.clone()),
Sum::First(Sum::Second(e)) => Sum5::Fourth(e.clone()),
Sum::Second(e) => Sum5::Fifth(e.clone()),
},
)
.map_command(&|c: &Sum5<C, C2, C3, C4, C5>| match c {
Sum5::First(c) => Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))),
Sum5::Second(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
Sum5::Third(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
Sum5::Fourth(c) => Sum::First(Sum::Second(c.clone())),
Sum5::Fifth(c) => Sum::Second(c.clone()),
});
combined
}

#[allow(clippy::type_complexity)]
/// Combines six deciders into one bigger decider
pub fn combine6<C2, S2, E2, C3, S3, E3, C4, S4, E4, C5, S5, E5, C6, S6, E6>(
self,
decider2: Decider<'a, C2, S2, E2, Error>,
decider3: Decider<'a, C3, S3, E3, Error>,
decider4: Decider<'a, C4, S4, E4, Error>,
decider5: Decider<'a, C5, S5, E5, Error>,
decider6: Decider<'a, C6, S6, E6, Error>,
) -> Decider6<'a, C, C2, C3, C4, C5, C6, S, S2, S3, S4, S5, S6, E, E2, E3, E4, E5, E6, Error>
where
S: Clone,
S2: Clone,
S3: Clone,
S4: Clone,
S5: Clone,
S6: Clone,
E: Clone,
E2: Clone,
E3: Clone,
E4: Clone,
E5: Clone,
E6: Clone,
C: Clone,
C2: Clone,
C3: Clone,
C4: Clone,
C5: Clone,
C6: Clone,
{
let combined = self
.combine(decider2)
.combine(decider3)
.combine(decider4)
.combine(decider5)
.combine(decider6)
.map_state(
&|s: &(S, S2, S3, S4, S5, S6)| {
(
(
(((s.0.clone(), s.1.clone()), s.2.clone()), s.3.clone()),
s.4.clone(),
),
s.5.clone(),
)
},
&|s: &(((((S, S2), S3), S4), S5), S6)| {
(
s.0 .0 .0 .0 .0.clone(),
s.0 .0 .0 .0 .1.clone(),
s.0 .0 .0 .1.clone(),
s.0 .0 .1.clone(),
s.0 .1.clone(),
s.1.clone(),
)
},
)
.map_event(
&|e: &Sum6<E, E2, E3, E4, E5, E6>| match e {
Sum6::First(e) => {
Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e.clone())))))
}
Sum6::Second(e) => {
Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))))
}
Sum6::Third(e) => Sum::First(Sum::First(Sum::First(Sum::Second(e.clone())))),
Sum6::Fourth(e) => Sum::First(Sum::First(Sum::Second(e.clone()))),
Sum6::Fifth(e) => Sum::First(Sum::Second(e.clone())),
Sum6::Sixth(e) => Sum::Second(e.clone()),
},
&|e| match e {
Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(e))))) => {
Sum6::First(e.clone())
}
Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(e))))) => {
Sum6::Second(e.clone())
}
Sum::First(Sum::First(Sum::First(Sum::Second(e)))) => Sum6::Third(e.clone()),
Sum::First(Sum::First(Sum::Second(e))) => Sum6::Fourth(e.clone()),
Sum::First(Sum::Second(e)) => Sum6::Fifth(e.clone()),
Sum::Second(e) => Sum6::Sixth(e.clone()),
},
)
.map_command(&|c: &Sum6<C, C2, C3, C4, C5, C6>| match c {
Sum6::First(c) => {
Sum::First(Sum::First(Sum::First(Sum::First(Sum::First(c.clone())))))
}
Sum6::Second(c) => {
Sum::First(Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))))
}
Sum6::Third(c) => Sum::First(Sum::First(Sum::First(Sum::Second(c.clone())))),
Sum6::Fourth(c) => Sum::First(Sum::First(Sum::Second(c.clone()))),
Sum6::Fifth(c) => Sum::First(Sum::Second(c.clone())),
Sum6::Sixth(c) => Sum::Second(c.clone()),
});
combined
}
}

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