matrix_sdk_indexeddb/media_store/
builder.rs

1// Copyright 2025 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
15use std::{rc::Rc, sync::Arc};
16
17use matrix_sdk_base::media::store::MediaService;
18use matrix_sdk_store_encryption::StoreCipher;
19
20use crate::{
21    media_store::{
22        IndexeddbMediaStore, error::IndexeddbMediaStoreError, migrations::open_and_upgrade_db,
23    },
24    serializer::{indexed_type::IndexedTypeSerializer, safe_encode::types::SafeEncodeSerializer},
25};
26
27/// A type for conveniently building an [`IndexeddbMediaStore`]
28pub struct IndexeddbMediaStoreBuilder {
29    // The name of the IndexedDB database which will be opened
30    database_name: String,
31    // The store cipher, if any, to use when encrypting data
32    // before it is persisted to the IndexedDB database
33    store_cipher: Option<Arc<StoreCipher>>,
34}
35
36impl Default for IndexeddbMediaStoreBuilder {
37    fn default() -> Self {
38        Self { database_name: Self::DEFAULT_DATABASE_NAME.to_owned(), store_cipher: None }
39    }
40}
41
42impl IndexeddbMediaStoreBuilder {
43    /// The default name of the IndexedDB database used to back the
44    /// [`IndexeddbMediaStore`]
45    pub const DEFAULT_DATABASE_NAME: &'static str = "media";
46
47    /// Create a new [`IndexeddbMediaStoreBuilder`] where the database name is
48    /// constructed by joining the given prefix with
49    /// [`Self::DEFAULT_DATABASE_NAME`] and separated by `::`.
50    pub fn with_prefix(prefix: &str) -> Self {
51        Self {
52            database_name: format!("{}::{}", prefix, Self::DEFAULT_DATABASE_NAME),
53            store_cipher: None,
54        }
55    }
56
57    /// Sets the name of the IndexedDB database which will be opened. This
58    /// defaults to [`Self::DEFAULT_DATABASE_NAME`].
59    pub fn database_name(mut self, name: String) -> Self {
60        self.database_name = name;
61        self
62    }
63
64    /// Sets the store cipher to use when encrypting data before it is persisted
65    /// to the IndexedDB database. By default, no store cipher is used -
66    /// i.e., data is not encrypted before it is persisted.
67    pub fn store_cipher(mut self, store_cipher: Arc<StoreCipher>) -> Self {
68        self.store_cipher = Some(store_cipher);
69        self
70    }
71
72    /// Opens the IndexedDB database with the provided name. If successfully
73    /// opened, builds the [`IndexeddbMediaStore`] with that database
74    /// and the provided store cipher.
75    pub async fn build(self) -> Result<IndexeddbMediaStore, IndexeddbMediaStoreError> {
76        Ok(IndexeddbMediaStore {
77            inner: Rc::new(open_and_upgrade_db(&self.database_name).await?),
78            serializer: IndexedTypeSerializer::new(SafeEncodeSerializer::new(self.store_cipher)),
79            media_service: MediaService::new(),
80        })
81    }
82}