bitwarden_state/persisted_value/key.rs
1//! Type-safe keys for persisted values storage.
2
3use super::Internal;
4use crate::Persist;
5
6/// Register a type-safe persisted value key.
7///
8/// This macro is the primary way to create persisted value keys. It associates
9/// a string key name with a value type at compile time.
10///
11/// **Important:** The key name must be globally unique across the entire application.
12/// Using the same key name for different persisted values will cause conflicts. It may contain
13/// only ASCII letters and underscores, which is checked at compile time.
14///
15/// # Example
16/// ```rust
17/// use bitwarden_state::register_persisted_value;
18/// use serde::{Deserialize, Serialize};
19///
20/// #[derive(Serialize, Deserialize)]
21/// struct AppConfig {
22/// theme: String,
23/// auto_save: bool,
24/// }
25///
26/// register_persisted_value!(CONFIG: AppConfig = "app_config");
27/// ```
28#[macro_export]
29macro_rules! register_persisted_value {
30 ($(#[$meta:meta])* $vis:vis $name:ident: $ty:ty = $key:literal) => {
31 // The key is a marker type named like a constant, and is never constructed.
32 $(#[$meta])*
33 #[allow(non_camel_case_types, dead_code, clippy::upper_case_acronyms)]
34 #[derive(Debug, Clone, Copy)]
35 $vis struct $name {}
36
37 const _: () = {
38 impl $crate::persisted_value::___internal::Internal for $name {}
39 impl $crate::persisted_value::PersistedValueKey for $name {
40 const NAME: &'static str = $key;
41 type Value = $ty;
42 }
43 assert!(
44 $crate::repository::validate_registry_name($key),
45 concat!(
46 "Persisted value key '",
47 $key,
48 "' must contain only alphabetic characters and underscores"
49 )
50 )
51 };
52 };
53}
54
55/// Type-safe key for persisted values storage.
56///
57/// Associates a string key name with a value type at compile time,
58/// preventing type mismatches while maintaining ergonomic usage.
59///
60/// Use the [`register_persisted_value!`](crate::register_persisted_value) macro to create keys.
61///
62/// # Example
63/// ```rust
64/// use bitwarden_state::register_persisted_value;
65/// use serde::{Deserialize, Serialize};
66///
67/// #[derive(Serialize, Deserialize)]
68/// struct AppConfig {
69/// theme: String,
70/// auto_save: bool,
71/// }
72///
73/// register_persisted_value!(CONFIG: AppConfig = "app_config");
74/// ```
75pub trait PersistedValueKey: Internal + Send + Sync + 'static {
76 /// The key name the value is stored under.
77 const NAME: &'static str;
78
79 /// The type stored under this key.
80 type Value: Persist;
81}