Skip to main content

sword_core/state/
mod.rs

1mod traits;
2
3use std::{
4    any::{Any, TypeId, type_name},
5    collections::HashMap,
6    sync::Arc,
7};
8
9use crate::DependencyInjectionError;
10use parking_lot::RwLock;
11
12pub use traits::*;
13
14/// Application state container for type-safe dependency injection and data sharing.
15///
16/// `State` provides a thread-safe way to store and retrieve shared data across
17/// the entire application. It uses `TypeId` as keys to ensure type safety.
18#[derive(Clone, Debug)]
19pub struct State {
20    inner: Arc<RwLock<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>>,
21}
22
23impl State {
24    pub fn new() -> Self {
25        Self {
26            inner: Arc::new(RwLock::new(HashMap::new())),
27        }
28    }
29
30    /// Extract a clone of the stored value of type `T` from the state.
31    pub fn get<T>(&self) -> Result<T, DependencyInjectionError>
32    where
33        T: Clone + Send + Sync + 'static,
34    {
35        let map = self.inner.read();
36        let type_name = type_name::<T>().to_string();
37
38        let state_ref = map.get(&TypeId::of::<T>()).ok_or(
39            DependencyInjectionError::DependencyNotFound {
40                type_name: type_name.clone(),
41            },
42        )?;
43
44        state_ref
45            .downcast_ref::<T>()
46            .cloned()
47            .ok_or(DependencyInjectionError::DependencyNotFound { type_name })
48    }
49
50    /// Borrow an `Arc` to the stored value of type `T` from the state.
51    /// This returns an `Arc<T>` without cloning the underlying value.
52    pub fn borrow<T>(&self) -> Result<Arc<T>, DependencyInjectionError>
53    where
54        T: Send + Sync + 'static,
55    {
56        let map = self.inner.read();
57        let type_name = type_name::<T>().to_string();
58
59        let state_ref = map.get(&TypeId::of::<T>()).ok_or(
60            DependencyInjectionError::DependencyNotFound {
61                type_name: type_name.clone(),
62            },
63        )?;
64
65        state_ref
66            .clone()
67            .downcast::<T>()
68            .map_err(|_| DependencyInjectionError::DependencyNotFound { type_name })
69    }
70
71    pub fn insert<T: Send + Sync + 'static>(&self, state: T) {
72        self.inner
73            .write()
74            .insert(TypeId::of::<T>(), Arc::new(state));
75    }
76
77    pub fn insert_instance(
78        &self,
79        type_id: TypeId,
80        instance: Arc<dyn Any + Send + Sync>,
81    ) {
82        self.inner.write().insert(type_id, instance);
83    }
84}
85
86impl Default for State {
87    fn default() -> Self {
88        Self::new()
89    }
90}