oxide-mvu
A lightweight Model-View-Update (MVU) runtime framework for Rust with no_std support.
Overview
(Note that this framework is not yet ready for production, and APIs should not be considered stable. Many of the current interfaces are an assault on the eyes as of v0.2.0)
oxide-mvu implements the MVU pattern for building predictable, testable applications in Rust. The framework is powerful enough
to be a good choice for most applications, but will always evolve with support for no_std, low-memory, single-cpu, embedded systems as a baseline.
Oxide is intended to clarify the management of state in an application using clear separation of concerns between cleanly isolated view and application logic layers.
Features
- Unidirectional data flow: State transitions occur in a single loop:
- → event emission is triggered from an effect or user input
- → update function receives event data and yields new state
- → view function reduces state to renderable props
- → renderer function receives props for display
- Type-safe event dispatch: Callbacks in Props maintain type safety
- Effect system: Controlled, declarative side effects
- no_std support: Works in embedded environments (requires
allocfor heap allocation)
Installation
Add to your Cargo.toml:
[]
= "0.2.0"
For no_std environments:
[]
= { = "0.2.0", = ["no_std"] }
Usage
Define your types
use ;
Implement the MvuLogic trait
;
Implement a Renderer
use Renderer;
;
Create a Spawner
The runtime needs a spawner function to execute async effects. The spawner is framework-agnostic, allowing you to use any async runtime (tokio, async-std, smol, etc.):
Using tokio:
use Spawner;
let spawner: Spawner = Boxnew;
Using async-std:
use Spawner;
let spawner: Spawner = Boxnew;
Run the application
use ;
Testing
oxide-mvu provides specialized testing utilities for integration testing your MVU applications.
Enabling Testing Utilities
To access the testing helpers in your project, enable the testing feature:
[]
= { = "0.2.0", = ["testing"] }
This gives you access to:
TestMvuRuntime- Runtime with manual event processing controlTestMvuDriver- Driver for manually processing events in testsTestRenderer- Renderer that captures Props for assertions
Unit Testing
State transitions are pure functions, making them easy to unit test:
Integration Testing
Use TestMvuRuntime and TestRenderer to test the full MVU loop:
use ;
Key Testing Concepts
TestMvuRuntime: UnlikeMvuRuntime, events are not automatically processed. You must calldriver.process_events()to manually drive the event loop.TestRenderer::boxed(): Returns a boxed renderer while keeping a handle for assertions.renderer.with_renders(): Access all captured Props for assertions or to trigger callbacks.driver.process_events(): Process all queued events until the queue is empty.create_test_spawner(): Creates a spawner that executes effects synchronously for deterministic testing.
See the tests directory for complete examples.
License
Licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)