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}