Struct View

Source
pub struct View<'a, S: 'a, E: 'a> {
    pub evolve: EvolveFunction<'a, S, E>,
    pub initial_state: InitialStateFunction<'a, S>,
}
Expand description

View represents the event handling algorithm, responsible for translating the events into denormalized state, which is more adequate for querying. It has two generic parameters S/State, E/Event , representing the type of the values that View may contain or use. 'a is used as a lifetime parameter, indicating that all references contained within the struct (e.g., references within the function closures) must have a lifetime that is at least as long as ’a.

§Example

use fmodel_rust::view::View;

fn view<'a>() -> View<'a, OrderViewState, OrderEvent> {
    View {
       // Exhaustive pattern matching is used to handle the events (modeled as Enum - SUM/OR type).
       evolve: Box::new(|state, event| {
            let mut new_state = state.clone();
            match event {
               OrderEvent::Created(created_event) => {
                    new_state.order_id = created_event.order_id;
                    new_state.customer_name = created_event.customer_name.to_owned();
                    new_state.items = created_event.items.to_owned();
                }
                OrderEvent::Updated(updated_event) => {
                    new_state.items = updated_event.updated_items.to_owned();
                }
                OrderEvent::Cancelled(_) => {
                    new_state.is_cancelled = true;
                }
            }
            new_state
        }),
        initial_state: Box::new(|| OrderViewState {
            order_id: 0,
            customer_name: "".to_string(),
            items: Vec::new(),
            is_cancelled: false,
        }),
    }
}

#[derive(Debug)]
pub enum OrderEvent {
    Created(OrderCreatedEvent),
    Updated(OrderUpdatedEvent),
    Cancelled(OrderCancelledEvent),
}

#[derive(Debug)]
pub struct OrderCreatedEvent {
    pub order_id: u32,
    pub customer_name: String,
    pub items: Vec<String>,
}

#[derive(Debug)]
pub struct OrderUpdatedEvent {
    pub order_id: u32,
    pub updated_items: Vec<String>,
}

#[derive(Debug)]
pub struct OrderCancelledEvent {
    pub order_id: u32,
}

#[derive(Debug, Clone)]
struct OrderViewState {
    order_id: u32,
    customer_name: String,
    items: Vec<String>,
    is_cancelled: bool,
}

let view: View<OrderViewState, OrderEvent> = view();
let order_created_event = OrderEvent::Created(OrderCreatedEvent {
    order_id: 1,
    customer_name: "John Doe".to_string(),
    items: vec!["Item 1".to_string(), "Item 2".to_string()],
});
let new_state = (view.evolve)(&(view.initial_state)(), &order_created_event);

Fields§

§evolve: EvolveFunction<'a, S, E>

The evolve function is the main state evolution algorithm.

§initial_state: InitialStateFunction<'a, S>

The initial_state function is the initial state.

Implementations§

Source§

impl<'a, S, E> View<'a, S, E>

Source

pub fn map_state<S2, F1, F2>(self, f1: &'a F1, f2: &'a F2) -> View<'a, S2, E>
where F1: Fn(&S2) -> S + Send + Sync, F2: Fn(&S) -> S2 + Send + Sync,

Maps the View over the S/State type parameter. Creates a new instance of View<S2, E>.

Source

pub fn map_event<E2, F>(self, f: &'a F) -> View<'a, S, E2>
where F: Fn(&E2) -> E + Send + Sync,

Maps the View over the E/Event type parameter. Creates a new instance of View<S, E2>.

Source

pub fn combine<S2, E2>( self, view2: View<'a, S2, E2>, ) -> View<'a, (S, S2), Sum<E, E2>>
where S: Clone, S2: Clone,

👎Deprecated since 0.8.0: Use the merge function instead. This ensures all your views can subscribe to all Event/E in the system.

Combines two views into one. Creates a new instance of a View by combining two views of type S, E and S2, E2 into a new view of type (S, S2), Sum<E, E2> Combines two views that operate on different event types (E`` and E2``) into a new view operating on Sum<E, E2>

Source

pub fn merge<S2>(self, view2: View<'a, S2, E>) -> View<'a, (S, S2), E>
where S: Clone, S2: Clone,

Merges two views into one. Creates a new instance of a View by merging two views of type S, E and S2, E into a new view of type (S, S2), E Similar to combine, but the event type is the same for both views. This ensures all your views can subscribe to all Event/E in the system.

Source

pub fn merge3<S2, S3>( self, view2: View<'a, S2, E>, view3: View<'a, S3, E>, ) -> View<'a, (S, S2, S3), E>
where S: Clone, S2: Clone, S3: Clone,

Merges three views into one.

Source

pub fn merge4<S2, S3, S4>( self, view2: View<'a, S2, E>, view3: View<'a, S3, E>, view4: View<'a, S4, E>, ) -> View<'a, (S, S2, S3, S4), E>
where S: Clone, S2: Clone, S3: Clone, S4: Clone,

Merges four views into one.

Source

pub fn merge5<S2, S3, S4, S5>( self, view2: View<'a, S2, E>, view3: View<'a, S3, E>, view4: View<'a, S4, E>, view5: View<'a, S5, E>, ) -> View<'a, (S, S2, S3, S4, S5), E>
where S: Clone, S2: Clone, S3: Clone, S4: Clone, S5: Clone,

Merges five views into one.

Source

pub fn merge6<S2, S3, S4, S5, S6>( self, view2: View<'a, S2, E>, view3: View<'a, S3, E>, view4: View<'a, S4, E>, view5: View<'a, S5, E>, view6: View<'a, S6, E>, ) -> View<'a, (S, S2, S3, S4, S5, S6), E>
where S: Clone, S2: Clone, S3: Clone, S4: Clone, S5: Clone, S6: Clone,

Merges six views into one.

Trait Implementations§

Source§

impl<S, E> ViewStateComputation<E, S> for View<'_, S, E>

Source§

fn compute_new_state(&self, current_state: Option<S>, events: &[&E]) -> S

Computes new state based on the current state and the events.

Auto Trait Implementations§

§

impl<'a, S, E> Freeze for View<'a, S, E>

§

impl<'a, S, E> !RefUnwindSafe for View<'a, S, E>

§

impl<'a, S, E> Send for View<'a, S, E>

§

impl<'a, S, E> Sync for View<'a, S, E>

§

impl<'a, S, E> Unpin for View<'a, S, E>

§

impl<'a, S, E> !UnwindSafe for View<'a, S, E>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.