bitwarden_state/repository.rs
1use std::any::TypeId;
2
3/// An error resulting from operations on a repository.
4#[derive(thiserror::Error, Debug)]
5pub enum RepositoryError {
6 /// An internal unspecified error.
7 #[error("Internal error: {0}")]
8 Internal(String),
9}
10
11/// This trait represents a generic repository interface, capable of storing and retrieving
12/// items using a key-value API.
13#[async_trait::async_trait]
14pub trait Repository<V: RepositoryItem>: Send + Sync {
15 /// Retrieves an item from the repository by its key.
16 async fn get(&self, key: String) -> Result<Option<V>, RepositoryError>;
17 /// Lists all items in the repository.
18 async fn list(&self) -> Result<Vec<V>, RepositoryError>;
19 /// Sets an item in the repository with the specified key.
20 async fn set(&self, key: String, value: V) -> Result<(), RepositoryError>;
21 /// Removes an item from the repository by its key.
22 async fn remove(&self, key: String) -> Result<(), RepositoryError>;
23}
24
25/// This trait is used to mark types that can be stored in a repository.
26/// It should not be implemented manually; instead, users should
27/// use the [crate::register_repository_item] macro to register their item types.
28pub trait RepositoryItem: Internal + Send + Sync + 'static {
29 /// The name of the type implementing this trait.
30 const NAME: &'static str;
31 /// Returns the `TypeId` of the type implementing this trait.
32 fn type_id() -> TypeId {
33 TypeId::of::<Self>()
34 }
35}
36
37/// Register a type for use in a repository. The type must only be registered once in the crate
38/// where it's defined. The provided name must be unique and not be changed.
39#[macro_export]
40macro_rules! register_repository_item {
41 ($ty:ty, $name:literal) => {
42 const _: () = {
43 impl $crate::repository::___internal::Internal for $ty {}
44 impl $crate::repository::RepositoryItem for $ty {
45 const NAME: &'static str = $name;
46 }
47 };
48 };
49}
50
51/// This code is not meant to be used directly, users of this crate should use the
52/// [crate::register_repository_item] macro to register their types.
53#[doc(hidden)]
54pub mod ___internal {
55
56 // This trait is just to try to discourage users from implementing `RepositoryItem` directly.
57 pub trait Internal {}
58}
59pub(crate) use ___internal::Internal;