gbj / async-store

A Redux-inspired Rust state container with a stream-based async API.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

async-store

A Redux-inspired Rust state container with an async Stream API.

Example

use async_store::Stream;
use futures::stream::StreamExt;

// Define state, action, and reducer
struct State {
    a: String,
}

impl State {
    pub fn new() -> Self {
        Self {
            a: String::from("Initial value"),
        }
    }
}

enum Msg {
    ClearStr,
    SetStr(String),
}

fn reducer(state: &mut State, action: Msg) {
    match action {
        Msg::ClearStr => state.a = String::from(""),
        Msg::SetStr(s) => state.a = s,
    }
}

// Create the actual store
let store = Store::new(State::new(), reducer);

// Derive a Stream from the store. Conceptually this is similar to a Redux slice; you'd
// typically use it to isolate a single field in your state.
// The function here is given &State, so you may need to clone or copy the field.
let mut stream = store.stream(|state| state.a.clone());

store.dispatch(Msg::SetStr(String::from("string 2")));
store.dispatch(Msg::ClearStr);

// Poll the stream
// It will always give the latest value of the state, without intervening values
assert_eq!(stream.next().await, Some(String::from("")));

Advantages

  • Simple, predictable state changes
  • Async interface via Streams
  • State does not need to be Clone; the store itself owns it.

Caveat

There's no change detection on individual fields of a state struct. If any action has been dispatched, every streamm will think it has a new value when it is polled, which means you should limit expensive operations in your .stream() selectors.

Prior art

The notion of a state container that combines a State type, an Action enum, and a reducer function is, of course, inspired by the model promoted by Elm, Redux, and company.

The design of the Store type is inspired by redux-rs and the async implementation of the Store type is heavily influenced by the excellent futures_signals crate.

About

A Redux-inspired Rust state container with a stream-based async API.

License:Apache License 2.0


Languages

Language:Rust 100.0%