diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index b6492c3f3..3d4c99cdd 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -71,9 +71,9 @@ pub use self::memory_store::MemoryStore; /// State store specific error type. #[derive(Debug, thiserror::Error)] pub enum StoreError { - #[error(transparent)] /// An error happened in the underlying database backend. - Backend(#[from] Box), + #[error(transparent)] + Backend(Box), /// An error happened while serializing or deserializing some data. #[error(transparent)] Json(#[from] serde_json::Error), @@ -107,6 +107,20 @@ pub enum StoreError { #[error("Redaction failed: {0}")] Redaction(#[source] ruma::signatures::Error), } + +impl StoreError { + /// Create a new [`Backend`][Self::Backend] error. + /// + /// Shorthand for `StoreError::Backend(Box::new(error))`. + #[inline] + pub fn backend(error: E) -> Self + where + E: std::error::Error + Send + Sync + 'static, + { + Self::Backend(Box::new(error)) + } +} + /// A `StateStore` specific result type. pub type Result = std::result::Result; diff --git a/crates/matrix-sdk-crypto-ffi/src/machine.rs b/crates/matrix-sdk-crypto-ffi/src/machine.rs index b450ad0d3..65bf6f51e 100644 --- a/crates/matrix-sdk-crypto-ffi/src/machine.rs +++ b/crates/matrix-sdk-crypto-ffi/src/machine.rs @@ -102,7 +102,7 @@ impl OlmMachine { // this. matrix_sdk_sled::OpenStoreError::Crypto(r) => r.into(), matrix_sdk_sled::OpenStoreError::Sled(s) => CryptoStoreError::CryptoStore( - matrix_sdk_crypto::store::CryptoStoreError::Backend(Box::new(s)), + matrix_sdk_crypto::store::CryptoStoreError::backend(s), ), _ => unreachable!(), } diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index 08578e806..e83621d6e 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -625,7 +625,20 @@ pub enum CryptoStoreError { /// A problem with the underlying database backend #[error(transparent)] - Backend(#[from] Box), + Backend(Box), +} + +impl CryptoStoreError { + /// Create a new [`Backend`][Self::Backend] error. + /// + /// Shorthand for `StoreError::Backend(Box::new(error))`. + #[inline] + pub fn backend(error: E) -> Self + where + E: std::error::Error + Send + Sync + 'static, + { + Self::Backend(Box::new(error)) + } } /// Trait abstracting a store that the `OlmMachine` uses to store cryptographic diff --git a/crates/matrix-sdk-indexeddb/src/cryptostore.rs b/crates/matrix-sdk-indexeddb/src/cryptostore.rs index 69d8b468c..d5ae528f3 100644 --- a/crates/matrix-sdk-indexeddb/src/cryptostore.rs +++ b/crates/matrix-sdk-indexeddb/src/cryptostore.rs @@ -120,7 +120,7 @@ impl From for CryptoStoreError { match frm { IndexeddbStoreError::Json(e) => CryptoStoreError::Serialization(e), IndexeddbStoreError::CryptoStoreError(e) => e, - _ => CryptoStoreError::Backend(Box::new(frm)), + _ => CryptoStoreError::backend(frm), } } } @@ -217,9 +217,8 @@ impl IndexeddbStore { Some(key) => StoreCipher::import(passphrase, &key) .map_err(|_| CryptoStoreError::UnpicklingError)?, None => { - let key = StoreCipher::new().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; - let encrypted = - key.export(passphrase).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let key = StoreCipher::new().map_err(CryptoStoreError::backend)?; + let encrypted = key.export(passphrase).map_err(CryptoStoreError::backend)?; let tx: IdbTransaction<'_> = db.transaction_on_one_with_mode( "matrix-sdk-crypto", @@ -246,8 +245,7 @@ impl IndexeddbStore { fn serialize_value(&self, value: &impl Serialize) -> Result { if let Some(key) = &self.store_cipher { - let value = - key.encrypt_value(value).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let value = key.encrypt_value(value).map_err(CryptoStoreError::backend)?; Ok(JsValue::from_serde(&value)?) } else { @@ -261,7 +259,7 @@ impl IndexeddbStore { ) -> Result { if let Some(key) = &self.store_cipher { let value: Vec = value.into_serde()?; - key.decrypt_value(&value).map_err(|e| CryptoStoreError::Backend(Box::new(e))) + key.decrypt_value(&value).map_err(CryptoStoreError::backend) } else { Ok(value.into_serde()?) } diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index 5bd8255c0..055d55c06 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -95,7 +95,7 @@ impl From for StoreError { expected, found )), }, - _ => StoreError::Backend(Box::new(e)), + _ => StoreError::backend(e), } } } diff --git a/crates/matrix-sdk-sled/src/cryptostore.rs b/crates/matrix-sdk-sled/src/cryptostore.rs index db1ed6263..3c616b115 100644 --- a/crates/matrix-sdk-sled/src/cryptostore.rs +++ b/crates/matrix-sdk-sled/src/cryptostore.rs @@ -212,11 +212,8 @@ impl SledStore { passphrase: Option<&str>, ) -> Result { let path = path.as_ref().join("matrix-sdk-crypto"); - let db = Config::new() - .temporary(false) - .path(&path) - .open() - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let db = + Config::new().temporary(false).path(&path).open().map_err(CryptoStoreError::backend)?; let store_cipher = if let Some(passphrase) = passphrase { Some(Self::get_or_create_store_cipher(passphrase, &db)?.into()) @@ -242,7 +239,7 @@ impl SledStore { fn serialize_value(&self, event: &impl Serialize) -> Result, CryptoStoreError> { if let Some(key) = &self.store_cipher { - key.encrypt_value(event).map_err(|e| CryptoStoreError::Backend(Box::new(e))) + key.encrypt_value(event).map_err(CryptoStoreError::backend) } else { Ok(serde_json::to_vec(event)?) } @@ -253,7 +250,7 @@ impl SledStore { event: &[u8], ) -> Result { if let Some(key) = &self.store_cipher { - key.decrypt_value(event).map_err(|e| CryptoStoreError::Backend(Box::new(e))) + key.decrypt_value(event).map_err(CryptoStoreError::backend) } else { Ok(serde_json::from_slice(event)?) } @@ -272,7 +269,7 @@ impl SledStore { .inbound_group_sessions .iter() .map(|p| { - let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let item = p.map_err(CryptoStoreError::backend)?; Ok((item.0, self.deserialize_value(&item.1)?)) }) .collect::>()?; @@ -294,9 +291,9 @@ impl SledStore { Ok(()) }); - ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + ret.map_err(CryptoStoreError::backend)?; - self.inner.flush_async().await.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + self.inner.flush_async().await.map_err(CryptoStoreError::backend)?; Ok(()) } @@ -305,7 +302,7 @@ impl SledStore { let version = self .inner .get("store_version") - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|v| { let (version_bytes, _) = v.split_at(std::mem::size_of::()); u8::from_be_bytes(version_bytes.try_into().unwrap_or_default()) @@ -325,25 +322,23 @@ impl SledStore { self.inner .insert("store_version", DATABASE_VERSION.to_be_bytes().as_ref()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; - self.inner.flush().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + .map_err(CryptoStoreError::backend)?; + self.inner.flush().map_err(CryptoStoreError::backend)?; Ok(()) } fn get_or_create_store_cipher(passphrase: &str, database: &Db) -> Result { - let key = if let Some(key) = database - .get("store_cipher".encode()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + let key = if let Some(key) = + database.get("store_cipher".encode()).map_err(CryptoStoreError::backend)? { StoreCipher::import(passphrase, &key).map_err(|_| CryptoStoreError::UnpicklingError)? } else { - let key = StoreCipher::new().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; - let encrypted = - key.export(passphrase).map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let key = StoreCipher::new().map_err(CryptoStoreError::backend)?; + let encrypted = key.export(passphrase).map_err(CryptoStoreError::backend)?; database .insert("store_cipher".encode(), encrypted) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + .map_err(CryptoStoreError::backend)?; key }; @@ -404,7 +399,7 @@ impl SledStore { async fn load_tracked_users(&self) -> Result<()> { for value in &self.tracked_users { - let (_, user) = value.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let (_, user) = value.map_err(CryptoStoreError::backend)?; let user: TrackedUser = self.deserialize_value(&user)?; self.tracked_users_cache.insert(user.user_id.to_owned()); @@ -425,7 +420,7 @@ impl SledStore { self.outbound_group_sessions .get(self.encode_key(OUTBOUND_GROUP_TABLE_NAME, room_id)) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|p| self.deserialize_value(&p)) .transpose()? .map(|p| { @@ -630,8 +625,8 @@ impl SledStore { }, ); - ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; - self.inner.flush().map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + ret.map_err(CryptoStoreError::backend)?; + self.inner.flush().map_err(CryptoStoreError::backend)?; Ok(()) } @@ -640,14 +635,14 @@ impl SledStore { let request = self .outgoing_secret_requests .get(id) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|r| self.deserialize_value(&r)) .transpose()?; let request = if request.is_none() { self.unsent_secret_requests .get(id) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|r| self.deserialize_value(&r)) .transpose()? } else { @@ -682,17 +677,15 @@ impl SledStore { ); } - self.tracked_users.apply_batch(batch).map_err(|e| CryptoStoreError::Backend(Box::new(e))) + self.tracked_users.apply_batch(batch).map_err(CryptoStoreError::backend) } } #[async_trait] impl CryptoStore for SledStore { async fn load_account(&self) -> Result> { - if let Some(pickle) = self - .account - .get("account".encode()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + if let Some(pickle) = + self.account.get("account".encode()).map_err(CryptoStoreError::backend)? { let pickle = self.deserialize_value(&pickle)?; @@ -718,10 +711,8 @@ impl CryptoStore for SledStore { } async fn load_identity(&self) -> Result> { - if let Some(i) = self - .private_identity - .get("identity".encode()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + if let Some(i) = + self.private_identity.get("identity".encode()).map_err(CryptoStoreError::backend)? { let pickle = self.deserialize_value(&i)?; Ok(Some( @@ -745,11 +736,7 @@ impl CryptoStore for SledStore { let sessions: Result> = self .sessions .scan_prefix(self.encode_key(SESSIONS_TABLE_NAME, sender_key)) - .map(|s| { - self.deserialize_value( - &s.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1, - ) - }) + .map(|s| self.deserialize_value(&s.map_err(CryptoStoreError::backend)?.1)) .map(|p| { Ok(Session::from_pickle( account_info.user_id.clone(), @@ -776,7 +763,7 @@ impl CryptoStore for SledStore { let pickle = self .inbound_group_sessions .get(&key) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|p| self.deserialize_value(&p)); if let Some(pickle) = pickle { @@ -790,9 +777,7 @@ impl CryptoStore for SledStore { let pickles: Result> = self .inbound_group_sessions .iter() - .map(|p| { - self.deserialize_value(&p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1) - }) + .map(|p| self.deserialize_value(&p.map_err(CryptoStoreError::backend)?.1)) .collect(); Ok(pickles?.into_iter().filter_map(|p| InboundGroupSession::from_pickle(p).ok()).collect()) @@ -803,7 +788,7 @@ impl CryptoStore for SledStore { .inbound_group_sessions .iter() .map(|p| { - let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let item = p.map_err(CryptoStoreError::backend)?; self.deserialize_value(&item.1) }) .collect::>()?; @@ -822,7 +807,7 @@ impl CryptoStore for SledStore { .inbound_group_sessions .iter() .map(|p| { - let item = p.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + let item = p.map_err(CryptoStoreError::backend)?; self.deserialize_value(&item.1) }) .filter_map(|p: Result| match p { @@ -893,7 +878,7 @@ impl CryptoStore for SledStore { Ok(self .devices .get(key) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|d| self.deserialize_value(&d)) .transpose()?) } @@ -905,9 +890,7 @@ impl CryptoStore for SledStore { let key = self.encode_key(DEVICE_TABLE_NAME, user_id); self.devices .scan_prefix(key) - .map(|d| { - self.deserialize_value(&d.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1) - }) + .map(|d| self.deserialize_value(&d.map_err(CryptoStoreError::backend)?.1)) .map(|d| { let d: ReadOnlyDevice = d?; Ok((d.device_id().to_owned(), d)) @@ -921,7 +904,7 @@ impl CryptoStore for SledStore { Ok(self .identities .get(key) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|i| self.deserialize_value(&i)) .transpose()?) } @@ -933,7 +916,7 @@ impl CryptoStore for SledStore { Ok(self .olm_hashes .contains_key(serde_json::to_vec(message_hash)?) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))?) + .map_err(CryptoStoreError::backend)?) } async fn get_outgoing_secret_requests( @@ -952,7 +935,7 @@ impl CryptoStore for SledStore { let id = self .secret_requests_by_info .get(self.encode_key(SECRET_REQUEST_BY_INFO_TABLE, key_info)) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + .map_err(CryptoStoreError::backend)?; if let Some(id) = id { self.get_outgoing_key_request_helper(&id).await @@ -965,9 +948,7 @@ impl CryptoStore for SledStore { let requests: Result> = self .unsent_secret_requests .iter() - .map(|i| { - self.deserialize_value(&i.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?.1) - }) + .map(|i| self.deserialize_value(&i.map_err(CryptoStoreError::backend)?.1)) .collect(); requests @@ -1007,8 +988,8 @@ impl CryptoStore for SledStore { }, ); - ret.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; - self.inner.flush_async().await.map_err(|e| CryptoStoreError::Backend(Box::new(e)))?; + ret.map_err(CryptoStoreError::backend)?; + self.inner.flush_async().await.map_err(CryptoStoreError::backend)?; Ok(()) } @@ -1018,14 +999,14 @@ impl CryptoStore for SledStore { let backup_version = self .account .get("backup_version_v1".encode()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|v| self.deserialize_value(&v)) .transpose()?; let recovery_key = { self.account .get("recovery_key_v1".encode()) - .map_err(|e| CryptoStoreError::Backend(Box::new(e)))? + .map_err(CryptoStoreError::backend)? .map(|p| self.deserialize_value(&p)) .transpose()? }; diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 9207d62db..e7f575f2b 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -111,7 +111,7 @@ impl Into for SledStoreError { )), }, SledStoreError::StoreError(e) => e, - _ => StoreError::Backend(Box::new(self)), + _ => StoreError::backend(self), } } } @@ -269,8 +269,7 @@ impl SledStore { } pub fn open() -> StoreResult { - let db = - Config::new().temporary(true).open().map_err(|e| StoreError::Backend(Box::new(e)))?; + let db = Config::new().temporary(true).open().map_err(StoreError::backend)?; SledStore::open_helper(db, None, None).map_err(|e| e.into()) } @@ -278,8 +277,7 @@ impl SledStore { // testing only #[cfg(test)] fn open_encrypted() -> StoreResult { - let db = - Config::new().temporary(true).open().map_err(|e| StoreError::Backend(Box::new(e)))?; + let db = Config::new().temporary(true).open().map_err(StoreError::backend)?; SledStore::open_helper( db, @@ -321,19 +319,18 @@ impl SledStore { } fn upgrade(&self) -> StoreResult<()> { - let db_version = - self.inner.get(VERSION_KEY).map_err(|e| StoreError::Backend(Box::new(e)))?.map(|v| { - let (version_bytes, _) = v.split_at(std::mem::size_of::()); - u8::from_be_bytes(version_bytes.try_into().unwrap_or_default()) - }); + let db_version = self.inner.get(VERSION_KEY).map_err(StoreError::backend)?.map(|v| { + let (version_bytes, _) = v.split_at(std::mem::size_of::()); + u8::from_be_bytes(version_bytes.try_into().unwrap_or_default()) + }); let old_version = match db_version { None => { // we are fresh, let's write the current version self.inner .insert(VERSION_KEY, DATABASE_VERSION.to_be_bytes().as_ref()) - .map_err(|e| StoreError::Backend(Box::new(e)))?; - self.inner.flush().map_err(|e| StoreError::Backend(Box::new(e)))?; + .map_err(StoreError::backend)?; + self.inner.flush().map_err(StoreError::backend)?; return Ok(()); } Some(version) if version == DATABASE_VERSION => { @@ -789,14 +786,12 @@ impl SledStore { let key = self.encode_key(INVITED_USER_ID, room_id); spawn_blocking(move || { stream::iter(db.invited_user_ids.scan_prefix(key).map(|u| { - UserId::parse(String::from_utf8_lossy( - &u.map_err(|e| StoreError::Backend(Box::new(e)))?.1, - )) - .map_err(StoreError::Identifier) + UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1)) + .map_err(StoreError::Identifier) })) }) .await - .map_err(|e| StoreError::Backend(Box::new(e))) + .map_err(StoreError::backend) } pub async fn get_joined_user_ids( @@ -807,14 +802,12 @@ impl SledStore { let key = self.encode_key(JOINED_USER_ID, room_id); spawn_blocking(move || { stream::iter(db.joined_user_ids.scan_prefix(key).map(|u| { - UserId::parse(String::from_utf8_lossy( - &u.map_err(|e| StoreError::Backend(Box::new(e)))?.1, - )) - .map_err(StoreError::Identifier) + UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1)) + .map_err(StoreError::Identifier) })) }) .await - .map_err(|e| StoreError::Backend(Box::new(e))) + .map_err(StoreError::backend) } pub async fn get_stripped_invited_user_ids( @@ -825,14 +818,12 @@ impl SledStore { let key = self.encode_key(STRIPPED_INVITED_USER_ID, room_id); spawn_blocking(move || { stream::iter(db.stripped_invited_user_ids.scan_prefix(key).map(|u| { - UserId::parse(String::from_utf8_lossy( - &u.map_err(|e| StoreError::Backend(Box::new(e)))?.1, - )) - .map_err(StoreError::Identifier) + UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1)) + .map_err(StoreError::Identifier) })) }) .await - .map_err(|e| StoreError::Backend(Box::new(e))) + .map_err(StoreError::backend) } pub async fn get_stripped_joined_user_ids( @@ -843,14 +834,12 @@ impl SledStore { let key = self.encode_key(STRIPPED_JOINED_USER_ID, room_id); spawn_blocking(move || { stream::iter(db.stripped_joined_user_ids.scan_prefix(key).map(|u| { - UserId::parse(String::from_utf8_lossy( - &u.map_err(|e| StoreError::Backend(Box::new(e)))?.1, - )) - .map_err(StoreError::Identifier) + UserId::parse(String::from_utf8_lossy(&u.map_err(StoreError::backend)?.1)) + .map_err(StoreError::Identifier) })) }) .await - .map_err(|e| StoreError::Backend(Box::new(e))) + .map_err(StoreError::backend) } pub async fn get_room_infos(&self) -> Result>> { @@ -941,13 +930,13 @@ impl SledStore { .scan_prefix(key) .values() .map(|u| { - let v = u.map_err(|e| StoreError::Backend(Box::new(e)))?; - db.deserialize_event(&v).map_err(|e| StoreError::Backend(Box::new(e))) + let v = u.map_err(StoreError::backend)?; + db.deserialize_event(&v).map_err(StoreError::backend) }) .collect() }) .await - .map_err(|e| StoreError::Backend(Box::new(e)))? + .map_err(StoreError::backend)? } async fn add_media_content(&self, request: &MediaRequest, data: Vec) -> Result<()> { diff --git a/crates/matrix-sdk/src/event_handler.rs b/crates/matrix-sdk/src/event_handler.rs index 9567d6f04..444a18bbd 100644 --- a/crates/matrix-sdk/src/event_handler.rs +++ b/crates/matrix-sdk/src/event_handler.rs @@ -494,13 +494,20 @@ mod static_events { (EventKind::MessageLike, events::room::redaction::RoomRedactionEventContent::TYPE); } - impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent { + impl SyncEvent for events::room::redaction::OriginalSyncRoomRedactionEvent { const ID: (EventKind, &'static str) = ( EventKind::OriginalMessageLike, events::room::redaction::RoomRedactionEventContent::TYPE, ); } + impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent { + const ID: (EventKind, &'static str) = ( + EventKind::RedactedMessageLike, + events::room::redaction::RoomRedactionEventContent::TYPE, + ); + } + impl SyncEvent for events::SyncStateEvent where C: StaticEventContent + StateEventContent + RedactContent,