-
Notifications
You must be signed in to change notification settings - Fork 18
/
reducer.rs
42 lines (35 loc) · 1.38 KB
/
reducer.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use example_bindings::*;
use once_cell::sync::Lazy;
use redux_example::{ReduxAction, ReduxState, StateUpdate};
use std::{cell::RefCell, rc::Rc};
// We maintain the global state in a mutable static so that we do not need to pass it from
// JavaScript every time we call the reducer. This avoids significant serialization overhead we
// would incur otherwise.
static mut STATE: Lazy<RefCell<ReduxState>> = Lazy::new(|| RefCell::new(ReduxState::default()));
#[fp_export_impl(example_bindings)]
fn reducer_bridge(action: ReduxAction) -> StateUpdate {
// Accessing a global static instance is unsafe, because it could cause data
// races. This should not be a problem here as long as we only call this
// function from WASM in a single-threaded context:
let old_state = unsafe { STATE.get_mut() };
let new_state = reducer(old_state, action);
let state_update = StateUpdate::from_state(old_state, &new_state);
unsafe {
STATE.replace(new_state);
}
state_update
}
fn reducer(state: &ReduxState, action: ReduxAction) -> ReduxState {
let mut state = state.clone();
match action {
ReduxAction::ClearTitle => {
state.title = Rc::new(String::default());
state.revision += 1;
}
ReduxAction::UpdateTitle { title } => {
state.title = Rc::new(title);
state.revision += 1;
}
}
state
}