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>
impl<'a, S, E> View<'a, S, E>
Sourcepub fn map_state<S2, F1, F2>(self, f1: F1, f2: F2) -> View<'a, S2, E>
pub fn map_state<S2, F1, F2>(self, f1: F1, f2: F2) -> View<'a, S2, E>
Maps the View over the S/State type parameter.
Creates a new instance of View<S2, E>
.
Sourcepub fn map_event<E2, F>(self, f: F) -> View<'a, S, E2>
pub fn map_event<E2, F>(self, f: F) -> View<'a, S, E2>
Maps the View over the E/Event type parameter.
Creates a new instance of View<S, E2>
.
Sourcepub fn combine<S2, E2>(
self,
view2: View<'a, S2, E2>,
) -> View<'a, (S, S2), Sum<E, E2>>
👎Deprecated since 0.8.0: Use the merge
function instead. This ensures all your views can subscribe to all Event
/E
in the system.
pub fn combine<S2, E2>( self, view2: View<'a, S2, E2>, ) -> View<'a, (S, S2), Sum<E, E2>>
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>
Sourcepub fn merge<S2>(self, view2: View<'a, S2, E>) -> View<'a, (S, S2), E>
pub fn merge<S2>(self, view2: View<'a, S2, E>) -> View<'a, (S, S2), E>
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.
Sourcepub fn merge3<S2, S3>(
self,
view2: View<'a, S2, E>,
view3: View<'a, S3, E>,
) -> View<'a, (S, S2, S3), E>
pub fn merge3<S2, S3>( self, view2: View<'a, S2, E>, view3: View<'a, S3, E>, ) -> View<'a, (S, S2, S3), E>
Merges three views into one.
Sourcepub 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>
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>
Merges four views into one.
Sourcepub 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>
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>
Merges five views into one.
Trait Implementations§
Source§impl<S, E> ViewStateComputation<E, S> for View<'_, S, E>
impl<S, E> ViewStateComputation<E, S> for View<'_, S, E>
Source§fn compute_new_state(&self, current_state: Option<S>, events: &[&E]) -> S
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the foreground set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red()
and
green()
, which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg()
:
use yansi::{Paint, Color};
painted.fg(Color::White);
Set foreground color to white using white()
.
use yansi::Paint;
painted.white();
Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the background set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red()
and
on_green()
, which have the same functionality but
are pithier.
§Example
Set background color to red using fg()
:
use yansi::{Paint, Color};
painted.bg(Color::Red);
Set background color to red using on_red()
.
use yansi::Paint;
painted.on_red();
Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute
value
.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold()
and
underline()
, which have the same functionality
but are pithier.
§Example
Make text bold using attr()
:
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);
Make text bold using using bold()
.
use yansi::Paint;
painted.bold();
Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi
Quirk
value
.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask()
and
wrap()
, which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk()
:
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);
Enable wrapping using wrap()
.
use yansi::Paint;
painted.wrap();
Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition
value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted
only when both stdout
and stderr
are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);