Cmd

Struct Cmd 

Source
pub struct Cmd<M>
where M: Message,
{ /* private fields */ }
Expand description

A command is an asynchronous operation that produces a message.

Commands are used for side effects like:

  • HTTP requests
  • File I/O
  • Timers
  • Any async operation

Implementations§

Source§

impl<M> Cmd<M>
where M: Message,

Source

pub fn new<F>(f: F) -> Cmd<M>
where F: FnOnce() -> Option<M> + Send + 'static,

Create a new command from a function

Note: If the function returns None, consider using Cmd::noop() instead for better performance and clearer intent.

§Example
let cmd: Cmd<Msg> = Cmd::new(|| {
    // Perform a side effect
    let data = std::fs::read_to_string("config.json").ok()?;
    Some(Msg::DataLoaded(data))
});
Source

pub fn fallible<F>(f: F) -> Cmd<M>
where F: FnOnce() -> Result<Option<M>, Error> + Send + 'static,

Create a new fallible command that can return errors

Use this when your command might fail and you want to handle errors gracefully.

§Example
let cmd: Cmd<Msg> = Cmd::fallible(|| {
    let data = std::fs::read_to_string("config.json")?;
    Ok(Some(Msg::ConfigLoaded(data)))
});
Source

pub fn noop() -> Cmd<M>

Returns a no-op command that continues running without doing anything

This is the idiomatic way to return “no command” from update(). The program will continue running without executing any side effects.

§Example
        match event {
            Event::Tick => {
                // Update internal state but don't trigger side effects
                Cmd::noop()
            }
            _ => Cmd::noop()
        }
Source

pub fn none() -> Cmd<M>

👎Deprecated since 0.2.1: Use Cmd::noop() instead. The name ‘none’ was confusing.

Returns a no-op command that continues running without doing anything

§Deprecated

This method is deprecated. Use Cmd::noop() instead for clearer intent. The name “none” was confusing because it returns Some(Cmd) rather than None.

§Example
// Old way (deprecated):
let cmd: Cmd<Msg> = Cmd::noop();

// New way (preferred):
let cmd: Cmd<Msg> = Cmd::noop();
Source

pub fn quit() -> Cmd<M>

👎Deprecated since 0.2.1: Use commands::quit() instead for consistency

Create a quit command

§Deprecated

This method is deprecated. Use commands::quit() instead for consistency.

§Example
// Old way (deprecated):
let cmd: Cmd<Msg> = Cmd::quit();

// New way (preferred):
let cmd: Cmd<Msg> = commands::quit();
Source

pub fn tick<F>(duration: Duration, callback: F) -> Cmd<M>
where F: FnOnce() -> M + Send + 'static,

👎Deprecated since 0.2.1: Use commands::tick() instead for consistency

Create a tick command

§Deprecated

This method is deprecated. Use commands::tick() instead for consistency.

§Example
// Old way (deprecated):
let cmd: Cmd<Msg> = Cmd::tick(Duration::from_secs(1), || Msg::Tick);

// New way (preferred):
let cmd: Cmd<Msg> = commands::tick(Duration::from_secs(1), || Msg::Tick);
Source

pub fn every<F>(duration: Duration, callback: F) -> Cmd<M>
where F: FnOnce(Instant) -> M + Send + 'static,

👎Deprecated since 0.2.1: Use commands::every() instead for consistency

Create an every command

§Deprecated

This method is deprecated. Use commands::every() instead for consistency.

§Example
// Old way (deprecated):
let cmd: Cmd<Msg> = Cmd::every(Duration::from_secs(1), |instant| Msg::Tick(instant));

// New way (preferred):
let cmd: Cmd<Msg> = commands::every(Duration::from_secs(1), |instant| Msg::Tick(instant));
Source

pub fn is_exec_process(&self) -> bool

Check if this is an exec process command Check if this is an exec process command

Source

pub fn is_noop(&self) -> bool

Check if this is a no-op command

Source

pub fn is_quit(&self) -> bool

Check if this is a quit command

Source

pub fn map<N, F>(self, f: F) -> Cmd<N>
where N: Message, F: Fn(M) -> N + Send + Sync + 'static + Clone,

Transform the messages produced by this command

This is essential for component composition, allowing child components to produce commands that can be lifted to parent message types.

§Example
let child_cmd: Cmd<ChildMsg> = Cmd::new(|| Some(ChildMsg::Click));
let parent_cmd: Cmd<ParentMsg> = child_cmd.map(ParentMsg::Child);
Source

