Skip to main content

bitwarden_core/platform/
state_client.rs

1use std::sync::Arc;
2
3use bitwarden_state::{
4    Key, Setting, SettingItem, SettingsError,
5    registry::StateRegistryError,
6    repository::{Repository, RepositoryItem},
7};
8
9use crate::Client;
10
11/// Wrapper for state specific functionality.
12pub struct StateClient {
13    pub(crate) client: Client,
14}
15
16impl StateClient {
17    /// Register a client managed state repository for a specific type.
18    pub fn register_client_managed<T: 'static + Repository<V>, V: RepositoryItem>(
19        &self,
20        store: Arc<T>,
21    ) {
22        self.client
23            .internal
24            .state_registry
25            .register_client_managed(store)
26    }
27
28    /// Get a repository with fallback: prefer client-managed, fall back to SDK-managed.
29    ///
30    /// This method first attempts to retrieve a client-managed repository. If not registered,
31    /// it falls back to an SDK-managed repository. Both are returned as `Arc<dyn Repository<T>>`.
32    ///
33    /// # Errors
34    /// Returns `StateRegistryError` when neither repository type is available.
35    pub fn get<T>(&self) -> Result<Arc<dyn Repository<T>>, StateRegistryError>
36    where
37        T: RepositoryItem,
38    {
39        self.client.internal.state_registry.get()
40    }
41
42    /// Get a handle to a setting by its type-safe key.
43    ///
44    /// Returns a [`Setting`] handle that can be used to get, update, or delete the value.
45    ///
46    /// # Example
47    /// ```rust
48    /// use bitwarden_state::register_setting_key;
49    /// use serde::{Deserialize, Serialize};
50    ///
51    /// #[derive(Serialize, Deserialize)]
52    /// struct AppConfig {
53    ///     theme: String,
54    /// }
55    ///
56    /// register_setting_key!(const CONFIG: AppConfig = "app_config");
57    ///
58    /// # async fn example(client: bitwarden_core::Client) -> Result<(), bitwarden_state::SettingsError> {
59    /// let setting = client.platform().state().setting(CONFIG)?;
60    /// let value: Option<AppConfig> = setting.get().await?;
61    /// # Ok(())
62    /// # }
63    /// ```
64    pub fn setting<T>(&self, key: Key<T>) -> Result<Setting<T>, SettingsError> {
65        let repository = self.client.internal.state_registry.get::<SettingItem>()?;
66        Ok(Setting::new(repository, key))
67    }
68}