matrix_sdk_sled/
lib.rs

1#[cfg(any(feature = "state-store", feature = "crypto-store"))]
2use matrix_sdk_base::store::StoreConfig;
3#[cfg(feature = "state-store")]
4use matrix_sdk_base::store::StoreError;
5#[cfg(feature = "crypto-store")]
6use matrix_sdk_crypto::store::CryptoStoreError;
7use sled::Error as SledError;
8use thiserror::Error;
9
10#[cfg(feature = "crypto-store")]
11mod crypto_store;
12mod encode_key;
13#[cfg(feature = "state-store")]
14mod state_store;
15
16#[cfg(feature = "crypto-store")]
17pub use crypto_store::SledCryptoStore;
18#[cfg(feature = "state-store")]
19pub use state_store::{MigrationConflictStrategy, SledStateStore, SledStateStoreBuilder};
20
21/// All the errors that can occur when opening a sled store.
22#[derive(Error, Debug)]
23#[non_exhaustive]
24pub enum OpenStoreError {
25    /// An error occurred with the state store implementation.
26    #[cfg(feature = "state-store")]
27    #[error(transparent)]
28    State(#[from] StoreError),
29
30    /// An error occurred with the crypto store implementation.
31    #[cfg(feature = "crypto-store")]
32    #[error(transparent)]
33    Crypto(#[from] CryptoStoreError),
34
35    /// An error occurred with sled.
36    #[error(transparent)]
37    Sled(#[from] SledError),
38}
39
40/// Create a [`StoreConfig`] with an opened [`SledStateStore`] that uses the
41/// given path and passphrase.
42///
43/// If the `e2e-encryption` Cargo feature is enabled, a [`SledCryptoStore`] with
44/// the same parameters is also opened.
45///
46/// [`StoreConfig`]: #StoreConfig
47#[cfg(any(feature = "state-store", feature = "crypto-store"))]
48pub fn make_store_config(
49    path: impl AsRef<std::path::Path>,
50    passphrase: Option<&str>,
51) -> Result<StoreConfig, OpenStoreError> {
52    #[cfg(all(feature = "crypto-store", feature = "state-store"))]
53    {
54        let (state_store, crypto_store) = open_stores_with_path(path, passphrase)?;
55        Ok(StoreConfig::new().state_store(state_store).crypto_store(crypto_store))
56    }
57
58    #[cfg(all(feature = "crypto-store", not(feature = "state-store")))]
59    {
60        let crypto_store = SledCryptoStore::open_with_passphrase(path, passphrase)?;
61        Ok(StoreConfig::new().crypto_store(crypto_store))
62    }
63
64    #[cfg(not(feature = "crypto-store"))]
65    {
66        let mut store_builder = SledStateStore::builder();
67        store_builder.path(path.as_ref().to_path_buf());
68
69        if let Some(passphrase) = passphrase {
70            store_builder.passphrase(passphrase.to_owned());
71        };
72        let state_store = store_builder.build().map_err(StoreError::backend)?;
73
74        Ok(StoreConfig::new().state_store(state_store))
75    }
76}
77
78/// Create a [`StateStore`] and a [`CryptoStore`] that use the same database and
79/// passphrase.
80#[cfg(all(feature = "state-store", feature = "crypto-store"))]
81fn open_stores_with_path(
82    path: impl AsRef<std::path::Path>,
83    passphrase: Option<&str>,
84) -> Result<(SledStateStore, SledCryptoStore), OpenStoreError> {
85    let mut store_builder = SledStateStore::builder();
86    store_builder.path(path.as_ref().to_path_buf());
87
88    if let Some(passphrase) = passphrase {
89        store_builder.passphrase(passphrase.to_owned());
90    }
91
92    let state_store = store_builder.build().map_err(StoreError::backend)?;
93    let crypto_store = state_store.open_crypto_store()?;
94    Ok((state_store, crypto_store))
95}