Skip to main content

homecore_api/
state.rs

1use homecore::HomeCore;
2use homecore_recorder::Recorder;
3use std::sync::Arc;
4
5use crate::tokens::LongLivedTokenStore;
6
7#[derive(Clone)]
8pub struct SharedState {
9    inner: Arc<SharedStateInner>,
10}
11
12struct SharedStateInner {
13    pub homecore: HomeCore,
14    pub homecore_version: String,
15    pub location_name: String,
16    pub tokens: LongLivedTokenStore,
17    pub recorder: Option<Recorder>,
18}
19
20impl SharedState {
21    /// New SharedState with a default empty token store. Use
22    /// [`Self::with_tokens`] to inject one provisioned from env or
23    /// programmatic registration.
24    pub fn new(homecore: HomeCore) -> Self {
25        Self::with_metadata(homecore, "Home", env!("CARGO_PKG_VERSION"))
26    }
27
28    pub fn with_metadata(
29        homecore: HomeCore,
30        location_name: impl Into<String>,
31        homecore_version: impl Into<String>,
32    ) -> Self {
33        // Fail closed by default. Tests and explicitly insecure local
34        // development must opt into `allow_any_non_empty()` themselves.
35        Self::with_tokens(
36            homecore,
37            location_name,
38            homecore_version,
39            LongLivedTokenStore::empty(),
40        )
41    }
42
43    pub fn with_tokens(
44        homecore: HomeCore,
45        location_name: impl Into<String>,
46        homecore_version: impl Into<String>,
47        tokens: LongLivedTokenStore,
48    ) -> Self {
49        Self {
50            inner: Arc::new(SharedStateInner {
51                homecore,
52                homecore_version: homecore_version.into(),
53                location_name: location_name.into(),
54                tokens,
55                recorder: None,
56            }),
57        }
58    }
59
60    pub fn with_recorder(self, recorder: Option<Recorder>) -> Self {
61        Self {
62            inner: Arc::new(SharedStateInner {
63                homecore: self.inner.homecore.clone(),
64                homecore_version: self.inner.homecore_version.clone(),
65                location_name: self.inner.location_name.clone(),
66                tokens: self.inner.tokens.clone(),
67                recorder,
68            }),
69        }
70    }
71
72    pub fn homecore(&self) -> &HomeCore {
73        &self.inner.homecore
74    }
75    pub fn version(&self) -> &str {
76        &self.inner.homecore_version
77    }
78    pub fn location_name(&self) -> &str {
79        &self.inner.location_name
80    }
81    pub fn tokens(&self) -> &LongLivedTokenStore {
82        &self.inner.tokens
83    }
84    pub fn recorder(&self) -> Option<&Recorder> {
85        self.inner.recorder.as_ref()
86    }
87}