Struct Decider

Source
pub struct Decider<'a, C: 'a, S: 'a, E: 'a, Error: 'a = ()> {
    pub decide: DecideFunction<'a, C, S, E, Error>,
    pub evolve: EvolveFunction<'a, S, E>,
    pub initial_state: InitialStateFunction<'a, S>,
}
Expand description

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. '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::decider::{Decider, EventComputation, StateComputation};

fn decider<'a>() -> Decider<'a, OrderCommand, OrderState, OrderEvent> {
    Decider {
        // Exhaustive pattern matching is used to handle the commands (modeled as Enum - SUM/OR type).
        decide: Box::new(|command, state| {
           match command {
                OrderCommand::Create(create_cmd) => {
                    Ok(vec![OrderEvent::Created(OrderCreatedEvent {
                        order_id: create_cmd.order_id,
                        customer_name: create_cmd.customer_name.to_owned(),
                        items: create_cmd.items.to_owned(),
                    })])
                }
                OrderCommand::Update(update_cmd) => {
                    if state.order_id == update_cmd.order_id {
                        Ok(vec![OrderEvent::Updated(OrderUpdatedEvent {
                            order_id: update_cmd.order_id,
                            updated_items: update_cmd.new_items.to_owned(),
                        })])
                    } else {
                        Ok(vec![])
                    }
                }
                OrderCommand::Cancel(cancel_cmd) => {
                    if state.order_id == cancel_cmd.order_id {
                        Ok(vec![OrderEvent::Cancelled(OrderCancelledEvent {
                            order_id: cancel_cmd.order_id,
                        })])
                    } else {
                        Ok(vec![])
                    }
                }
            }
        }),
        // 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(|| OrderState {
            order_id: 0,
            customer_name: "".to_string(),
            items: Vec::new(),
            is_cancelled: false,
        }),
    }
}

// Modeling the commands, events, and state. Enum is modeling the SUM/OR type, and struct is modeling the PRODUCT/AND type.
#[derive(Debug)]
pub enum OrderCommand {
    Create(CreateOrderCommand),
    Update(UpdateOrderCommand),
    Cancel(CancelOrderCommand),
}

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

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

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

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

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

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

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

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

let decider: Decider<OrderCommand, OrderState, OrderEvent> = decider();
let create_order_command = OrderCommand::Create(CreateOrderCommand {
    order_id: 1,
    customer_name: "John Doe".to_string(),
    items: vec!["Item 1".to_string(), "Item 2".to_string()],
});
let new_events = decider.compute_new_events(&[], &create_order_command);
    assert_eq!(new_events, Ok(vec![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 = decider.compute_new_state(None, &create_order_command);
    assert_eq!(new_state, Ok(OrderState {
        order_id: 1,
        customer_name: "John Doe".to_string(),
        items: vec!["Item 1".to_string(), "Item 2".to_string()],
        is_cancelled: false,
    }));

Fields§

§decide: DecideFunction<'a, C, S, E, Error>

The decide function is used to decide which events to produce based on the command and the current state.

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

The evolve function is used to evolve the state based on the current state and the event.

§initial_state: InitialStateFunction<'a, S>

The initial_state function is used to produce the initial state of the decider.

Implementations§

Source§

impl<'a, C, S, E, Error> Decider<'a, C, S, E, Error>

Source

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

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

Source

pub fn map_event<E2, F1, F2>( self, f1: F1, f2: F2, ) -> Decider<'a, C, S, E2, Error>
where F1: Fn(&E2) -> E + Send + Sync + 'a, F2: Fn(&E) -> E2 + Send + Sync + 'a,

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

Source

pub fn map_command<C2, F>(self, f: F) -> Decider<'a, C2, S, E, Error>
where F: Fn(&C2) -> C + Send + Sync + 'a,

Maps the Decider over the C/Command type parameter. Creates a new instance of Decider<C2, S, E, Error>.

Source

pub fn map_error<Error2, F>(self, f: F) -> Decider<'a, C, S, E, Error2>
where F: Fn(&Error) -> Error2 + Send + Sync + 'a,

Maps the Decider over the Error type parameter. Creates a new instance of Decider<C, S, E, Error2>.

Source

pub fn combine<C2, S2, E2>( self, decider2: Decider<'a, C2, S2, E2, Error>, ) -> Decider<'a, Sum<C, C2>, (S, S2), Sum<E, E2>, Error>
where S: Clone, S2: Clone,

Combines two deciders into one bigger decider Creates a new instance of a Decider by combining two deciders of type C, S, E and C2, S2, E2 into a new decider of type Sum<C, C2>, (S, S2), Sum<E, E2>

Source

pub fn combine3<C2, S2, E2, C3, S3, E3>( self, decider2: Decider<'a, C2, S2, E2, Error>, decider3: Decider<'a, C3, S3, E3, Error>, ) -> Decider<'a, Sum3<C, C2, C3>, (S, S2, S3), Sum3<E, E2, E3>, Error>
where S: Clone, S2: Clone, S3: Clone, E: Clone, E2: Clone, E3: Clone, C: Clone, C2: Clone, C3: Clone,

Combines three deciders into one bigger decider

Source

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>, ) -> Decider<'a, Sum4<C, C2, C3, C4>, (S, S2, S3, S4), Sum4<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,

Combines four deciders into one bigger decider

Source

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>, ) -> Decider<'a, Sum5<C, C2, C3, C4, C5>, (S, S2, S3, S4, S5), Sum5<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,

Combines five deciders into one bigger decider

Source

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>, ) -> Decider<'a, Sum6<C, C2, C3, C4, C5, C6>, (S, S2, S3, S4, S5, S6), Sum6<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,

Combines six deciders into one bigger decider

Trait Implementations§

Source§

impl<C, S, E, Error> EventComputation<C, S, E, Error> for Decider<'_, C, S, E, Error>

Source§

fn compute_new_events( &self, current_events: &[E], command: &C, ) -> Result<Vec<E>, Error>

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

Source§

impl<C, S, E, Error> StateComputation<C, S, E, Error> for Decider<'_, C, S, E, Error>

Source§

fn compute_new_state( &self, current_state: Option<S>, command: &C, ) -> Result<S, Error>

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

Auto Trait Implementations§

§

impl<'a, C, S, E, Error> Freeze for Decider<'a, C, S, E, Error>

§

impl<'a, C, S, E, Error = ()> !RefUnwindSafe for Decider<'a, C, S, E, Error>

§

impl<'a, C, S, E, Error> Send for Decider<'a, C, S, E, Error>

§

impl<'a, C, S, E, Error> Sync for Decider<'a, C, S, E, Error>

§

impl<'a, C, S, E, Error> Unpin for Decider<'a, C, S, E, Error>

§

impl<'a, C, S, E, Error = ()> !UnwindSafe for Decider<'a, C, S, E, Error>

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> Paint for T
where T: ?Sized,

Source§

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 primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
Source§

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>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
Source§

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 bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
Source§

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 mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
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.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
Source§

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);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
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.