percy_state/lib.rs
1//! Used to manage application state.
2
3#![deny(missing_docs)]
4
5use std::sync::{Arc, RwLock, RwLockReadGuard};
6
7/// Holds application state.
8///
9/// # Cloning
10///
11/// It can be useful to clone `AppStateWrapper`'s in order to pass state into event handler
12/// closures.
13///
14/// All clones will point to the same inner state.
15///
16/// Cloning an `AppStateWrapper` is a very cheap operation.
17pub struct AppStateWrapper<S: AppState>(Arc<RwLock<S>>);
18
19/// Application state.
20pub trait AppState {
21 /// Indicates that something has happened.
22 ///
23 /// ```
24 /// # use std::time::SystemTime;
25 /// #[allow(unused)]
26 /// enum MyMessageType {
27 /// IncreaseClickCounter,
28 /// SetLastPausedAt(SystemTime)
29 /// }
30 /// ```
31 type Message;
32
33 /// Send a message to the state object.
34 /// This will usually lead to a state update
35 fn msg(&mut self, message: Self::Message);
36}
37
38impl<S: AppState> AppStateWrapper<S> {
39 /// Create a new AppStateWrapper.
40 pub fn new(state: S) -> Self {
41 Self(Arc::new(RwLock::new(state)))
42 }
43
44 /// Acquire write access to the AppState then send a message.
45 pub fn msg(&mut self, msg: S::Message) {
46 self.0.write().unwrap().msg(msg);
47 }
48
49 /// Acquire read access to AppState.
50 pub fn read(&self) -> RwLockReadGuard<'_, S> {
51 self.0.read().unwrap()
52 }
53}
54
55impl<S: AppState> Clone for AppStateWrapper<S> {
56 fn clone(&self) -> Self {
57 AppStateWrapper(Arc::clone(&self.0))
58 }
59}