Crate oxide_mvu

Crate oxide_mvu 

Source
Expand description

A lightweight Model-View-Update (MVU) runtime for Rust with no_std support.

Implements the MVU pattern for building predictable, testable applications with unidirectional data flow and controlled side effects.

§Example

use oxide_mvu::{Emitter, Effect, MvuLogic, MvuRuntime, Renderer};

#[derive(Clone)]
enum Event {
    AccumulateClicked,
}

#[derive(Clone)]
struct Model {
    count: i32,
}

struct Props {
    count: i32,
    on_accumulate_click: Box<dyn Fn()>,
}

struct MyLogic;

impl MvuLogic<Event, Model, Props> for MyLogic {
    fn init(&self, model: Model) -> (Model, Effect<Event>) {
        (model, Effect::none())
    }

    fn update(&self, event: Event, model: &Model) -> (Model, Effect<Event>) {
        match event {
            Event::AccumulateClicked => {
                let new_model = Model {
                    count: model.count + 1,
                    ..model.clone()
                };
                (new_model, Effect::none())
            }
        }
    }

    fn view(&self, model: &Model, emitter: &Emitter<Event>) -> Props {
        let emitter = emitter.clone();
        Props {
            count: model.count,
            on_accumulate_click: Box::new(move || {
                emitter.try_emit(Event::AccumulateClicked);
            }),
        }
    }
}

struct MyRenderer;

impl Renderer<Props> for MyRenderer {
    fn render(&mut self, _props: Props) {}
}

async fn main_async() {
    // Create a spawner for your async runtime.
    // This is how `Effect`s are executed.
    let spawner = |fut| {
        // Spawn the future on your chosen runtime.
        // Examples:
        // tokio::spawn(fut);
        // async_std::task::spawn(fut);
        let _ = fut;
    };

    let runtime = MvuRuntime::new(
        Model { count: 0 },
        MyLogic,
        MyRenderer,
        spawner,
    );

    // `run()` returns a Future representing the event loop.
    // It must be awaited inside an async context.
    runtime.run().await;
}

In a real application, main_async would be executed by your async runtime (e.g. via #[tokio::main], async_std::main, or an embedded executor).

Structs§

Effect
Declarative description of events to be processed.
Emitter
Event emitter that can be embedded in Props.
MvuRuntime
The MVU runtime that orchestrates the event loop.

Traits§

Event
Trait alias for event type constraints.
MvuLogic
Application logic trait defining the MVU contract.
Renderer
Renderer abstraction for rendering Props.
Spawner
A spawner trait for executing futures on an async runtime.