matrix_sdk_redis/
lib.rs

1// Copyright 2022 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[cfg(all(test, feature = "crypto-store"))]
16mod fake_redis;
17#[cfg(feature = "crypto-store")]
18mod real_redis;
19#[cfg(feature = "crypto-store")]
20mod redis_crypto_store;
21#[cfg(feature = "crypto-store")]
22mod redis_shim;
23
24#[cfg(any(feature = "state-store", feature = "crypto-store"))]
25use matrix_sdk_base::store::StoreConfig;
26#[cfg(feature = "state-store")]
27use matrix_sdk_base::store::StoreError;
28#[cfg(feature = "crypto-store")]
29use matrix_sdk_crypto::store::CryptoStoreError;
30use redis::RedisError;
31#[cfg(feature = "crypto-store")]
32pub use redis_crypto_store::RedisStore as CryptoStore;
33#[cfg(feature = "crypto-store")]
34use redis_crypto_store::RedisStore;
35use thiserror::Error;
36
37/// All the errors that can occur when opening a redis store.
38#[derive(Error, Debug)]
39#[non_exhaustive]
40pub enum OpenStoreError {
41    /// An error occurred with the state store implementation.
42    #[cfg(feature = "state-store")]
43    #[error(transparent)]
44    State(#[from] StoreError),
45
46    /// An error occurred with the crypto store implementation.
47    #[cfg(feature = "crypto-store")]
48    #[error(transparent)]
49    Crypto(#[from] CryptoStoreError),
50
51    /// An error occurred with redis.
52    #[error(transparent)]
53    Redis(#[from] RedisError),
54}
55
56/// Create a [`StoreConfig`].
57///
58/// If the `e2e-encryption` Cargo feature is enabled, a [`CryptoStore`] is
59/// opened.
60///
61/// [`StoreConfig`]: #StoreConfig
62#[cfg(any(feature = "state-store", feature = "crypto-store"))]
63pub async fn make_store_config(
64    redis_url: &str,
65    passphrase: Option<&str>,
66    redis_prefix: &str,
67) -> Result<StoreConfig, OpenStoreError> {
68    #[cfg(all(feature = "crypto-store", feature = "state-store"))]
69    {
70        panic!("Currently don't have a Redis state store!");
71
72        let underlying_client = redis::Client::open(redis_url).unwrap();
73        let client = RealRedisClient::from(underlying_client);
74        let crypto_store =
75            RedisStore::open(client, passphrase, String::from(redis_prefix))
76                .await?;
77        // TODO: state_store
78        Ok(StoreConfig::new("arnie".to_owned())
79            .state_store(state_store)
80            .crypto_store(crypto_store))
81    }
82
83    #[cfg(all(feature = "crypto-store", not(feature = "state-store")))]
84    {
85        let client = redis::Client::open(redis_url).unwrap();
86        let crypto_store =
87            RedisStore::open(client, passphrase, String::from(redis_prefix))
88                .await?;
89        Ok(StoreConfig::new("arnie".to_owned()).crypto_store(crypto_store))
90    }
91
92    #[cfg(not(feature = "crypto-store"))]
93    {
94        panic!("Currently don't have a Redis state store!");
95
96        let mut store_builder = RedisStateStore::builder();
97        store_builder.path(path.as_ref().to_path_buf());
98
99        if let Some(passphrase) = passphrase {
100            store_builder.passphrase(passphrase.to_owned());
101        }
102        let state_store = store_builder.build().map_err(StoreError::backend)?;
103
104        Ok(StoreConfig::new("arnie".to_owned()).state_store(state_store))
105    }
106}