Skip to main content

rio_rs/
app_data.rs

1//! Shared data for Rio applications
2//!
3//! Provides an Container in which one can store data that will be
4//! accessed across the application's handlers
5
6use state::Container;
7
8/// Alias for data Container
9///
10/// It will usually be wrapped in a [`std::sync::Arc`]. This Container does not
11/// provide interior mutability.
12///
13/// More about the container [`struct@state::Container`]
14///
15/// # Example
16/// ```rust
17/// # use rio_rs::app_data::{AppData, AppDataExt};
18/// let app_data = AppData::new();
19/// app_data.set("Test".to_string());
20///
21/// let value = app_data.get::<String>();
22/// assert_eq!(value, "Test");
23///
24/// let value = app_data.get_or_default::<usize>();
25/// assert_eq!(value, &0);
26/// ```
27pub type AppData = Container!(Send + Sync);
28
29/// Set of utilities to work with [state] crate
30pub trait AppDataExt {
31    /// Attempts to retrieve the global state for type `T`.
32    /// If it hasn't been initialize, a new one `T` will be created
33    /// using [Default::default]
34    fn get_or_default<T: Default + Send + Sync + 'static>(&self) -> &T;
35}
36
37impl AppDataExt for AppData {
38    fn get_or_default<T: Default + Send + Sync + 'static>(&self) -> &T {
39        match self.try_get::<T>() {
40            Some(value) => value,
41            None => {
42                let value = T::default();
43                self.set(value);
44                self.get::<T>()
45            }
46        }
47    }
48}