pub fn inspect<F>(self, f: F) -> Cmd<M>
where F: FnOnce(&Cmd<M>),

Inspect this command for debugging

This allows you to observe command execution without modifying behavior.

§Example
let cmd: Cmd<Msg> = Cmd::noop()
    .inspect(|cmd| println!("Executing command: {:?}", cmd));
Source

pub fn inspect_if<F>(self, condition: bool, f: F) -> Cmd<M>
where F: FnOnce(&Cmd<M>),

Conditionally inspect this command

Only runs the inspection function if the condition is true.

§Example
let cmd: Cmd<Msg> = Cmd::new(|| Some(Msg::Data("test".into())))
    .inspect_if(debug_mode, |cmd| {
        eprintln!("Debug: executing {}", cmd.debug_name());
    });
Source

pub fn debug_name(&self) -> &'static str

Get a string representation of the command type for debugging

§Example
let cmd: Cmd<Msg> = commands::tick(Duration::from_secs(1), || Msg::Tick);
assert_eq!(cmd.debug_name(), "Tick");

let noop: Cmd<Msg> = Cmd::noop();
assert_eq!(noop.debug_name(), "NoOp");
Source

pub fn then(self, other: Cmd<M>) -> Cmd<M>

Chain this command with another, running them sequentially

The second command will only run after the first completes. This is equivalent to sequence(vec![self, other]).

§Example
use hojicha_core::{Cmd, Message};

#[derive(Debug, Clone)]
enum Msg {
    First,
    Second,
}

let cmd: Cmd<Msg> = Cmd::new(|| Some(Msg::First))
    .then(Cmd::new(|| Some(Msg::Second)));
Source

pub fn and(self, other: Cmd<M>) -> Cmd<M>

Combine this command with another, running them concurrently

Both commands will run at the same time. This is equivalent to batch(vec![self, other]).

§Example
use hojicha_core::{Cmd, Message};
use std::time::Duration;

#[derive(Debug, Clone)]
enum Msg {
    Tick1,
    Tick2,
}

let cmd: Cmd<Msg> = Cmd::tick(Duration::from_secs(1), || Msg::Tick1)
    .and(Cmd::tick(Duration::from_secs(2), || Msg::Tick2));
Source

pub fn when(self, condition: bool) -> Cmd<M>

Execute this command only if a condition is met

If the condition is false, returns Cmd::noop().

§Example
use hojicha_core::{Cmd, Message};

#[derive(Debug, Clone)]
enum Msg {
    Action,
}

let enabled = true;
let cmd: Cmd<Msg> = Cmd::new(|| Some(Msg::Action))
    .when(enabled);
Source

pub fn unless(self, condition: bool) -> Cmd<M>

Execute this command unless a condition is met

If the condition is true, returns Cmd::noop().

§Example
use hojicha_core::{Cmd, Message};

#[derive(Debug, Clone)]
enum Msg {
    Action,
}

let disabled = false;
let cmd: Cmd<Msg> = Cmd::new(|| Some(Msg::Action))
    .unless(disabled);

Trait Implementations§

Source§

impl<M> CmdTestExt<M> for Cmd<M>
where M: Message + Clone + Send + 'static,

Source§

fn execute_sync(self) -> Option<M>

Execute the command synchronously in tests
Source§

fn execute_with_harness(self, harness: &AsyncTestHarness) -> Vec<M>

Execute with a test harness
Source§

impl<M> Debug for Cmd<M>
where M: Message,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<M> Freeze for Cmd<M>

§

impl<M> !RefUnwindSafe for Cmd<M>

§

impl<M> Send for Cmd<M>

§

impl<M> !Sync for Cmd<M>

§

impl<M> Unpin for Cmd<M>

§

impl<M> !UnwindSafe for Cmd<M>

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> Inspectable for T

Source§

fn inspect(self, label: &str) -> Self
where Self: Debug,

Inspect this value with a label
Source§

fn inspect_if(self, condition: bool, label: &str) -> Self
where Self: Debug,

Conditionally inspect this value
Source§

fn inspect_with<F>(self, label: &str, f: F) -> Self
where F: FnOnce(&Self) -> String,

Inspect with a custom formatter
Source§

fn tap<F>(self, f: F) -> Self
where F: FnOnce(&Self),

Tap into the value for side effects
Source§

fn tap_if<F>(self, condition: bool, f: F) -> Self
where F: FnOnce(&Self),

Conditionally tap into the value
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.
Source§

impl<T> Message for T
where T: Send + 'static,