Struct fmodel_rust::view::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,

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>

Trait Implementations§

source§

impl<'a, S, E> ViewStateComputation<E, S> for View<'a, 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> !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>,

§

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>,

§

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.