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}