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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::rc::Rc;
use serde::{Deserialize, Serialize};
use yew::{
format::Json,
services::{storage::Area, StorageService},
};
pub(crate) type Reduction<T> = Box<dyn FnOnce(&mut T)>;
pub trait Handler {
type Model;
fn new() -> Self;
fn apply(&mut self, f: Reduction<Self::Model>);
fn state(&self) -> Rc<Self::Model>;
}
#[derive(Default, Clone)]
pub struct GlobalHandler<T> {
state: Rc<T>,
}
impl<T> Handler for GlobalHandler<T>
where
T: Clone + Default,
{
type Model = T;
fn new() -> Self {
Default::default()
}
fn apply(&mut self, f: Reduction<Self::Model>) {
f(Rc::make_mut(&mut self.state));
}
fn state(&self) -> Rc<Self::Model> {
Rc::clone(&self.state)
}
}
pub trait Storable: Serialize + for<'a> Deserialize<'a> {
fn key() -> &'static str;
fn area() -> Area;
}
#[derive(Default)]
pub struct StorageHandler<T> {
state: Rc<T>,
storage: Option<StorageService>,
}
impl<T> StorageHandler<T>
where
T: Storable,
{
fn load_state(&mut self) {
let result = self.storage.as_mut().map(|s| s.restore(T::key()));
if let Some(Json(Ok(state))) = result {
self.state = state;
}
}
fn save_state(&mut self) {
if let Some(storage) = &mut self.storage {
storage.store(T::key(), Json(&self.state));
}
}
}
impl<T> Handler for StorageHandler<T>
where
T: Default + Clone + Storable,
{
type Model = T;
fn new() -> Self {
let mut this: Self = Default::default();
this.storage = StorageService::new(T::area()).ok();
this.load_state();
this
}
fn apply(&mut self, f: Reduction<Self::Model>) {
f(Rc::make_mut(&mut self.state));
self.save_state();
}
fn state(&self) -> Rc<Self::Model> {
Rc::clone(&self.state)
}
}
impl<T> Clone for StorageHandler<T>
where
T: Default + Clone + Storable,
{
fn clone(&self) -> Self {
let mut new = Self::new();
new.state = self.state.clone();
new
}
}