Skip to main content

Layer

Trait Layer 

Source
pub trait Layer:
    Send
    + Sync
    + Sized {
    type Event;
    type Effect;
    type ViewModel;

    // Required methods
    fn update<F>(
        &self,
        event: Self::Event,
        effect_callback: F,
    ) -> Vec<Self::Effect>
       where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
    fn resolve<Output, F>(
        &self,
        request: &mut impl Resolvable<Output>,
        output: Output,
        effect_callback: F,
    ) -> Result<Vec<Self::Effect>, ResolveError>
       where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
    fn process_tasks<F>(&self, effect_callback: F) -> Vec<Self::Effect>
       where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static;
    fn view(&self) -> Self::ViewModel;

    // Provided methods
    fn handle_effects_using<EM>(
        self,
        middleware: EM,
    ) -> HandleEffectLayer<Self, EM>
       where EM: EffectMiddleware + 'static,
             Self::Effect: TryInto<Request<EM::Op>, Error = Self::Effect> { ... }
    fn map_effect<NewEffect>(self) -> MapEffectLayer<Self, NewEffect>
       where NewEffect: From<Self::Effect> + Send + 'static { ... }
    fn bridge<Format: FfiFormat>(
        self,
        effect_callback: impl Fn(Result<Vec<u8>, BridgeError<Format>>) + Send + Sync + 'static,
    ) -> Bridge<Self, Format>
       where Self::Effect: EffectFFI,
             Self::Event: for<'a> Deserialize<'a> { ... }
}
Expand description

A layer in the middleware stack.

This is implemented by the Core and the different types of middlewares, so that they can be composed as required.

This is the lower-level of the middleware traits. You might want to implement this for middleware which filters or transforms events or your view model, with awareness of your app’s Event and ViewModel types.

If you want to build a reusable effect-handling middleware, see EffectMiddleware.

Required Associated Types§

Source

type Event

Event type expected by this layer

Source

type Effect

Effect type returned by this layer

Source

type ViewModel

ViewModel returned by this layer

Required Methods§

Source

fn update<F>(&self, event: Self::Event, effect_callback: F) -> Vec<Self::Effect>
where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static,

Process event from the Shell. Compared to Core::process_event this expects an additional argument - a callback to be called with effects requested outside of the initial call context.

The callback is used in scenarios where an effect handling middleware has handled and resolved an effect, and received follow-up effects (from the next layer down), which it cannot process. This may happen some time after the initial process_event call from the shell, and on a different thread.

The expected behaviour of the callback is to process the effects like a shell would and call Layer::resolve with the output of the processing.

Source

fn resolve<Output, F>( &self, request: &mut impl Resolvable<Output>, output: Output, effect_callback: F, ) -> Result<Vec<Self::Effect>, ResolveError>
where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static,

Resolve a requested effect. Compared to Core::process_event this expects an additional argument - a callback to be called with effects requested outside of the initial call context.

The callback is used in scenarios where an effect handling middleware has handled and resolved an effect, and received follow-up effects (from the next layer down), which it cannot process. This may happen some time after this resolve call, and on a different thread.

The expected behaviour of the callback is to process the effects like a shell would and call Layer::resolve with the output of the processing.

§Errors

Returns a ResolveError if the request fails to resolve due to a type mismatch, or isn’t expected to be resolved (either it was never expected to be resolved, or it has already been resolved)

Source

fn process_tasks<F>(&self, effect_callback: F) -> Vec<Self::Effect>
where F: Fn(Vec<Self::Effect>) + Sync + Send + 'static,

Process any tasks in the effect runtime of the Core, which are able to proceed. The tasks may produce effects which will be returned by the core and may be processed by lower middleware layers.

You should not need to call this method directly. Most implementations should simply forward the call to the next Layer.

This is used by the Bridge, when resolving effects over FFI. It can’t call Core::resolve, because the Output type argument is not known due to the type erasure involved in serializing effects and storing request handles for the FFI.

Source

fn view(&self) -> Self::ViewModel

Return the current state of the view model

Provided Methods§

Source

fn handle_effects_using<EM>(self, middleware: EM) -> HandleEffectLayer<Self, EM>
where EM: EffectMiddleware + 'static, Self::Effect: TryInto<Request<EM::Op>, Error = Self::Effect>,

Wrap this layer with an effect handling middleware. The middleware argument must implement the EffectMiddleware trait.

Source

fn map_effect<NewEffect>(self) -> MapEffectLayer<Self, NewEffect>
where NewEffect: From<Self::Effect> + Send + 'static,

Wrap this layer with an effect mapping middleware to change the Effect type returned.

This is generally used after a number of effect handling layers to “narrow” the effect type - eliminate the variants which will never be encountered, so that exhaustive matches don’t require unused branches.

Source

fn bridge<Format: FfiFormat>( self, effect_callback: impl Fn(Result<Vec<u8>, BridgeError<Format>>) + Send + Sync + 'static, ) -> Bridge<Self, Format>
where Self::Effect: EffectFFI, Self::Event: for<'a> Deserialize<'a>,

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<A> Layer for Core<A>
where A: Send + Sync + 'static + App, A::Model: Send + Sync + 'static,

Source§

type Event = <A as App>::Event

Source§

type Effect = <A as App>::Effect

Source§

type ViewModel = <A as App>::ViewModel

Source§

impl<Next, EM> Layer for HandleEffectLayer<Next, EM>
where Next: Layer, Next::Effect: TryInto<Request<EM::Op>, Error = Next::Effect>, EM: EffectMiddleware + 'static,

Source§

type Event = <Next as Layer>::Event

Source§

type Effect = <Next as Layer>::Effect

Source§

type ViewModel = <Next as Layer>::ViewModel

Source§

impl<Next, Effect> Layer for MapEffectLayer<Next, Effect>
where Next: Layer, Effect: From<Next::Effect> + Send + 'static,

Source§

type Event = <Next as Layer>::Event

Source§

type Effect = Effect

Source§

type ViewModel = <Next as Layer>::ViewModel