Skip to content

Commit

Permalink
simplifying the combine function
Browse files Browse the repository at this point in the history
We are limiting to combine only two components (decider, view, saga) into one big component ((decider, view, saga)). If you want to combine three or more, please create your own `combine function`
  • Loading branch information
idugalic committed Dec 14, 2023
1 parent dd8eb78 commit 6176d4a
Show file tree
Hide file tree
Showing 7 changed files with 14 additions and 153 deletions.
70 changes: 2 additions & 68 deletions src/decider_combined.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::decider::Decider;
use crate::{Sum, Sum3};
use crate::Sum;

/// Combine two deciders into one bigger decider
/// Creates a new instance of a Decider by combining two deciders of type `C1`, `S1`, `E1` and `C2`, `S2`, `E2` into a new decider of type `Sum<C, C2>`, `(S, S2)`, `Sum<E, E2>`
/// We encourage you to create your own combine functions to combine more deciders (three, four, five, ...) into one.
pub fn combine<'a, C1, S1: Clone, E1, C2, S2: Clone, E2>(
decider1: Decider<'a, C1, S1, E1>,
decider2: Decider<'a, C2, S2, E2>,
Expand Down Expand Up @@ -51,70 +52,3 @@ pub fn combine<'a, C1, S1: Clone, E1, C2, S2: Clone, E2>(
initial_state: new_initial_state,
}
}

/// Combine three deciders into one bigger decider
/// Creates a new instance of a Decider by combining two deciders of type `C1`, `S1`, `E1` , `C2`, `S2`, `E2`, and `C3`, `S3`, `E3` into a new decider of type `Sum3<C, C2, C3>`, `(S, S2, S3)`, `Sum3<E, E2, E3>`
#[allow(clippy::type_complexity)]
pub fn combine3<'a, C1, S1: Clone, E1, C2, S2: Clone, E2, C3, S3: Clone, E3>(
decider1: Decider<'a, C1, S1, E1>,
decider2: Decider<'a, C2, S2, E2>,
decider3: Decider<'a, C3, S3, E3>,
) -> Decider<'a, Sum3<C1, C2, C3>, (S1, S2, S3), Sum3<E1, E2, E3>> {
let new_decide = Box::new(move |c: &Sum3<C1, C2, C3>, s: &(S1, S2, S3)| match c {
Sum3::First(c) => {
let s1 = &s.0;
let events = (decider1.decide)(c, s1);
events
.into_iter()
.map(|e: E1| Sum3::First(e))
.collect::<Vec<Sum3<E1, E2, E3>>>()
}
Sum3::Second(c) => {
let s2 = &s.1;
let events = (decider2.decide)(c, s2);
events
.into_iter()
.map(|e: E2| Sum3::Second(e))
.collect::<Vec<Sum3<E1, E2, E3>>>()
}
Sum3::Third(c) => {
let s3 = &s.2;
let events = (decider3.decide)(c, s3);
events
.into_iter()
.map(|e: E3| Sum3::Third(e))
.collect::<Vec<Sum3<E1, E2, E3>>>()
}
});

let new_evolve = Box::new(move |s: &(S1, S2, S3), e: &Sum3<E1, E2, E3>| match e {
Sum3::First(e) => {
let s1 = &s.0;
let new_state = (decider1.evolve)(s1, e);
(new_state, s.1.to_owned(), s.2.to_owned())
}
Sum3::Second(e) => {
let s2 = &s.1;
let new_state = (decider2.evolve)(s2, e);
(s.0.to_owned(), new_state, s.2.to_owned())
}
Sum3::Third(e) => {
let s3 = &s.2;
let new_state = (decider3.evolve)(s3, e);
(s.0.to_owned(), s.1.to_owned(), new_state)
}
});

let new_initial_state = Box::new(move || {
let s1 = (decider1.initial_state)();
let s2 = (decider2.initial_state)();
let s3 = (decider3.initial_state)();
(s1, s2, s3)
});

Decider {
decide: new_decide,
evolve: new_evolve,
initial_state: new_initial_state,
}
}
11 changes: 0 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,3 @@ pub enum Sum<A, B> {
/// Second variant
Second(B),
}

/// Define the generic Combined/Sum Enum
#[derive(Debug, PartialEq, Clone)]
pub enum Sum3<A, B, C> {
/// First variant
First(A),
/// Second variant
Second(B),
/// Third variant
Third(C),
}
40 changes: 8 additions & 32 deletions src/saga_combined.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,21 @@
use crate::saga::Saga;
use crate::{Sum, Sum3};
use crate::Sum;

/// Combine two sagas into one.
/// Creates a new instance of a Saga by combining two sagas of type `AR1`, `A1` and `AR2`, `A2` into a new saga of type `Sum<AR1, AR2>`, `Sum<A1, A2>`
/// We encourage you to create your own combine functions to combine more sagas (three, four, five, ...) into one.
pub fn combine<'a, AR1, A1, AR2, A2>(
saga1: Saga<'a, AR1, A1>,
saga2: Saga<'a, AR2, A2>,
saga1: Saga<'a, AR2, A1>,
saga2: Saga<'a, AR1, A2>,
) -> Saga<'a, Sum<AR1, AR2>, Sum<A1, A2>> {
let new_react = Box::new(move |ar: &Sum<AR1, AR2>| match ar {
Sum::First(ar1) => {
let a1 = (saga1.react)(ar1);
a1.into_iter().map(|a: A1| Sum::First(a)).collect()
}
Sum::Second(ar2) => {
let a2 = (saga2.react)(ar2);
let a2 = (saga2.react)(ar1);
a2.into_iter().map(|a: A2| Sum::Second(a)).collect()
}
});

