core_crypto_keystore/traits/
entity.rs

1use std::borrow::Borrow;
2
3use async_trait::async_trait;
4
5use crate::{
6    CryptoKeystoreResult,
7    traits::{EntityBase, KeyType},
8};
9
10/// Something which can be stored in our database.
11///
12/// It has a primary key, which uniquely identifies it.
13#[cfg_attr(target_family = "wasm", async_trait(?Send))]
14#[cfg_attr(not(target_family = "wasm"), async_trait)]
15pub trait Entity: EntityBase {
16    /// Each distinct `PrimaryKey` uniquely identifies either 0 or 1 instance.
17    ///
18    /// This constraint should be enforced at the DB level.
19    type PrimaryKey: KeyType;
20
21    /// Get this entity's primary key.
22    ///
23    /// This must return an owned type, because there are some entities for which only owned primary keys are possible.
24    /// However, entities which have primary keys owned within the entity itself should consider also implementing
25    /// [`BorrowPrimaryKey`] for greater efficiency.
26    fn primary_key(&self) -> Self::PrimaryKey;
27
28    /// Get an entity by its primary key.
29    ///
30    /// For entites whose primary key has a distinct borrowed type, it is best to implement this as a direct
31    /// passthrough:
32    ///
33    /// ```rust,ignore
34    /// async fn get(conn: &mut Self::ConnectionType, key: &Self::PrimaryKey) -> CoreCryptoKeystoreResult<Option<Self>> {
35    ///     Self::get_borrowed(conn, key).await
36    /// }
37    /// ```
38    async fn get(conn: &mut Self::ConnectionType, key: &Self::PrimaryKey) -> CryptoKeystoreResult<Option<Self>>;
39
40    /// Count the number of entities of this type in the database.
41    async fn count(conn: &mut Self::ConnectionType) -> CryptoKeystoreResult<u32>;
42
43    /// Retrieve all entities of this type from the database.
44    async fn load_all(conn: &mut Self::ConnectionType) -> CryptoKeystoreResult<Vec<Self>>;
45}
46
47/// An extension trait which should be implemented for all entities whose primary key has a distinct borrowed form.
48///
49/// i.e. `String`, `Vec<u8>`, etc.
50#[cfg_attr(target_family = "wasm", async_trait(?Send))]
51#[cfg_attr(not(target_family = "wasm"), async_trait)]
52pub trait BorrowPrimaryKey: Entity {
53    type BorrowedPrimaryKey: ?Sized + ToOwned<Owned = Self::PrimaryKey>;
54
55    /// Borrow this entity's primary key without copying any data.
56    ///
57    /// This borrowed key has a lifetime tied to that of this entity.
58    fn borrow_primary_key(&self) -> &Self::BorrowedPrimaryKey;
59
60    /// Get an entity by a borrowed form of its primary key.
61    ///
62    /// The type signature here is somewhat complicated, but it breaks down simply: if our primary key is something
63    /// like `Vec<u8>`, we want to be able to use this method even if what we have on hand is `&[u8]`.
64    async fn get_borrowed<Q>(conn: &mut Self::ConnectionType, key: &Q) -> CryptoKeystoreResult<Option<Self>>
65    where
66        Self::PrimaryKey: Borrow<Q>,
67        Q: KeyType;
68}