matrix_sdk_search/index/
builder.rs1use std::{fs, path::PathBuf, sync::Arc};
2
3use ruma::OwnedRoomId;
4use tantivy::{
5 Index,
6 directory::{MmapDirectory, error::OpenDirectoryError},
7};
8use zeroize::Zeroizing;
9
10use crate::{
11 encrypted::encrypted_dir::{EncryptedMmapDirectory, PBKDF_COUNT},
12 error::IndexError,
13 index::RoomIndex,
14 schema::{MatrixSearchIndexSchema, RoomMessageSchema},
15};
16
17pub struct RoomIndexBuilder {}
19
20impl RoomIndexBuilder {
21 pub fn new_on_disk<R: Into<OwnedRoomId>>(
23 path: PathBuf,
24 room_id: R,
25 ) -> PhysicalRoomIndexBuilder {
26 PhysicalRoomIndexBuilder::new(path, room_id.into())
27 }
28
29 pub fn new_in_memory<R: Into<OwnedRoomId>>(room_id: R) -> MemoryRoomIndexBuilder {
31 MemoryRoomIndexBuilder::new(room_id.into())
32 }
33}
34
35pub struct PhysicalRoomIndexBuilder {
37 path: PathBuf,
38 room_id: OwnedRoomId,
39}
40
41impl PhysicalRoomIndexBuilder {
42 pub(crate) fn new(path: PathBuf, room_id: OwnedRoomId) -> PhysicalRoomIndexBuilder {
44 PhysicalRoomIndexBuilder { path, room_id }
45 }
46
47 pub fn unencrypted(&self) -> UnencryptedPhysicalRoomIndexBuilder {
49 UnencryptedPhysicalRoomIndexBuilder {
50 path: self.path.clone(),
51 room_id: self.room_id.clone(),
52 }
53 }
54
55 pub fn encrypted<P: Into<String>>(&self, password: P) -> EncryptedPhysicalRoomIndexBuilder {
57 EncryptedPhysicalRoomIndexBuilder {
58 path: self.path.clone(),
59 room_id: self.room_id.clone(),
60 password: Zeroizing::new(password.into()),
61 }
62 }
63}
64
65pub struct UnencryptedPhysicalRoomIndexBuilder {
67 path: PathBuf,
68 room_id: OwnedRoomId,
69}
70
71impl UnencryptedPhysicalRoomIndexBuilder {
72 pub fn build(&self) -> Result<RoomIndex, IndexError> {
74 let path = self.path.join(self.room_id.as_str());
75 let mmap_dir = match MmapDirectory::open(path) {
76 Ok(dir) => Ok(dir),
77 Err(err) => match err {
78 OpenDirectoryError::DoesNotExist(path) => {
79 fs::create_dir_all(path.clone()).map_err(|err| {
80 OpenDirectoryError::IoError {
81 io_error: Arc::new(err),
82 directory_path: path.to_path_buf(),
83 }
84 })?;
85 MmapDirectory::open(path)
86 }
87 _ => Err(err),
88 },
89 }?;
90 let schema = RoomMessageSchema::new();
91 let index = Index::open_or_create(mmap_dir, schema.as_tantivy_schema())?;
92 Ok(RoomIndex::new_with(index, schema, &self.room_id))
93 }
94}
95
96pub struct EncryptedPhysicalRoomIndexBuilder {
98 path: PathBuf,
99 room_id: OwnedRoomId,
100 password: Zeroizing<String>,
101}
102
103impl EncryptedPhysicalRoomIndexBuilder {
104 pub fn build(&self) -> Result<RoomIndex, IndexError> {
106 let path = self.path.join(self.room_id.as_str());
107 let mmap_dir =
108 match EncryptedMmapDirectory::open_or_create(path, &self.password, PBKDF_COUNT) {
109 Ok(dir) => Ok(dir),
110 Err(err) => match err {
111 OpenDirectoryError::DoesNotExist(path) => {
112 fs::create_dir_all(path.clone()).map_err(|err| {
113 OpenDirectoryError::IoError {
114 io_error: Arc::new(err),
115 directory_path: path.to_path_buf(),
116 }
117 })?;
118 EncryptedMmapDirectory::open_or_create(path, &self.password, PBKDF_COUNT)
119 }
120 _ => Err(err),
121 },
122 }?;
123 let schema = RoomMessageSchema::new();
124 let index = Index::open_or_create(mmap_dir, schema.as_tantivy_schema())?;
125 Ok(RoomIndex::new_with(index, schema, &self.room_id))
126 }
127}
128
129pub struct MemoryRoomIndexBuilder {
131 room_id: OwnedRoomId,
132}
133
134impl MemoryRoomIndexBuilder {
135 pub(crate) fn new(room_id: OwnedRoomId) -> MemoryRoomIndexBuilder {
137 MemoryRoomIndexBuilder { room_id }
138 }
139
140 pub fn build(&self) -> RoomIndex {
142 let schema = RoomMessageSchema::new();
143 let index = Index::create_in_ram(schema.as_tantivy_schema());
144 RoomIndex::new_with(index, schema, &self.room_id)
145 }
146}