Saga { react: new_react }
}

/// Combine three sagas into one.
/// Creates a new instance of a Saga by combining three sagas of type `AR1`, `A1` , `AR2`, `A2`, and `AR3`, `A3` into a new saga of type `Sum3<AR1, AR2, AR3>`, `Sum3<A1, A2, A3>`
pub fn combine3<'a, AR1, A1, AR2, A2, AR3, A3>(
saga1: Saga<'a, AR1, A1>,
saga2: Saga<'a, AR2, A2>,
saga3: Saga<'a, AR3, A3>,
) -> Saga<'a, Sum3<AR1, AR2, AR3>, Sum3<A1, A2, A3>> {
let new_react = Box::new(move |ar: &Sum3<AR1, AR2, AR3>| match ar {
Sum3::First(ar1) => {
let a1 = (saga1.react)(ar1);
a1.into_iter().map(|a: A1| Sum3::First(a)).collect()
}
Sum3::Second(ar2) => {
let a2 = (saga2.react)(ar2);
a2.into_iter().map(|a: A2| Sum3::Second(a)).collect()
}
Sum3::Third(ar3) => {
let a3 = (saga3.react)(ar3);
a3.into_iter().map(|a: A3| Sum3::Third(a)).collect()
Sum::Second(ar2) => {
let a1 = (saga1.react)(ar2);
a1.into_iter().map(|a: A1| Sum::First(a)).collect()
}
});

Expand Down
2 changes: 1 addition & 1 deletion src/saga_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub trait ActionPublisher<A, Error> {

/// Saga Manager.
///
/// It is using a [Saga] to react to the action result and to publish the new actions.
/// It is using a `Saga` to react to the action result and to publish the new actions.
/// It is using an [ActionPublisher] to publish the new actions.
///
/// Generic parameters:
Expand Down
40 changes: 1 addition & 39 deletions src/view_combined.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::view::View;
use crate::{Sum, Sum3};
use crate::Sum;

/// Combine two views into one.
/// Creates a new instance of a View by combining two views of type `S1`, `E1` and `S2`, `E2` into a new view of type `(S1, S2)`, `Sum<E1, E2>`
Expand Down Expand Up @@ -31,41 +31,3 @@ pub fn combine<'a, S1: Clone, E1, S2: Clone, E2>(
initial_state: new_initial_state,
}
}

/// Combine three views into one.
/// Creates a new instance of a View by combining three views of type `S1`, `E1` , `S2`, `E2`, and `S3`, `E3` into a new view of type `(S1, S2, S3)`, `Sum3<E1, E2, E3>`
pub fn combine3<'a, S1: Clone, E1, S2: Clone, E2, S3: Clone, E3>(
view1: View<'a, S1, E1>,
view2: View<'a, S2, E2>,
view3: View<'a, S3, E3>,
) -> View<'a, (S1, S2, S3), Sum3<E1, E2, E3>> {
let new_evolve = Box::new(move |s: &(S1, S2, S3), e: &Sum3<E1, E2, E3>| match e {
Sum3::First(e) => {
let s1 = &s.0;
let new_state = (view1.evolve)(s1, e);
(new_state, s.1.to_owned(), s.2.to_owned())
}
Sum3::Second(e) => {
let s2 = &s.1;
let new_state = (view2.evolve)(s2, e);
(s.0.to_owned(), new_state, s.2.to_owned())
}
Sum3::Third(e) => {
let s3 = &s.2;
let new_state = (view3.evolve)(s3, e);
(s.0.to_owned(), s.1.to_owned(), new_state)
}
});

let new_initial_state = Box::new(move || {
let s1 = (view1.initial_state)();
let s2 = (view2.initial_state)();
let s3 = (view3.initial_state)();
(s1, s2, s3)
});

View {
evolve: new_evolve,
initial_state: new_initial_state,
}
}
2 changes: 1 addition & 1 deletion tests/saga_manager_combined_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl ActionPublisher<Sum<ShipmentCommand, OrderCommand>, SagaManagerError>

#[tokio::test]
async fn test() {
let order_created_event = Sum::First(OrderEvent::Created(OrderCreatedEvent {
let order_created_event = Sum::Second(OrderEvent::Created(OrderCreatedEvent {
order_id: 1,
customer_name: "John Doe".to_string(),
items: vec!["Item 1".to_string(), "Item 2".to_string()],
Expand Down
2 changes: 1 addition & 1 deletion tests/saga_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn test() {
items: vec!["Item 1".to_string(), "Item 2".to_string()],
})]
);
let combined_commands = combined_saga.compute_new_actions(&Sum::First(order_created_event));
let combined_commands = combined_saga.compute_new_actions(&Sum::Second(order_created_event));
assert_eq!(
combined_commands,
[Sum::First(ShipmentCommand::Create(CreateShipmentCommand {
Expand Down

0 comments on commit 6176d4a

Please sign in to comment.