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;