Struct crux_core::compose::Compose

source ·
pub struct Compose<Ev> { /* private fields */ }
Expand description

Compose capability can be used to orchestrate effects into a single transaction.

Example include:

  • Running a number of HTTP requests in parallel and waiting for all to finish
  • Chaining effects together, where the output of one is the input of the next and the intermediate results are not useful to the app
  • Implementing request timeouts by selecting across a HTTP effect and a time effect
  • Any arbitrary graph of effects which depend on each other (or not).

The compose capability doesn’t have any operations it emits to the shell, and type generation fails on its operation type (Never)). This is difficult for crux to detect at the moment. To avoid this problem until a better fix is found, use #[effect(skip)] to skip the generation of an effect variant for the compose capability. For example

#[derive(Effect)]
pub struct Capabilities {
    pub render: Render<Event>,
    #[effect(skip)]
    pub compose: Compose<Event>,
}

Note that testing composed effects is more difficult, because it is not possible to enter the effect transaction “in the middle” - only from the beginning - or to ignore some of the effects with out stalling the entire downstream dependency chain.

Implementations§

source§

impl<Ev> Compose<Ev>

source

pub fn new(context: CapabilityContext<Never, Ev>) -> Self

source

pub fn spawn<F, Fut>(&self, effects_task: F)
where F: FnOnce(ComposeContext<Ev>) -> Fut, Fut: Future<Output = ()> + 'static + Send, Ev: 'static,

Spawn a task which orchestrates across other capabilities.

The argument is a closure which receives a ComposeContext which can be used to send events to the app.

For example:

    fn update(&self, event: Self::Event, model: &mut Self::Model, caps: &Self::Capabilities) {
        match event {
            Event::Trigger => caps.compose.spawn(|context| {
                let one = caps.one.clone();
                let two = caps.two.clone();

                async move {
                    let (result_one, result_two) =
                        futures::future::join(
                            one.one_async(10),
                            two.two_async(20)
                        ).await;

                    context.update_app(Event::Finished(result_one, result_two))
                }
            }),
            Event::Finished(one, two) => {
                model.total = one + two;
            }
        }
    }

Trait Implementations§

source§

impl<Ev> Capability<Ev> for Compose<Ev>

source§

type Operation = Never

source§

type MappedSelf<MappedEv> = Compose<MappedEv>

source§

fn map_event<F, NewEv>(&self, f: F) -> Self::MappedSelf<NewEv>
where F: Fn(NewEv) -> Ev + Send + Sync + 'static, Ev: 'static, NewEv: 'static,

source§

impl<E> Clone for Compose<E>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<Ev> Freeze for Compose<Ev>

§

impl<Ev> !RefUnwindSafe for Compose<Ev>

§

impl<Ev> Send for Compose<Ev>

§

impl<Ev> Sync for Compose<Ev>

§

impl<Ev> Unpin for Compose<Ev>

§

impl<Ev> !UnwindSafe for Compose<Ev>

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> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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.