From 4931c0749e2b534785ade0c2b8e0213291a64458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= <76261501+zecakeh@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:59:26 +0200 Subject: [PATCH] Upgrade Ruma again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch updates our `Raw` API usage since the newly added `JsonCastable` that disallows Raw casts that are known to fail deserialization. Signed-off-by: Kévin Commaille --- Cargo.lock | 16 +++---- Cargo.toml | 4 +- .../src/notification_settings.rs | 4 +- crates/matrix-sdk-base/src/client.rs | 2 +- .../src/deserialized_responses.rs | 4 +- crates/matrix-sdk-base/src/latest_event.rs | 3 +- .../src/response_processors/changes.rs | 2 +- .../src/response_processors/e2ee/decrypt.rs | 2 +- .../src/response_processors/latest_event.rs | 2 +- .../src/response_processors/state_events.rs | 2 +- .../src/response_processors/timeline.rs | 8 ++-- .../matrix-sdk-base/src/room/display_name.rs | 2 +- crates/matrix-sdk-base/src/room/room_info.rs | 6 +-- crates/matrix-sdk-base/src/room/tags.rs | 8 ++-- crates/matrix-sdk-base/src/sliding_sync.rs | 14 +++--- .../src/store/integration_tests.rs | 9 ++-- .../matrix-sdk-base/src/store/memory_store.rs | 46 ++++++++++--------- crates/matrix-sdk-base/src/store/mod.rs | 8 +++- crates/matrix-sdk-base/src/store/traits.rs | 7 ++- crates/matrix-sdk-base/src/sync.rs | 4 +- .../src/deserialized_responses.rs | 17 +++---- crates/matrix-sdk-common/src/serde_helpers.rs | 16 +++---- .../src/gossiping/machine.rs | 2 +- .../src/identities/manager.rs | 6 +-- crates/matrix-sdk-crypto/src/lib.rs | 2 +- crates/matrix-sdk-crypto/src/machine/mod.rs | 4 +- .../src/machine/test_helpers.rs | 3 +- .../src/machine/tests/mod.rs | 8 ++-- .../src/machine/tests/olm_encryption.rs | 4 +- .../src/session_manager/group_sessions/mod.rs | 8 ++-- crates/matrix-sdk-crypto/src/types/backup.rs | 5 ++ .../src/types/cross_signing/common.rs | 7 ++- .../src/types/cross_signing/mod.rs | 4 +- .../src/types/device_keys.rs | 5 +- .../src/types/events/room/encrypted.rs | 11 ++++- .../src/types/events/room_key_request.rs | 7 ++- .../src/types/events/room_key_withheld.rs | 4 +- .../src/types/events/to_device.rs | 6 ++- .../src/types/one_time_keys.rs | 2 +- .../src/state_store/migrations.rs | 16 ++++--- .../src/state_store/mod.rs | 22 +++++---- crates/matrix-sdk-sqlite/src/state_store.rs | 4 +- .../matrix-sdk-ui/src/notification_client.rs | 7 +-- .../event_item/content/pinned_events.rs | 2 +- .../src/timeline/event_item/mod.rs | 2 +- .../matrix-sdk-ui/src/timeline/tests/edit.rs | 8 ++-- .../src/timeline/tests/redaction.rs | 2 +- crates/matrix-sdk-ui/src/timeline/traits.rs | 4 +- .../tests/integration/notification_client.rs | 10 ++-- .../integration/timeline/pinned_event.rs | 5 +- crates/matrix-sdk/src/account.rs | 6 +-- .../matrix-sdk/src/encryption/recovery/mod.rs | 5 +- .../encryption/secret_storage/secret_store.rs | 5 +- crates/matrix-sdk/src/encryption/tasks.rs | 8 ++-- crates/matrix-sdk/src/event_cache/room/mod.rs | 6 +-- crates/matrix-sdk/src/event_handler/mod.rs | 9 ++-- crates/matrix-sdk/src/room/mod.rs | 18 ++++---- crates/matrix-sdk/src/test_utils/mocks/mod.rs | 3 +- crates/matrix-sdk/src/utils/mod.rs | 4 +- crates/matrix-sdk/src/widget/filter.rs | 14 ++++-- crates/matrix-sdk/src/widget/machine/mod.rs | 4 +- crates/matrix-sdk/src/widget/matrix.rs | 13 +++--- crates/matrix-sdk/tests/integration/client.rs | 6 +-- .../tests/integration/encryption/backups.rs | 6 +-- .../integration/encryption/shared_history.rs | 6 +-- .../tests/integration/encryption/to_device.rs | 8 ++-- .../tests/integration/event_cache/mod.rs | 2 +- .../tests/integration/notification.rs | 4 +- crates/matrix-sdk/tests/integration/widget.rs | 2 +- .../src/tests/e2ee/mod.rs | 6 +-- testing/matrix-sdk-test/src/event_factory.rs | 8 ++-- testing/matrix-sdk-test/src/lib.rs | 10 ++-- 72 files changed, 288 insertions(+), 221 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5acaa8cf..576b78a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4483,7 +4483,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.12.5" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "assign", "js_int", @@ -4499,7 +4499,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.20.4" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "as_variant", "assign", @@ -4522,7 +4522,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.15.4" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "as_variant", "base64", @@ -4555,7 +4555,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.30.4" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "as_variant", "indexmap", @@ -4581,7 +4581,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.11.2" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "headers", "http", @@ -4599,7 +4599,7 @@ dependencies = [ [[package]] name = "ruma-html" version = "0.4.1" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "as_variant", "html5ever", @@ -4610,7 +4610,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.10.1" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "js_int", "thiserror 2.0.11", @@ -4619,7 +4619,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.15.2" -source = "git+https://github.com/ruma/ruma?rev=a3663c04511f79f99376924d739f84d839600de6#a3663c04511f79f99376924d739f84d839600de6" +source = "git+https://github.com/ruma/ruma?rev=7bae3d0c0b8edf008899ac2b04cf9722182eef68#7bae3d0c0b8edf008899ac2b04cf9722182eef68" dependencies = [ "cfg-if", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 56fd7429d..91b2cb18c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ proptest = { version = "1.6.0", default-features = false, features = ["std"] } rand = "0.8.5" reqwest = { version = "0.12.12", default-features = false } rmp-serde = "1.3.0" -ruma = { git = "https://github.com/ruma/ruma", rev = "a3663c04511f79f99376924d739f84d839600de6", features = [ +ruma = { git = "https://github.com/ruma/ruma", rev = "7bae3d0c0b8edf008899ac2b04cf9722182eef68", features = [ "client-api-c", "compat-upload-signatures", "compat-arbitrary-length-ids", @@ -77,7 +77,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "a3663c04511f79f99376924d73 "unstable-msc4278", "unstable-msc4286", ] } -ruma-common = { git = "https://github.com/ruma/ruma", rev = "a3663c04511f79f99376924d739f84d839600de6" } +ruma-common = { git = "https://github.com/ruma/ruma", rev = "7bae3d0c0b8edf008899ac2b04cf9722182eef68" } sentry = "0.36.0" sentry-tracing = "0.36.0" serde = { version = "1.0.217", features = ["rc"] } diff --git a/bindings/matrix-sdk-ffi/src/notification_settings.rs b/bindings/matrix-sdk-ffi/src/notification_settings.rs index 0e0b23424..9cce328bf 100644 --- a/bindings/matrix-sdk-ffi/src/notification_settings.rs +++ b/bindings/matrix-sdk-ffi/src/notification_settings.rs @@ -172,7 +172,7 @@ impl TryFrom for PushCondition { Self::RoomMemberCount { prefix: is.prefix.into(), count: is.count.into() } } SdkPushCondition::SenderNotificationPermission { key } => { - Self::SenderNotificationPermission { key } + Self::SenderNotificationPermission { key: key.to_string() } } SdkPushCondition::EventPropertyIs { key, value } => { Self::EventPropertyIs { key, value: value.into() } @@ -197,7 +197,7 @@ impl From for SdkPushCondition { }, }, PushCondition::SenderNotificationPermission { key } => { - Self::SenderNotificationPermission { key } + Self::SenderNotificationPermission { key: key.into() } } PushCondition::EventPropertyIs { key, value } => { Self::EventPropertyIs { key, value: value.into() } diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 84b248265..1c0de9137 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -1040,7 +1040,7 @@ impl BaseClient { ) -> Result { if let Some(event) = global_account_data_processor .push_rules() - .and_then(|ev| ev.deserialize_as::().ok()) + .and_then(|ev| ev.deserialize_as_unchecked::().ok()) { Ok(event.content.global) } else if let Some(event) = self diff --git a/crates/matrix-sdk-base/src/deserialized_responses.rs b/crates/matrix-sdk-base/src/deserialized_responses.rs index 022cbe4fc..f812ffc04 100644 --- a/crates/matrix-sdk-base/src/deserialized_responses.rs +++ b/crates/matrix-sdk-base/src/deserialized_responses.rs @@ -304,8 +304,8 @@ impl RawAnySyncOrStrippedState { C::Redacted: RedactedStateEventContent, { match self { - Self::Sync(raw) => RawSyncOrStrippedState::Sync(raw.cast()), - Self::Stripped(raw) => RawSyncOrStrippedState::Stripped(raw.cast()), + Self::Sync(raw) => RawSyncOrStrippedState::Sync(raw.cast_unchecked()), + Self::Stripped(raw) => RawSyncOrStrippedState::Stripped(raw.cast_unchecked()), } } } diff --git a/crates/matrix-sdk-base/src/latest_event.rs b/crates/matrix-sdk-base/src/latest_event.rs index a5c18531c..049258da2 100644 --- a/crates/matrix-sdk-base/src/latest_event.rs +++ b/crates/matrix-sdk-base/src/latest_event.rs @@ -345,7 +345,6 @@ mod tests { AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent, EmptyStateKey, Mentions, MessageLikeUnsigned, OriginalSyncMessageLikeEvent, OriginalSyncStateEvent, RedactedSyncMessageLikeEvent, RedactedUnsigned, StateUnsigned, SyncMessageLikeEvent, - UnsignedRoomRedactionEvent, }, owned_event_id, owned_mxc_uri, owned_user_id, MilliSecondsSinceUnixEpoch, UInt, VoipVersionId, @@ -501,7 +500,7 @@ mod tests { #[test] fn test_redacted_messages_are_suitable() { // Ruma does not allow constructing UnsignedRoomRedactionEvent instances. - let room_redaction_event: UnsignedRoomRedactionEvent = serde_json::from_value(json!({ + let room_redaction_event = serde_json::from_value(json!({ "content": {}, "event_id": "$redaction", "sender": "@x:y.za", diff --git a/crates/matrix-sdk-base/src/response_processors/changes.rs b/crates/matrix-sdk-base/src/response_processors/changes.rs index 304b057af..aacb836f9 100644 --- a/crates/matrix-sdk-base/src/response_processors/changes.rs +++ b/crates/matrix-sdk-base/src/response_processors/changes.rs @@ -80,7 +80,7 @@ fn apply_changes( if let Some(event) = context.state_changes.account_data.get(&GlobalAccountDataEventType::IgnoredUserList) { - match event.deserialize_as::() { + match event.deserialize_as_unchecked::() { Ok(event) => { let user_ids: Vec = event.content.ignored_users.keys().map(|id| id.to_string()).collect(); diff --git a/crates/matrix-sdk-base/src/response_processors/e2ee/decrypt.rs b/crates/matrix-sdk-base/src/response_processors/e2ee/decrypt.rs index 66f822878..dd8adcbb3 100644 --- a/crates/matrix-sdk-base/src/response_processors/e2ee/decrypt.rs +++ b/crates/matrix-sdk-base/src/response_processors/e2ee/decrypt.rs @@ -35,7 +35,7 @@ pub async fn sync_timeline_event( Ok(Some( match olm - .try_decrypt_room_event(event.cast_ref(), room_id, e2ee.decryption_settings) + .try_decrypt_room_event(event.cast_ref_unchecked(), room_id, e2ee.decryption_settings) .await? { RoomEventDecryptionResult::Decrypted(decrypted) => { diff --git a/crates/matrix-sdk-base/src/response_processors/latest_event.rs b/crates/matrix-sdk-base/src/response_processors/latest_event.rs index 124e1f3de..283bfccee 100644 --- a/crates/matrix-sdk-base/src/response_processors/latest_event.rs +++ b/crates/matrix-sdk-base/src/response_processors/latest_event.rs @@ -111,7 +111,7 @@ async fn decrypt_sync_room_event( let event = match e2ee .olm_machine .expect("An `OlmMachine` is expected") - .try_decrypt_room_event(event.cast_ref(), room_id, e2ee.decryption_settings) + .try_decrypt_room_event(event.cast_ref_unchecked(), room_id, e2ee.decryption_settings) .await? { RoomEventDecryptionResult::Decrypted(decrypted) => { diff --git a/crates/matrix-sdk-base/src/response_processors/state_events.rs b/crates/matrix-sdk-base/src/response_processors/state_events.rs index 098d557ec..2a5c0622f 100644 --- a/crates/matrix-sdk-base/src/response_processors/state_events.rs +++ b/crates/matrix-sdk-base/src/response_processors/state_events.rs @@ -64,7 +64,7 @@ pub mod sync { super::collect(raw_events.iter().filter_map(|raw_event| { // Only state events have a `state_key` field. match raw_event.get_field::<&str>("state_key") { - Ok(Some(_)) => Some(raw_event.cast_ref()), + Ok(Some(_)) => Some(raw_event.cast_ref_unchecked()), _ => None, } })) diff --git a/crates/matrix-sdk-base/src/response_processors/timeline.rs b/crates/matrix-sdk-base/src/response_processors/timeline.rs index a9a88a2b5..f3d75700f 100644 --- a/crates/matrix-sdk-base/src/response_processors/timeline.rs +++ b/crates/matrix-sdk-base/src/response_processors/timeline.rs @@ -69,13 +69,15 @@ pub async fn build<'notification, 'e2ee>( let redaction_rules = room_info.room_version_rules_or_default().redaction; if let Some(redacts) = redaction_event.redacts(&redaction_rules) { - room_info - .handle_redaction(redaction_event, timeline_event.raw().cast_ref()); + room_info.handle_redaction( + redaction_event, + timeline_event.raw().cast_ref_unchecked(), + ); context.state_changes.add_redaction( room_id, redacts, - timeline_event.raw().clone().cast(), + timeline_event.raw().clone().cast_unchecked(), ); } } diff --git a/crates/matrix-sdk-base/src/room/display_name.rs b/crates/matrix-sdk-base/src/room/display_name.rs index 6dbfadadd..6d8b3c2d1 100644 --- a/crates/matrix-sdk-base/src/room/display_name.rs +++ b/crates/matrix-sdk-base/src/room/display_name.rs @@ -554,7 +554,7 @@ mod tests { "state_key": user_id, }); - Raw::new(&ev_json).unwrap().cast() + Raw::new(&ev_json).unwrap().cast_unchecked() } fn make_canonical_alias_event() -> MinimalStateEvent { diff --git a/crates/matrix-sdk-base/src/room/room_info.rs b/crates/matrix-sdk-base/src/room/room_info.rs index 55558f7fc..86b0fbc96 100644 --- a/crates/matrix-sdk-base/src/room/room_info.rs +++ b/crates/matrix-sdk-base/src/room/room_info.rs @@ -1146,7 +1146,7 @@ pub fn apply_redaction( } let raw = Raw::new(&event_json).expect("CanonicalJsonObject must be serializable"); - Some(raw.cast()) + Some(raw.cast_unchecked()) } /// Indicates that a notable update of `RoomInfo` has been applied, and why. @@ -1412,11 +1412,11 @@ mod tests { // Add events to the store. let mut changes = StateChanges::default(); - let raw_tag_event = Raw::new(&*TAG).unwrap().cast(); + let raw_tag_event = Raw::new(&*TAG).unwrap().cast_unchecked(); let tag_event = raw_tag_event.deserialize().unwrap(); changes.add_room_account_data(&room_info.room_id, tag_event, raw_tag_event); - let raw_pinned_events_event = Raw::new(&*PINNED_EVENTS).unwrap().cast(); + let raw_pinned_events_event = Raw::new(&*PINNED_EVENTS).unwrap().cast_unchecked(); let pinned_events_event = raw_pinned_events_event.deserialize().unwrap(); changes.add_state_event(&room_info.room_id, pinned_events_event, raw_pinned_events_event); diff --git a/crates/matrix-sdk-base/src/room/tags.rs b/crates/matrix-sdk-base/src/room/tags.rs index adfbb6a73..71ed2f82c 100644 --- a/crates/matrix-sdk-base/src/room/tags.rs +++ b/crates/matrix-sdk-base/src/room/tags.rs @@ -132,7 +132,7 @@ mod tests { "type": "m.tag", })) .unwrap() - .cast(); + .cast_unchecked(); // When the new tag is handled and applied. let mut context = processors::Context::default(); @@ -164,7 +164,7 @@ mod tests { "type": "m.tag" })) .unwrap() - .cast(); + .cast_unchecked(); processors::account_data::for_room(&mut context, room_id, &[tag_raw], &client.state_store) .await; @@ -230,7 +230,7 @@ mod tests { "type": "m.tag" })) .unwrap() - .cast(); + .cast_unchecked(); // When the new tag is handled and applied. let mut context = processors::Context::default(); @@ -262,7 +262,7 @@ mod tests { "type": "m.tag" })) .unwrap() - .cast(); + .cast_unchecked(); processors::account_data::for_room(&mut context, room_id, &[tag_raw], &client.state_store) .await; diff --git a/crates/matrix-sdk-base/src/sliding_sync.rs b/crates/matrix-sdk-base/src/sliding_sync.rs index 6f4b53567..c710b7ce0 100644 --- a/crates/matrix-sdk-base/src/sliding_sync.rs +++ b/crates/matrix-sdk-base/src/sliding_sync.rs @@ -623,7 +623,7 @@ mod tests { "state_key": user_id, })) .expect("Failed to make raw event") - .cast(); + .cast_unchecked(); room.invite_state = Some(vec![event]); let response = response_with_room(room_id, room); @@ -1327,7 +1327,7 @@ mod tests { // When the sliding sync response contains a timeline let events = &[knock_event]; let mut room = room_with_timeline(events); - room.required_state.push(Raw::new(&power_levels).unwrap().cast()); + room.required_state.push(Raw::new(&power_levels).unwrap().cast_unchecked()); let response = response_with_room(room_id, room); client .process_sliding_sync(&response, &RequestedRequiredStates::default()) @@ -1375,7 +1375,7 @@ mod tests { // When the sliding sync response contains a timeline let events = &[knock_event]; let mut room = room_with_timeline(events); - room.required_state.push(Raw::new(&power_levels).unwrap().cast()); + room.required_state.push(Raw::new(&power_levels).unwrap().cast_unchecked()); let response = response_with_room(room_id, room); client .process_sliding_sync(&response, &RequestedRequiredStates::default()) @@ -2708,7 +2708,7 @@ mod tests { "state_key": invitee, })) .expect("Failed to make raw event") - .cast(); + .cast_unchecked(); room.invite_state = Some(vec![evt]); @@ -2736,7 +2736,7 @@ mod tests { "state_key": knocker, })) .expect("Failed to make raw event") - .cast(); + .cast_unchecked(); room.invite_state = Some(vec![evt]); } @@ -2771,7 +2771,7 @@ mod tests { "content": content, })) .expect("Failed to create account data event") - .cast() + .cast_unchecked() } fn make_state_event( @@ -2796,6 +2796,6 @@ mod tests { "unsigned": unsigned, })) .expect("Failed to create state event") - .cast() + .cast_unchecked() } } diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index bf3253691..dcbd30342 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -207,7 +207,8 @@ impl StateStoreIntegrationTests for DynStateStore { changes.add_room(stripped_room); let stripped_member_json: &JsonValue = &test_json::MEMBER_STRIPPED; - let stripped_member_event = Raw::new(&stripped_member_json.clone()).unwrap().cast(); + let stripped_member_event = + Raw::new(&stripped_member_json.clone()).unwrap().cast_unchecked(); changes.add_stripped_member(stripped_room_id, user_id, stripped_member_event); self.save_changes(&changes).await?; @@ -1969,7 +1970,7 @@ fn custom_stripped_membership_event(user_id: &UserId) -> Raw Raw { @@ -1986,7 +1987,7 @@ fn custom_membership_event(user_id: &UserId, event_id: &EventId) -> Raw Raw { @@ -1997,5 +1998,5 @@ fn custom_presence_event(user_id: &UserId) -> Raw { "sender": user_id, }); - Raw::new(&ev_json).unwrap().cast() + Raw::new(&ev_json).unwrap().cast_unchecked() } diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index 266b8be4f..01db4d79a 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -333,15 +333,16 @@ impl StateStore for MemoryStore { inner.stripped_room_state.remove(room); if *event_type == StateEventType::RoomMember { - let event = match raw_event.deserialize_as::() { - Ok(ev) => ev, - Err(e) => { - let event_id: Option = - raw_event.get_field("event_id").ok().flatten(); - debug!(event_id, "Failed to deserialize member event: {e}"); - continue; - } - }; + let event = + match raw_event.deserialize_as_unchecked::() { + Ok(ev) => ev, + Err(e) => { + let event_id: Option = + raw_event.get_field("event_id").ok().flatten(); + debug!(event_id, "Failed to deserialize member event: {e}"); + continue; + } + }; inner.stripped_members.remove(room); @@ -375,18 +376,19 @@ impl StateStore for MemoryStore { .insert(state_key.to_owned(), raw_event.clone()); if *event_type == StateEventType::RoomMember { - let event = match raw_event.deserialize_as::() { - Ok(ev) => ev, - Err(e) => { - let event_id: Option = - raw_event.get_field("event_id").ok().flatten(); - debug!( - event_id, - "Failed to deserialize stripped member event: {e}" - ); - continue; - } - }; + let event = + match raw_event.deserialize_as_unchecked::() { + Ok(ev) => ev, + Err(e) => { + let event_id: Option = + raw_event.get_field("event_id").ok().flatten(); + debug!( + event_id, + "Failed to deserialize stripped member event: {e}" + ); + continue; + } + }; inner .stripped_members @@ -466,7 +468,7 @@ impl StateStore for MemoryStore { Some(RedactedBecause::from_raw_event(redaction)?), ) .map_err(StoreError::Redaction)?; - *raw_evt = Raw::new(&redacted)?.cast(); + *raw_evt = Raw::new(&redacted)?.cast_unchecked(); } } } diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index 6cf77e4db..369c8623f 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -579,7 +579,11 @@ impl StateChanges { C::StateKey: Borrow, K: AsRef + ?Sized, { - self.state.get(room_id)?.get(&C::TYPE.into())?.get(state_key.as_ref()).map(Raw::cast_ref) + self.state + .get(room_id)? + .get(&C::TYPE.into())? + .get(state_key.as_ref()) + .map(Raw::cast_ref_unchecked) } /// Get a specific stripped state event of statically-known type with the @@ -599,7 +603,7 @@ impl StateChanges { .get(room_id)? .get(&C::TYPE.into())? .get(state_key.as_ref()) - .map(Raw::cast_ref) + .map(Raw::cast_ref_unchecked) } /// Get a specific state event of statically-known type with the given state diff --git a/crates/matrix-sdk-base/src/store/traits.rs b/crates/matrix-sdk-base/src/store/traits.rs index 5767cbc0b..870d18f04 100644 --- a/crates/matrix-sdk-base/src/store/traits.rs +++ b/crates/matrix-sdk-base/src/store/traits.rs @@ -878,7 +878,7 @@ pub trait StateStoreExt: StateStore { where C: StaticEventContent + GlobalAccountDataEventContent, { - Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast)) + Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked)) } /// Get an event of a statically-known type from the room account data @@ -895,7 +895,10 @@ pub trait StateStoreExt: StateStore { where C: StaticEventContent + RoomAccountDataEventContent, { - Ok(self.get_room_account_data_event(room_id, C::TYPE.into()).await?.map(Raw::cast)) + Ok(self + .get_room_account_data_event(room_id, C::TYPE.into()) + .await? + .map(Raw::cast_unchecked)) } /// Get the `MemberEvent` for the given state key in the given room id. diff --git a/crates/matrix-sdk-base/src/sync.rs b/crates/matrix-sdk-base/src/sync.rs index 9ba1d4db7..aa9bd79b7 100644 --- a/crates/matrix-sdk-base/src/sync.rs +++ b/crates/matrix-sdk-base/src/sync.rs @@ -339,7 +339,9 @@ impl fmt::Debug for Notification { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let event_debug = match &self.event { RawAnySyncOrStrippedTimelineEvent::Sync(ev) => DebugRawEvent(ev), - RawAnySyncOrStrippedTimelineEvent::Stripped(ev) => DebugRawEvent(ev.cast_ref()), + RawAnySyncOrStrippedTimelineEvent::Stripped(ev) => { + DebugRawEvent(ev.cast_ref_unchecked()) + } }; f.debug_struct("Notification") diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index 8b133fad3..6c6ebfdb4 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -564,7 +564,7 @@ impl TimelineEvent { DecryptedRoomEvent { // Safety: A decrypted event always includes a room_id in its // payload. - event: latest_event.cast(), + event: latest_event.cast_unchecked(), encryption_info: encryption_info.clone(), // A bundled latest event is never a thread root. It could have // a replacement event, but we don't carry this information @@ -753,7 +753,7 @@ impl TimelineEventKind { // expected to contain a `room_id`). It just means that the `room_id` will be ignored // in a future deserialization. TimelineEventKind::Decrypted(d) => d.event.cast_ref(), - TimelineEventKind::UnableToDecrypt { event, .. } => event.cast_ref(), + TimelineEventKind::UnableToDecrypt { event, .. } => event, TimelineEventKind::PlainText { event } => event, } } @@ -794,7 +794,7 @@ impl TimelineEventKind { // expected to contain a `room_id`). It just means that the `room_id` will be ignored // in a future deserialization. TimelineEventKind::Decrypted(d) => d.event.cast(), - TimelineEventKind::UnableToDecrypt { event, .. } => event.cast(), + TimelineEventKind::UnableToDecrypt { event, .. } => event, TimelineEventKind::PlainText { event } => event, } } @@ -1159,7 +1159,7 @@ impl From for TimelineEvent { // That *should* be ok, because if this is genuinely a decrypted // room event (as the encryption_info indicates), then it will have // a room_id. - event: event.cast(), + event: event.cast_unchecked(), encryption_info, unsigned_encryption_info, }) @@ -1261,7 +1261,8 @@ mod tests { #[test] fn sync_timeline_debug_content() { - let room_event = TimelineEvent::from_plaintext(Raw::new(&example_event()).unwrap().cast()); + let room_event = + TimelineEvent::from_plaintext(Raw::new(&example_event()).unwrap().cast_unchecked()); let debug_s = format!("{room_event:?}"); assert!( !debug_s.contains("secret"), @@ -1381,7 +1382,7 @@ mod tests { fn sync_timeline_event_serialisation() { let room_event = TimelineEvent { kind: TimelineEventKind::Decrypted(DecryptedRoomEvent { - event: Raw::new(&example_event()).unwrap().cast(), + event: Raw::new(&example_event()).unwrap().cast_unchecked(), encryption_info: Arc::new(EncryptionInfo { sender: user_id!("@sender:example.com").to_owned(), sender_device: None, @@ -1556,7 +1557,7 @@ mod tests { } }); - let raw = Raw::new(&event).unwrap().cast(); + let raw = Raw::new(&event).unwrap().cast_unchecked(); // When creating a timeline event from a raw event, the thread summary is always // extracted, if available. @@ -1818,7 +1819,7 @@ mod tests { fn snapshot_test_sync_timeline_event() { let room_event = TimelineEvent { kind: TimelineEventKind::Decrypted(DecryptedRoomEvent { - event: Raw::new(&example_event()).unwrap().cast(), + event: Raw::new(&example_event()).unwrap().cast_unchecked(), encryption_info: Arc::new(EncryptionInfo { sender: user_id!("@sender:example.com").to_owned(), sender_device: Some(device_id!("ABCDEFGHIJ").to_owned()), diff --git a/crates/matrix-sdk-common/src/serde_helpers.rs b/crates/matrix-sdk-common/src/serde_helpers.rs index aad2306ef..9ea8f40e9 100644 --- a/crates/matrix-sdk-common/src/serde_helpers.rs +++ b/crates/matrix-sdk-common/src/serde_helpers.rs @@ -130,7 +130,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); let observed_thread_root = extract_thread_root(&event); assert_eq!(observed_thread_root.as_deref(), Some(thread_root)); @@ -144,7 +144,7 @@ mod tests { "origin_server_ts": 42, })) .unwrap() - .cast(); + .cast_unchecked(); let observed_thread_root = extract_thread_root(&event); assert_matches!(observed_thread_root, None); @@ -160,7 +160,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); let observed_thread_root = extract_thread_root(&event); assert_matches!(observed_thread_root, None); @@ -180,7 +180,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); let observed_thread_root = extract_thread_root(&event); assert_matches!(observed_thread_root, None); @@ -216,7 +216,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); assert_matches!( extract_bundled_thread_summary(&event), @@ -231,7 +231,7 @@ mod tests { "origin_server_ts": 42, })) .unwrap() - .cast(); + .cast_unchecked(); assert_matches!(extract_bundled_thread_summary(&event), (ThreadSummaryStatus::None, None)); @@ -260,7 +260,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); assert_matches!(extract_bundled_thread_summary(&event), (ThreadSummaryStatus::None, None)); @@ -280,7 +280,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); assert_matches!( extract_bundled_thread_summary(&event), diff --git a/crates/matrix-sdk-crypto/src/gossiping/machine.rs b/crates/matrix-sdk-crypto/src/gossiping/machine.rs index 912887d93..2c9efbf60 100644 --- a/crates/matrix-sdk-crypto/src/gossiping/machine.rs +++ b/crates/matrix-sdk-crypto/src/gossiping/machine.rs @@ -1382,7 +1382,7 @@ mod tests { + std::fmt::Debug, { let content = extract_content(recipient, request); - let content: C = content.deserialize_as().unwrap_or_else(|_| { + let content: C = content.deserialize_as_unchecked().unwrap_or_else(|_| { panic!("We can always deserialize the to-device event content {content:?}") }); diff --git a/crates/matrix-sdk-crypto/src/identities/manager.rs b/crates/matrix-sdk-crypto/src/identities/manager.rs index adf4f2591..48d85a55d 100644 --- a/crates/matrix-sdk-crypto/src/identities/manager.rs +++ b/crates/matrix-sdk-crypto/src/identities/manager.rs @@ -587,12 +587,12 @@ impl IdentityManager { master_key: &Raw, response: &KeysQueryResponse, ) -> Option<(MasterPubkey, SelfSigningPubkey)> { - match master_key.deserialize_as::() { + match master_key.deserialize_as_unchecked::() { Ok(master_key) => { if let Some(self_signing) = response .self_signing_keys .get(master_key.user_id()) - .and_then(|k| k.deserialize_as::().ok()) + .and_then(|k| k.deserialize_as_unchecked::().ok()) { Some((master_key, self_signing)) } else { @@ -629,7 +629,7 @@ impl IdentityManager { let Some(user_signing) = response .user_signing_keys .get(self.user_id()) - .and_then(|k| k.deserialize_as::().ok()) + .and_then(|k| k.deserialize_as_unchecked::().ok()) else { warn!( "User identity for our own user didn't contain a user signing pubkey or the key \ diff --git a/crates/matrix-sdk-crypto/src/lib.rs b/crates/matrix-sdk-crypto/src/lib.rs index 6103438f0..8402ef679 100644 --- a/crates/matrix-sdk-crypto/src/lib.rs +++ b/crates/matrix-sdk-crypto/src/lib.rs @@ -1055,7 +1055,7 @@ pub enum RoomEventDecryptionResult { /// let content = Raw::new(&json!({ /// "body": message, /// "msgtype": "m.text", -/// }))?.cast(); +/// }))?.cast_unchecked(); /// /// let users = get_joined_members(room_id).await; /// diff --git a/crates/matrix-sdk-crypto/src/machine/mod.rs b/crates/matrix-sdk-crypto/src/machine/mod.rs index e836631bf..bfcf6eb6a 100644 --- a/crates/matrix-sdk-crypto/src/machine/mod.rs +++ b/crates/matrix-sdk-crypto/src/machine/mod.rs @@ -1067,7 +1067,7 @@ impl OlmMachine { content: impl MessageLikeEventContent, ) -> MegolmResult> { let event_type = content.event_type().to_string(); - let content = Raw::new(&content)?.cast(); + let content = Raw::new(&content)?.cast_unchecked(); self.encrypt_room_event_raw(room_id, &event_type, &content).await } @@ -1378,7 +1378,7 @@ impl OlmMachine { content: ContentStub<'a>, } - if let Ok(event) = event.deserialize_as::>() { + if let Ok(event) = event.deserialize_as_unchecked::>() { Span::current().record("sender", event.sender); Span::current().record("event_type", event.event_type); Span::current().record("message_id", event.content.message_id); diff --git a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs index d28e10e4b..cc757ff66 100644 --- a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs +++ b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs @@ -263,7 +263,8 @@ pub async fn get_machine_pair_with_setup_sessions_test_helper( bob_device.encrypt("m.dummy", ToDeviceDummyEventContent::new()).await.unwrap(); alice.store().save_sessions(&[session]).await.unwrap(); - let event = ToDeviceEvent::new(alice.user_id().to_owned(), content.deserialize_as().unwrap()); + let event = + ToDeviceEvent::new(alice.user_id().to_owned(), content.deserialize_as_unchecked().unwrap()); let decrypted = bob .store() diff --git a/crates/matrix-sdk-crypto/src/machine/tests/mod.rs b/crates/matrix-sdk-crypto/src/machine/tests/mod.rs index 251683ce3..662358edd 100644 --- a/crates/matrix-sdk-crypto/src/machine/tests/mod.rs +++ b/crates/matrix-sdk-crypto/src/machine/tests/mod.rs @@ -129,7 +129,7 @@ pub fn to_device_requests_to_content( .values() .next() .unwrap() - .deserialize_as() + .deserialize_as_unchecked() .unwrap() } @@ -268,7 +268,7 @@ fn test_one_time_key_signing() { .values_mut() .next() .expect("One time keys should be generated") - .deserialize_as() + .deserialize_as_unchecked() .unwrap(); ed25519_key @@ -311,7 +311,7 @@ async fn test_keys_for_upload() { .values_mut() .next() .expect("One time keys should be generated") - .deserialize_as() + .deserialize_as_unchecked() .unwrap(); let ret = ed25519_key.verify_json( @@ -735,7 +735,7 @@ async fn test_withheld_unverified() { .values() .next() .unwrap() - .deserialize_as::() + .deserialize_as_unchecked::() .expect("Deserialize should work"); let event = ToDeviceEvent::new(alice.user_id().to_owned(), wh_content); diff --git a/crates/matrix-sdk-crypto/src/machine/tests/olm_encryption.rs b/crates/matrix-sdk-crypto/src/machine/tests/olm_encryption.rs index 78197886d..8a2c32e0a 100644 --- a/crates/matrix-sdk-crypto/src/machine/tests/olm_encryption.rs +++ b/crates/matrix-sdk-crypto/src/machine/tests/olm_encryption.rs @@ -207,7 +207,9 @@ async fn olm_encryption_test_helper(use_fallback_key: bool) { let event = ToDeviceEvent::new( alice.user_id().to_owned(), - content.deserialize_as().expect("We should be able to deserialize the encrypted content"), + content + .deserialize_as_unchecked() + .expect("We should be able to deserialize the encrypted content"), ); // Decrypting the first time should succeed. diff --git a/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs b/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs index 693882926..f42ea7723 100644 --- a/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs +++ b/crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs @@ -602,7 +602,7 @@ impl GroupSessionManager { for (user_id, device_map) in &request.messages { for (device, content) in device_map { let message_id: Option<&str> = content - .deserialize_as::>() + .deserialize_as_unchecked::>() .expect("We should be able to deserialize the content we generated") .message_id; @@ -1243,7 +1243,7 @@ mod tests { for message in r.messages.values() { message.iter().for_each(|(_, content)| { let withheld: RoomKeyWithheldContent = - content.deserialize_as::().unwrap(); + content.deserialize_as_unchecked::().unwrap(); if let MegolmV1AesSha2(content) = withheld { if content.withheld_code() == code { @@ -1528,7 +1528,7 @@ mod tests { let device_key = DeviceIdOrAllDevices::from(device_id!("MWVTUXDNNM").to_owned()); let content = &r.messages[user_id][&device_key]; let withheld: RoomKeyWithheldContent = - content.deserialize_as::().unwrap(); + content.deserialize_as_unchecked::().unwrap(); if let MegolmV1AesSha2(content) = withheld { content.withheld_code() == WithheldCode::Blacklisted } else { @@ -1812,7 +1812,7 @@ mod tests { .unwrap(); let to_device = EncryptedToDeviceEvent::new( alice.user_id().to_owned(), - bob_message.cast_ref().deserialize().unwrap(), + bob_message.deserialize_as_unchecked().unwrap(), ); let sync_changes = EncryptionSyncChanges { diff --git a/crates/matrix-sdk-crypto/src/types/backup.rs b/crates/matrix-sdk-crypto/src/types/backup.rs index 313a5d6cc..62b026857 100644 --- a/crates/matrix-sdk-crypto/src/types/backup.rs +++ b/crates/matrix-sdk-crypto/src/types/backup.rs @@ -14,6 +14,7 @@ use std::collections::BTreeMap; +use ruma::serde::JsonCastable; use serde::{Deserialize, Serialize}; use serde_json::Value; use vodozemac::Curve25519PublicKey; @@ -62,6 +63,10 @@ pub enum RoomKeyBackupInfo { }, } +impl JsonCastable for RoomKeyBackupInfo {} + +impl JsonCastable for ruma::api::client::backup::BackupAlgorithm {} + #[derive(Clone, Debug, Serialize, Deserialize)] struct BackupInfoHelper { algorithm: String, diff --git a/crates/matrix-sdk-crypto/src/types/cross_signing/common.rs b/crates/matrix-sdk-crypto/src/types/cross_signing/common.rs index 01b5f1887..a0e468202 100644 --- a/crates/matrix-sdk-crypto/src/types/cross_signing/common.rs +++ b/crates/matrix-sdk-crypto/src/types/cross_signing/common.rs @@ -23,8 +23,9 @@ use std::collections::BTreeMap; use as_variant::as_variant; use ruma::{ - encryption::KeyUsage, serde::Raw, DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceKeyId, - OwnedUserId, UserId, + encryption::KeyUsage, + serde::{JsonCastable, Raw}, + DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceKeyId, OwnedUserId, UserId, }; use serde::{Deserialize, Serialize}; use serde_json::{value::to_raw_value, Value}; @@ -86,6 +87,8 @@ impl CrossSigningKey { } } +impl JsonCastable for ruma::encryption::CrossSigningKey {} + /// An enum over the different key types a cross-signing key can have. /// /// Currently cross signing keys support an ed25519 keypair. The keys transport diff --git a/crates/matrix-sdk-crypto/src/types/cross_signing/mod.rs b/crates/matrix-sdk-crypto/src/types/cross_signing/mod.rs index cdbc778b5..d425343eb 100644 --- a/crates/matrix-sdk-crypto/src/types/cross_signing/mod.rs +++ b/crates/matrix-sdk-crypto/src/types/cross_signing/mod.rs @@ -107,7 +107,7 @@ mod tests { let user_id = user_id!("@example:localhost"); let response = own_key_query(); let raw = response.$field.get(user_id).unwrap(); - let key: $key_type = raw.deserialize_as().unwrap(); + let key: $key_type = raw.deserialize_as_unchecked().unwrap(); // A different key is naturally not the same as our key. let other_identity = get_other_own_identity().await; @@ -118,7 +118,7 @@ mod tests { let other_user_id = user_id!("@example2:localhost"); let other_response = own_key_query_with_user_id(&other_user_id); let other_raw = other_response.$field.get(other_user_id).unwrap(); - let other_key: $key_type = other_raw.deserialize_as().unwrap(); + let other_key: $key_type = other_raw.deserialize_as_unchecked().unwrap(); assert_ne!(key, other_key); // Now let's add another signature to our key. diff --git a/crates/matrix-sdk-crypto/src/types/device_keys.rs b/crates/matrix-sdk-crypto/src/types/device_keys.rs index a9173ff6b..291d4e8cf 100644 --- a/crates/matrix-sdk-crypto/src/types/device_keys.rs +++ b/crates/matrix-sdk-crypto/src/types/device_keys.rs @@ -22,7 +22,8 @@ use std::collections::BTreeMap; use js_option::JsOption; use ruma::{ - serde::Raw, DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, + serde::{JsonCastable, Raw}, + DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, }; use serde::{Deserialize, Serialize}; use serde_json::{value::to_raw_value, Value}; @@ -135,6 +136,8 @@ impl DeviceKeys { } } +impl JsonCastable for ruma::encryption::DeviceKeys {} + /// Additional data added to device key information by intermediate servers. #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] pub struct UnsignedDeviceInfo { diff --git a/crates/matrix-sdk-crypto/src/types/events/room/encrypted.rs b/crates/matrix-sdk-crypto/src/types/events/room/encrypted.rs index 21f8e5c18..d29d3a46a 100644 --- a/crates/matrix-sdk-crypto/src/types/events/room/encrypted.rs +++ b/crates/matrix-sdk-crypto/src/types/events/room/encrypted.rs @@ -16,7 +16,7 @@ use std::collections::BTreeMap; -use ruma::{OwnedDeviceId, RoomId}; +use ruma::{events::AnyToDeviceEventContent, serde::JsonCastable, OwnedDeviceId, RoomId}; use serde::{Deserialize, Serialize}; use serde_json::Value; use vodozemac::{megolm::MegolmMessage, olm::OlmMessage, Curve25519PublicKey}; @@ -65,6 +65,11 @@ impl EncryptedEvent { } } +impl JsonCastable + for ruma::events::room::encrypted::OriginalSyncRoomEncryptedEvent +{ +} + /// An m.room.encrypted to-device event. pub type EncryptedToDeviceEvent = ToDeviceEvent; @@ -95,6 +100,8 @@ impl EventType for ToDeviceEncryptedEventContent { const EVENT_TYPE: &'static str = "m.room.encrypted"; } +impl JsonCastable for ToDeviceEncryptedEventContent {} + impl ToDeviceEncryptedEventContent { /// Get the algorithm of the event content. pub fn algorithm(&self) -> EventEncryptionAlgorithm { @@ -221,6 +228,8 @@ impl EventType for RoomEncryptedEventContent { const EVENT_TYPE: &'static str = "m.room.encrypted"; } +impl JsonCastable for RoomEncryptedEventContent {} + /// An enum for per encryption algorithm event contents. #[derive(Clone, Debug, PartialEq, Eq, Deserialize)] #[serde(try_from = "Helper")] diff --git a/crates/matrix-sdk-crypto/src/types/events/room_key_request.rs b/crates/matrix-sdk-crypto/src/types/events/room_key_request.rs index e46414ed6..2ffee119c 100644 --- a/crates/matrix-sdk-crypto/src/types/events/room_key_request.rs +++ b/crates/matrix-sdk-crypto/src/types/events/room_key_request.rs @@ -16,7 +16,10 @@ use std::collections::BTreeMap; -use ruma::{OwnedDeviceId, OwnedRoomId, OwnedTransactionId, RoomId}; +use ruma::{ + events::AnyToDeviceEventContent, serde::JsonCastable, OwnedDeviceId, OwnedRoomId, + OwnedTransactionId, RoomId, +}; use serde::{Deserialize, Serialize}; use serde_json::Value; use vodozemac::Curve25519PublicKey; @@ -67,6 +70,8 @@ impl EventType for RoomKeyRequestContent { const EVENT_TYPE: &'static str = "m.room_key_request"; } +impl JsonCastable for RoomKeyRequestContent {} + /// Enum describing different actions a room key request event can be carrying. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(tag = "action", content = "body")] diff --git a/crates/matrix-sdk-crypto/src/types/events/room_key_withheld.rs b/crates/matrix-sdk-crypto/src/types/events/room_key_withheld.rs index 39a4dc93f..bc410b681 100644 --- a/crates/matrix-sdk-crypto/src/types/events/room_key_withheld.rs +++ b/crates/matrix-sdk-crypto/src/types/events/room_key_withheld.rs @@ -17,7 +17,7 @@ use std::collections::BTreeMap; use matrix_sdk_common::deserialized_responses::WithheldCode; -use ruma::{OwnedDeviceId, OwnedRoomId}; +use ruma::{events::AnyToDeviceEventContent, serde::JsonCastable, OwnedDeviceId, OwnedRoomId}; use serde::{Deserialize, Serialize}; use serde_json::Value; use vodozemac::Curve25519PublicKey; @@ -155,6 +155,8 @@ impl EventType for RoomKeyWithheldContent { const EVENT_TYPE: &'static str = "m.room_key.withheld"; } +impl JsonCastable for RoomKeyWithheldContent {} + #[derive(Debug, Deserialize, Serialize)] struct WithheldHelper { pub algorithm: EventEncryptionAlgorithm, diff --git a/crates/matrix-sdk-crypto/src/types/events/to_device.rs b/crates/matrix-sdk-crypto/src/types/events/to_device.rs index 04919c5a3..6fa0bdd9f 100644 --- a/crates/matrix-sdk-crypto/src/types/events/to_device.rs +++ b/crates/matrix-sdk-crypto/src/types/events/to_device.rs @@ -25,7 +25,7 @@ use ruma::{ secret::request::{SecretName, ToDeviceSecretRequestEvent}, ToDeviceEventContent, ToDeviceEventType, }, - serde::Raw, + serde::{JsonCastable, Raw}, OwnedUserId, UserId, }; use serde::{Deserialize, Serialize}; @@ -234,6 +234,10 @@ impl ToDeviceEvents { } } +impl JsonCastable for ruma::events::AnyToDeviceEvent {} + +impl JsonCastable for ToDeviceEvents {} + /// A to-device event with an unknown type and content. #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ToDeviceCustomEvent { diff --git a/crates/matrix-sdk-crypto/src/types/one_time_keys.rs b/crates/matrix-sdk-crypto/src/types/one_time_keys.rs index 54b0f5d7c..edd2311c7 100644 --- a/crates/matrix-sdk-crypto/src/types/one_time_keys.rs +++ b/crates/matrix-sdk-crypto/src/types/one_time_keys.rs @@ -114,7 +114,7 @@ impl OneTimeKey { ) -> Result { match algorithm { OneTimeKeyAlgorithm::SignedCurve25519 => { - let key: SignedKey = key.deserialize_as()?; + let key: SignedKey = key.deserialize_as_unchecked()?; Ok(OneTimeKey::SignedKey(key)) } _ => Err(serde::de::Error::custom(format!("Unsupported key algorithm {algorithm}"))), diff --git a/crates/matrix-sdk-indexeddb/src/state_store/migrations.rs b/crates/matrix-sdk-indexeddb/src/state_store/migrations.rs index d29d91218..3474f9869 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store/migrations.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store/migrations.rs @@ -1234,12 +1234,13 @@ mod tests { let room_id = room_id!("!room:localhost"); let member_event = - Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast::(); + Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast_unchecked::(); let user_id = user_id!("@invited:localhost"); let stripped_room_id = room_id!("!stripped_room:localhost"); - let stripped_member_event = - Raw::new(&*test_json::MEMBER_STRIPPED).unwrap().cast::(); + let stripped_member_event = Raw::new(&*test_json::MEMBER_STRIPPED) + .unwrap() + .cast_unchecked::(); let stripped_user_id = user_id!("@example:localhost"); // Populate DB with old table. @@ -1308,15 +1309,16 @@ mod tests { let room_id = room_id!("!room:localhost"); let invite_member_event = - Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast::(); + Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast_unchecked::(); let invite_user_id = user_id!("@invited:localhost"); let ban_member_event = - Raw::new(&*test_json::MEMBER_BAN).unwrap().cast::(); + Raw::new(&*test_json::MEMBER_BAN).unwrap().cast_unchecked::(); let ban_user_id = user_id!("@banned:localhost"); let stripped_room_id = room_id!("!stripped_room:localhost"); - let stripped_member_event = - Raw::new(&*test_json::MEMBER_STRIPPED).unwrap().cast::(); + let stripped_member_event = Raw::new(&*test_json::MEMBER_STRIPPED) + .unwrap() + .cast_unchecked::(); let stripped_user_id = user_id!("@example:localhost"); // Populate DB with old table. diff --git a/crates/matrix-sdk-indexeddb/src/state_store/mod.rs b/crates/matrix-sdk-indexeddb/src/state_store/mod.rs index 3521e9eec..b3eeffca2 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store/mod.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store/mod.rs @@ -758,15 +758,16 @@ impl_state_store!({ stripped_state.delete(&key)?; if *event_type == StateEventType::RoomMember { - let event = match raw_event.deserialize_as::() { - Ok(ev) => ev, - Err(e) => { - let event_id: Option = - raw_event.get_field("event_id").ok().flatten(); - debug!(event_id, "Failed to deserialize member event: {e}"); - continue; - } - }; + let event = + match raw_event.deserialize_as_unchecked::() { + Ok(ev) => ev, + Err(e) => { + let event_id: Option = + raw_event.get_field("event_id").ok().flatten(); + debug!(event_id, "Failed to deserialize member event: {e}"); + continue; + } + }; let key = (room, state_key); @@ -824,7 +825,8 @@ impl_state_store!({ store.put_key_val(&key, &self.serialize_value(&raw_event)?)?; if *event_type == StateEventType::RoomMember { - let event = match raw_event.deserialize_as::() + let event = match raw_event + .deserialize_as_unchecked::() { Ok(ev) => ev, Err(e) => { diff --git a/crates/matrix-sdk-sqlite/src/state_store.rs b/crates/matrix-sdk-sqlite/src/state_store.rs index 4e7f630dd..6ccef6737 100644 --- a/crates/matrix-sdk-sqlite/src/state_store.rs +++ b/crates/matrix-sdk-sqlite/src/state_store.rs @@ -1153,7 +1153,7 @@ impl StateStore for SqliteStateStore { if event_type == StateEventType::RoomMember { let member_event = match raw_state_event - .deserialize_as::() + .deserialize_as_unchecked::() { Ok(ev) => ev, Err(e) => { @@ -1210,7 +1210,7 @@ impl StateStore for SqliteStateStore { if event_type == StateEventType::RoomMember { let member_event = match raw_stripped_state_event - .deserialize_as::( + .deserialize_as_unchecked::( ) { Ok(ev) => ev, Err(e) => { diff --git a/crates/matrix-sdk-ui/src/notification_client.rs b/crates/matrix-sdk-ui/src/notification_client.rs index ebe9b8e80..de960b871 100644 --- a/crates/matrix-sdk-ui/src/notification_client.rs +++ b/crates/matrix-sdk-ui/src/notification_client.rs @@ -266,8 +266,9 @@ impl NotificationClient { sleep(Duration::from_millis(wait)).await; - let new_event = - room.decrypt_event(raw_event.cast_ref(), push_ctx.as_ref()).await?; + let new_event = room + .decrypt_event(raw_event.cast_ref_unchecked(), push_ctx.as_ref()) + .await?; match new_event.kind { matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt { @@ -308,7 +309,7 @@ impl NotificationClient { match encryption_sync { Ok(sync) => match sync.run_fixed_iterations(2, sync_permit_guard).await { - Ok(()) => match room.decrypt_event(raw_event.cast_ref(), push_ctx.as_ref()).await { + Ok(()) => match room.decrypt_event(raw_event.cast_ref_unchecked(), push_ctx.as_ref()).await { Ok(new_event) => match new_event.kind { matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt { utd_info, .. diff --git a/crates/matrix-sdk-ui/src/timeline/event_item/content/pinned_events.rs b/crates/matrix-sdk-ui/src/timeline/event_item/content/pinned_events.rs index f6a8706a7..d41ba569f 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/content/pinned_events.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/content/pinned_events.rs @@ -185,7 +185,7 @@ mod tests { "pinned": ids, })) .unwrap() - .cast::() + .cast_unchecked::() .deserialize() .ok() } diff --git a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs index 86c54d04f..4eecca2a7 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs @@ -1076,7 +1076,7 @@ mod tests { .display_name("Alice Margatroid") .reason("") .into_raw_sync() - .deserialize_as::>() + .deserialize_as_unchecked::>() .unwrap(), ); diff --git a/crates/matrix-sdk-ui/src/timeline/tests/edit.rs b/crates/matrix-sdk-ui/src/timeline/tests/edit.rs index f74b74096..44d8bc2ab 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/edit.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/edit.rs @@ -158,7 +158,7 @@ async fn test_edit_updates_encryption_info() { .sender(*ALICE) .event_id(original_event_id) .room(room_id) - .into_raw_timeline(); + .into_raw(); let mut encryption_info = Arc::new(EncryptionInfo { sender: (*ALICE).into(), @@ -173,7 +173,7 @@ async fn test_edit_updates_encryption_info() { let original_event = TimelineEvent::from_decrypted( DecryptedRoomEvent { - event: original_event.cast(), + event: original_event, encryption_info: encryption_info.clone(), unsigned_encryption_info: None, }, @@ -199,12 +199,12 @@ async fn test_edit_updates_encryption_info() { .sender(*ALICE) .room(room_id) .edit(original_event_id, MessageType::text_plain("!!edited!! **better** message").into()) - .into_raw_timeline(); + .into_raw(); Arc::make_mut(&mut encryption_info).verification_state = VerificationState::Unverified(VerificationLevel::UnverifiedIdentity); let edit_event = TimelineEvent::from_decrypted( DecryptedRoomEvent { - event: edit_event.cast(), + event: edit_event, encryption_info: encryption_info.clone(), unsigned_encryption_info: None, }, diff --git a/crates/matrix-sdk-ui/src/timeline/tests/redaction.rs b/crates/matrix-sdk-ui/src/timeline/tests/redaction.rs index 6f1d03057..1fa667649 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/redaction.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/redaction.rs @@ -70,7 +70,7 @@ async fn test_redact_replied_to_event() { let first_item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value); assert!(first_item.content().is_message()); let first_event: OriginalSyncRoomMessageEvent = - first_item.original_json().unwrap().deserialize_as().unwrap(); + first_item.original_json().unwrap().deserialize_as_unchecked().unwrap(); timeline .handle_live_event(f.text_msg("Hello, alice.").sender(&BOB).reply_to(&first_event.event_id)) diff --git a/crates/matrix-sdk-ui/src/timeline/traits.rs b/crates/matrix-sdk-ui/src/timeline/traits.rs index e1e376488..67706ac2a 100644 --- a/crates/matrix-sdk-ui/src/timeline/traits.rs +++ b/crates/matrix-sdk-ui/src/timeline/traits.rs @@ -323,7 +323,7 @@ impl Decryptor for Room { raw: &Raw, push_ctx: Option<&PushContext>, ) -> Result { - self.decrypt_event(raw.cast_ref(), push_ctx).await + self.decrypt_event(raw.cast_ref_unchecked(), push_ctx).await } } @@ -339,7 +339,7 @@ impl Decryptor for (matrix_sdk_base::crypto::OlmMachine, ruma::OwnedRoomId) { DecryptionSettings { sender_device_trust_requirement: TrustRequirement::Untrusted }; match olm_machine - .try_decrypt_room_event(raw.cast_ref(), room_id, &decryption_settings) + .try_decrypt_room_event(raw.cast_ref_unchecked(), room_id, &decryption_settings) .await? { RoomEventDecryptionResult::Decrypted(decrypted) => { diff --git a/crates/matrix-sdk-ui/tests/integration/notification_client.rs b/crates/matrix-sdk-ui/tests/integration/notification_client.rs index 982e0ef6c..4182465b3 100644 --- a/crates/matrix-sdk-ui/tests/integration/notification_client.rs +++ b/crates/matrix-sdk-ui/tests/integration/notification_client.rs @@ -23,7 +23,7 @@ use matrix_sdk_ui::{ }; use ruma::{ event_id, - events::{AnyStateEvent, TimelineEventType, room::member::MembershipState}, + events::{TimelineEventType, room::member::MembershipState}, mxc_uri, room_id, user_id, }; use serde_json::json; @@ -91,7 +91,7 @@ async fn test_notification_client_with_context() { .and(header("authorization", "Bearer 1234")) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "event": event_json, - "state": [sender_member_event.cast::()] + "state": [sender_member_event] }))) .mount(&server) .await; @@ -593,13 +593,13 @@ async fn test_notification_client_mixed() { .display_name(sender_display_name) .avatar_url(sender_avatar_url) .membership(MembershipState::Join) - .into_raw_sync(); + .into_raw(); let own_member_event = event_factory .member(&my_user_id) .display_name("My self") .membership(MembershipState::Join) - .into_raw_sync(); + .into_raw(); let power_levels_event = event_factory.power_levels(&mut BTreeMap::new()).sender(sender).into_raw_sync(); @@ -619,7 +619,7 @@ async fn test_notification_client_mixed() { let mut sync_builder = SyncResponseBuilder::new(); sync_builder.add_joined_room( JoinedRoomBuilder::new(room_id) - .add_state_bulk([sender_member_event.clone().cast(), own_member_event.clone().cast()]), + .add_state_bulk([sender_member_event.clone(), own_member_event.clone()]), ); // First, mock a sync that contains a state event so we get a valid room for diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/pinned_event.rs b/crates/matrix-sdk-ui/tests/integration/timeline/pinned_event.rs index a00954d1a..bebe0b50b 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/pinned_event.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/pinned_event.rs @@ -715,10 +715,9 @@ impl PinnedEventsSync { .event(RoomPinnedEventsEventContent::new(pinned_event_ids)) .sender(user_id!("@example:localhost")) .state_key("") - .into_raw_sync(); + .into_raw(); - joined_room_builder = - joined_room_builder.add_state_bulk(vec![pinned_events_event.cast()]); + joined_room_builder = joined_room_builder.add_state_bulk(vec![pinned_events_event]); } Ok(server.sync_room(client, joined_room_builder).await) diff --git a/crates/matrix-sdk/src/account.rs b/crates/matrix-sdk/src/account.rs index d0eec02a1..6824b5dbf 100644 --- a/crates/matrix-sdk/src/account.rs +++ b/crates/matrix-sdk/src/account.rs @@ -749,7 +749,7 @@ impl Account { /// use matrix_sdk::ruma::events::{ignored_user_list::IgnoredUserListEventContent, GlobalAccountDataEventType}; /// /// if let Some(raw_content) = account.fetch_account_data(GlobalAccountDataEventType::IgnoredUserList).await? { - /// let content = raw_content.deserialize_as::()?; + /// let content = raw_content.deserialize_as_unchecked::()?; /// /// println!("Ignored users:"); /// @@ -787,7 +787,7 @@ impl Account { where C: GlobalAccountDataEventContent + StaticEventContent, { - Ok(self.fetch_account_data(C::TYPE.into()).await?.map(Raw::cast)) + Ok(self.fetch_account_data(C::TYPE.into()).await?.map(Raw::cast_unchecked)) } /// Set the given account data event. @@ -1173,7 +1173,7 @@ fn get_raw_content(raw: Option>) -> Result>> { } Ok(raw - .map(|event| event.deserialize_as::>()) + .map(|event| event.deserialize_as_unchecked::>()) .transpose()? .map(|get_raw| get_raw.content)) } diff --git a/crates/matrix-sdk/src/encryption/recovery/mod.rs b/crates/matrix-sdk/src/encryption/recovery/mod.rs index 34d8f04b2..645840580 100644 --- a/crates/matrix-sdk/src/encryption/recovery/mod.rs +++ b/crates/matrix-sdk/src/encryption/recovery/mod.rs @@ -314,7 +314,10 @@ impl Recovery { self.client .account() - .set_account_data_raw(event_type, Raw::new(&json!({})).expect("").cast()) + .set_account_data_raw( + event_type, + Raw::new(&json!({})).expect("").cast_unchecked(), + ) .await?; } } diff --git a/crates/matrix-sdk/src/encryption/secret_storage/secret_store.rs b/crates/matrix-sdk/src/encryption/secret_storage/secret_store.rs index de055e79f..6b27a4fed 100644 --- a/crates/matrix-sdk/src/encryption/secret_storage/secret_store.rs +++ b/crates/matrix-sdk/src/encryption/secret_storage/secret_store.rs @@ -152,7 +152,8 @@ impl SecretStore { let event_type = GlobalAccountDataEventType::from(secret_name.to_owned()); if let Some(secret_content) = self.client.account().fetch_account_data(event_type).await? { - let mut secret_content = secret_content.deserialize_as::()?; + let mut secret_content = + secret_content.deserialize_as_unchecked::()?; // The `SecretEventContent` contains a map from the secret storage key ID to the // ciphertext. Let's try to find a secret which was encrypted using our @@ -241,7 +242,7 @@ impl SecretStore { self.client.account().fetch_account_data(event_type.to_owned()).await? { secret_content - .deserialize_as::() + .deserialize_as_unchecked::() .unwrap_or_else(|_| SecretEventContent::new(Default::default())) } else { SecretEventContent::new(Default::default()) diff --git a/crates/matrix-sdk/src/encryption/tasks.rs b/crates/matrix-sdk/src/encryption/tasks.rs index 660cabe23..9401eff28 100644 --- a/crates/matrix-sdk/src/encryption/tasks.rs +++ b/crates/matrix-sdk/src/encryption/tasks.rs @@ -559,17 +559,17 @@ mod test { .await; let event_factory = EventFactory::new().room(invited_rom_id); - let bob_member_event = event_factory.member(bob_user_id).into_raw_timeline(); + let bob_member_event = event_factory.member(bob_user_id).into_raw(); let alice_member_event = - event_factory.member(bob_user_id).invited(alice_user_id).into_raw_timeline(); + event_factory.member(bob_user_id).invited(alice_user_id).into_raw(); server .mock_sync() .ok_and_run(&client, |builder| { builder.add_joined_room(JoinedRoomBuilder::new(joined_room_id)).add_invited_room( InvitedRoomBuilder::new(invited_rom_id) - .add_state_event(bob_member_event.cast()) - .add_state_event(alice_member_event.cast()), + .add_state_event(bob_member_event) + .add_state_event(alice_member_event), ); }) .await; diff --git a/crates/matrix-sdk/src/event_cache/room/mod.rs b/crates/matrix-sdk/src/event_cache/room/mod.rs index 6d1cbddec..09edf323b 100644 --- a/crates/matrix-sdk/src/event_cache/room/mod.rs +++ b/crates/matrix-sdk/src/event_cache/room/mod.rs @@ -1100,7 +1100,7 @@ mod private { let unsigned = val.get_mut("unsigned")?; let unsigned_obj = unsigned.as_object_mut()?; if unsigned_obj.remove("m.relations").is_some() { - *event = Raw::new(&val).ok()?.cast(); + *event = Raw::new(&val).ok()?.cast_unchecked(); } None }; @@ -1621,14 +1621,14 @@ mod private { if let Some(redacted_event) = apply_redaction( target_event.raw(), - event.raw().cast_ref::(), + event.raw().cast_ref_unchecked::(), &self.room_version_rules.redaction, ) { // It's safe to cast `redacted_event` here: // - either the event was an `AnyTimelineEvent` cast to `AnySyncTimelineEvent` // when calling .raw(), so it's still one under the hood. // - or it wasn't, and it's a plain `AnySyncTimelineEvent` in this case. - target_event.replace_raw(redacted_event.cast()); + target_event.replace_raw(redacted_event.cast_unchecked()); self.replace_event_at(location, target_event).await?; } diff --git a/crates/matrix-sdk/src/event_handler/mod.rs b/crates/matrix-sdk/src/event_handler/mod.rs index 2778557c2..56d532aa9 100644 --- a/crates/matrix-sdk/src/event_handler/mod.rs +++ b/crates/matrix-sdk/src/event_handler/mod.rs @@ -349,7 +349,7 @@ impl Client { } for raw_event in events { - let event_type = raw_event.deserialize_as::>()?.event_type; + let event_type = raw_event.deserialize_as_unchecked::>()?.event_type; self.call_event_handlers(room, raw_event.json(), kind, &event_type, None, &[]).await; } @@ -373,7 +373,7 @@ impl Client { } other => (&other.to_raw(), None), }; - let event_type = raw_event.deserialize_as::>()?.event_type; + let event_type = raw_event.deserialize_as_unchecked::>()?.event_type; self.call_event_handlers( None, raw_event.json(), @@ -405,7 +405,8 @@ impl Client { // Event handlers specifically for redacted OR unredacted state events for raw_event in state_events { - let StateEventDetails { event_type, unsigned } = raw_event.deserialize_as()?; + let StateEventDetails { event_type, unsigned } = + raw_event.deserialize_as_unchecked()?; let redacted = unsigned.and_then(|u| u.redacted_because).is_some(); let handler_kind = HandlerKind::state_redacted(redacted); @@ -431,7 +432,7 @@ impl Client { for item in timeline_events { let TimelineEventDetails { event_type, state_key, unsigned } = - item.raw().deserialize_as()?; + item.raw().deserialize_as_unchecked()?; let redacted = unsigned.and_then(|u| u.redacted_because).is_some(); let (handler_kind_g, handler_kind_r) = match state_key { diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 998d98d8d..4fa8b41a0 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -579,7 +579,7 @@ impl Room { SyncMessageLikeEvent::Original(_), ))) = event.deserialize_as::() { - if let Ok(event) = self.decrypt_event(event.cast_ref(), push_ctx).await { + if let Ok(event) = self.decrypt_event(event.cast_ref_unchecked(), push_ctx).await { return event; } } @@ -759,9 +759,11 @@ impl Room { "".to_owned(), ); let response = match self.client.send(request).await { - Ok(response) => { - Some(response.content.deserialize_as::()?) - } + Ok(response) => Some( + response + .content + .deserialize_as_unchecked::()?, + ), Err(err) if err.client_api_error_kind() == Some(&ErrorKind::NotFound) => None, Err(err) => return Err(err.into()), }; @@ -1196,7 +1198,7 @@ impl Room { where C: StaticEventContent + RoomAccountDataEventContent, { - Ok(self.account_data(C::TYPE.into()).await?.map(Raw::cast)) + Ok(self.account_data(C::TYPE.into()).await?.map(Raw::cast_unchecked)) } /// Check if all members of this room are verified and all their devices are @@ -3423,9 +3425,9 @@ impl Room { .await; match response { - Ok(response) => { - Ok(Some(response.content.deserialize_as::()?.pinned)) - } + Ok(response) => Ok(Some( + response.content.deserialize_as_unchecked::()?.pinned, + )), Err(http_error) => match http_error.as_client_api_error() { Some(error) if error.status_code == StatusCode::NOT_FOUND => Ok(None), _ => Err(http_error.into()), diff --git a/crates/matrix-sdk/src/test_utils/mocks/mod.rs b/crates/matrix-sdk/src/test_utils/mocks/mod.rs index 80abc2996..de94d9699 100644 --- a/crates/matrix-sdk/src/test_utils/mocks/mod.rs +++ b/crates/matrix-sdk/src/test_utils/mocks/mod.rs @@ -942,8 +942,7 @@ impl MatrixMockServer { /// .event_id(event_id) /// .sender(alice_user_id) /// .state_key(alice_user_id) - /// .into_raw_timeline() - /// .cast(); + /// .into_raw(); /// /// mock_server /// .mock_get_members() diff --git a/crates/matrix-sdk/src/utils/mod.rs b/crates/matrix-sdk/src/utils/mod.rs index 905871bb3..4f32b5e35 100644 --- a/crates/matrix-sdk/src/utils/mod.rs +++ b/crates/matrix-sdk/src/utils/mod.rs @@ -126,7 +126,7 @@ impl IntoRawMessageLikeEventContent for JsonValue { impl IntoRawMessageLikeEventContent for &JsonValue { fn into_raw_message_like_event_content(self) -> Raw { - Raw::new(self).expect("serde_json::Value never fails to serialize").cast() + Raw::new(self).expect("serde_json::Value never fails to serialize").cast_unchecked() } } @@ -174,7 +174,7 @@ impl IntoRawStateEventContent for JsonValue { impl IntoRawStateEventContent for &JsonValue { fn into_raw_state_event_content(self) -> Raw { - Raw::new(self).expect("serde_json::Value never fails to serialize").cast() + Raw::new(self).expect("serde_json::Value never fails to serialize").cast_unchecked() } } diff --git a/crates/matrix-sdk/src/widget/filter.rs b/crates/matrix-sdk/src/widget/filter.rs index a674fdbb5..fd8c0fbfb 100644 --- a/crates/matrix-sdk/src/widget/filter.rs +++ b/crates/matrix-sdk/src/widget/filter.rs @@ -14,10 +14,10 @@ use ruma::{ events::{ - AnyStateEvent, AnyTimelineEvent, AnyToDeviceEvent, MessageLikeEventType, StateEventType, - ToDeviceEventType, + AnyMessageLikeEvent, AnyStateEvent, AnyTimelineEvent, AnyToDeviceEvent, + MessageLikeEventType, StateEventType, ToDeviceEventType, }, - serde::Raw, + serde::{JsonCastable, Raw}, }; use serde::Deserialize; use tracing::debug; @@ -235,6 +235,12 @@ impl<'a> TryFrom<&'a Raw> for FilterInput<'a> { } } +impl<'a> JsonCastable> for AnyTimelineEvent {} + +impl<'a> JsonCastable> for AnyStateEvent {} + +impl<'a> JsonCastable> for AnyMessageLikeEvent {} + #[derive(Debug, Deserialize)] pub struct FilterInputToDevice<'a> { #[serde(rename = "type")] @@ -252,6 +258,8 @@ impl<'a> TryFrom<&'a Raw> for FilterInput<'a> { } } +impl<'a> JsonCastable> for AnyToDeviceEvent {} + impl<'a> From<&'a SendToDeviceRequest> for FilterInput<'a> { fn from(request: &'a SendToDeviceRequest) -> Self { FilterInput::ToDevice(FilterInputToDevice { event_type: &request.event_type }) diff --git a/crates/matrix-sdk/src/widget/machine/mod.rs b/crates/matrix-sdk/src/widget/machine/mod.rs index 9abcb8c3f..0aa13d683 100644 --- a/crates/matrix-sdk/src/widget/machine/mod.rs +++ b/crates/matrix-sdk/src/widget/machine/mod.rs @@ -621,8 +621,8 @@ impl WidgetMachine { response_data: impl Serialize, ) -> Action { let f = || { - let mut object = - raw_request.deserialize_as::>>()?; + let mut object = raw_request + .deserialize_as_unchecked::>>()?; let response_data = serde_json::value::to_raw_value(&response_data)?; object.insert("response".to_owned(), response_data); serde_json::to_string(&object) diff --git a/crates/matrix-sdk/src/widget/matrix.rs b/crates/matrix-sdk/src/widget/matrix.rs index 66c616064..36aa67c4c 100644 --- a/crates/matrix-sdk/src/widget/matrix.rs +++ b/crates/matrix-sdk/src/widget/matrix.rs @@ -92,7 +92,7 @@ impl MatrixDriver { Ok(messages .chunk .into_iter() - .map(|ev| ev.into_raw().cast()) + .map(|ev| ev.into_raw().cast_unchecked()) .filter(|ev| match &state_key { Some(state_key) => { ev.get_field::("state_key").is_ok_and(|key| match state_key { @@ -548,13 +548,14 @@ impl StateUpdateReceiver { } fn attach_room_id(raw_ev: &Raw, room_id: &RoomId) -> Raw { - let mut ev_obj = raw_ev.deserialize_as::>>().unwrap(); + let mut ev_obj = + raw_ev.deserialize_as_unchecked::>>().unwrap(); ev_obj.insert("room_id".to_owned(), serde_json::value::to_raw_value(room_id).unwrap()); - Raw::new(&ev_obj).unwrap().cast() + Raw::new(&ev_obj).unwrap().cast_unchecked() } fn attach_room_id_state(raw_ev: &Raw, room_id: &RoomId) -> Raw { - attach_room_id(raw_ev.cast_ref(), room_id).cast() + attach_room_id(raw_ev.cast_ref(), room_id).cast_unchecked() } #[cfg(test)] @@ -578,7 +579,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); let room_id = room_id!("!my_id:example.org"); let new = attach_room_id(&raw, room_id); @@ -606,7 +607,7 @@ mod tests { } })) .unwrap() - .cast(); + .cast_unchecked(); let room_id = room_id!("!my_id:example.org"); let new = attach_room_id(&raw, room_id); diff --git a/crates/matrix-sdk/tests/integration/client.rs b/crates/matrix-sdk/tests/integration/client.rs index d2e58c019..3b780fb54 100644 --- a/crates/matrix-sdk/tests/integration/client.rs +++ b/crates/matrix-sdk/tests/integration/client.rs @@ -770,7 +770,7 @@ async fn test_encrypt_room_event() { "content": content, })) .expect("We should be able to construct a full event from the encrypted event content") - .cast(); + .cast_unchecked(); let push_ctx = room.push_context().await.expect("We should be able to get the push action context"); @@ -1338,11 +1338,11 @@ async fn test_restore_room() { let mut changes = StateChanges::default(); - let raw_tag_event = Raw::new(&*TAG).unwrap().cast(); + let raw_tag_event = Raw::new(&*TAG).unwrap().cast_unchecked(); let tag_event = raw_tag_event.deserialize().unwrap(); changes.add_room_account_data(room_id, tag_event, raw_tag_event); - let raw_pinned_events_event = Raw::new(&*PINNED_EVENTS).unwrap().cast(); + let raw_pinned_events_event = Raw::new(&*PINNED_EVENTS).unwrap().cast_unchecked(); let pinned_events_event = raw_pinned_events_event.deserialize().unwrap(); changes.add_state_event(room_id, pinned_events_event, raw_pinned_events_event); diff --git a/crates/matrix-sdk/tests/integration/encryption/backups.rs b/crates/matrix-sdk/tests/integration/encryption/backups.rs index 9378bf330..8b297aaf8 100644 --- a/crates/matrix-sdk/tests/integration/encryption/backups.rs +++ b/crates/matrix-sdk/tests/integration/encryption/backups.rs @@ -1018,7 +1018,7 @@ async fn test_enable_from_secret_storage() { assert_matches!(event.encryption_info(), Some(..), "The event should now be decrypted"); let event: RoomMessageEvent = - event.raw().deserialize_as().expect("We should be able to deserialize the event"); + event.raw().deserialize_as_unchecked().expect("We should be able to deserialize the event"); let event = event.as_original().unwrap(); assert_eq!(event.content.body(), "tt"); @@ -1365,7 +1365,7 @@ async fn test_enable_from_secret_storage_and_download_after_utd() { assert_matches!(event.encryption_info(), Some(..), "The event should now be decrypted"); let event: RoomMessageEvent = - event.raw().deserialize_as().expect("We should be able to deserialize the event"); + event.raw().deserialize_as_unchecked().expect("We should be able to deserialize the event"); let event = event.as_original().unwrap(); assert_eq!(event.content.body(), "tt"); @@ -1491,7 +1491,7 @@ async fn test_enable_from_secret_storage_and_download_after_utd_from_old_message assert_matches!(event.encryption_info(), Some(..), "The event should now be decrypted"); let event: RoomMessageEvent = - event.raw().deserialize_as().expect("We should be able to deserialize the event"); + event.raw().deserialize_as_unchecked().expect("We should be able to deserialize the event"); let event = event.as_original().unwrap(); assert_eq!(event.content.body(), "tt"); diff --git a/crates/matrix-sdk/tests/integration/encryption/shared_history.rs b/crates/matrix-sdk/tests/integration/encryption/shared_history.rs index dd79bb0ce..46ec11c6e 100644 --- a/crates/matrix-sdk/tests/integration/encryption/shared_history.rs +++ b/crates/matrix-sdk/tests/integration/encryption/shared_history.rs @@ -46,7 +46,7 @@ async fn test_shared_history_out_of_order() { matrix_mock_server.exchange_e2ee_identities(&alice, &bob).await; let event_factory = EventFactory::new().room(room_id); - let alice_member_event = event_factory.member(alice_user_id).into_raw_timeline(); + let alice_member_event = event_factory.member(alice_user_id).into_raw(); matrix_mock_server .mock_sync() @@ -70,7 +70,7 @@ async fn test_shared_history_out_of_order() { matrix_mock_server .mock_get_members() - .ok(vec![alice_member_event.clone().cast()]) + .ok(vec![alice_member_event.clone()]) .mock_once() .mount() .await; @@ -105,7 +105,7 @@ async fn test_shared_history_out_of_order() { builder.add_invited_room( InvitedRoomBuilder::new(room_id) .add_state_event(alice_member_event.cast()) - .add_state_event(bob_member_event.into_raw_timeline().cast()), + .add_state_event(bob_member_event.into_raw()), ); }) .await; diff --git a/crates/matrix-sdk/tests/integration/encryption/to_device.rs b/crates/matrix-sdk/tests/integration/encryption/to_device.rs index 26f02d2c7..46394901b 100644 --- a/crates/matrix-sdk/tests/integration/encryption/to_device.rs +++ b/crates/matrix-sdk/tests/integration/encryption/to_device.rs @@ -50,7 +50,7 @@ async fn test_encrypt_and_send_to_device() { "sent_ts": 1000 })) .unwrap() - .cast(); + .cast_unchecked(); Mock::given(method("PUT")) .and(path_regex(r"^/_matrix/client/.*/sendToDevice/m.room.encrypted/.*")) @@ -94,7 +94,7 @@ async fn test_encrypt_and_send_to_device_report_failures_server() { "sent_ts": 1000 })) .unwrap() - .cast(); + .cast_unchecked(); // Fail Mock::given(method("PUT")) @@ -157,7 +157,7 @@ async fn test_to_device_event_handler_olm_encryption_info() { "sent_ts": 1000 })) .unwrap() - .cast(); + .cast_unchecked(); // Capture the event sent by Alice to feed it back to Bob's client later. let bob_received_to_device_future = @@ -215,7 +215,7 @@ async fn test_encrypt_and_send_to_device_report_failures_encryption_error() { "sent_ts": 1000 })) .unwrap() - .cast(); + .cast_unchecked(); // Should not be called Mock::given(method("PUT")) diff --git a/crates/matrix-sdk/tests/integration/event_cache/mod.rs b/crates/matrix-sdk/tests/integration/event_cache/mod.rs index 1bb3071c5..a4bf2ae50 100644 --- a/crates/matrix-sdk/tests/integration/event_cache/mod.rs +++ b/crates/matrix-sdk/tests/integration/event_cache/mod.rs @@ -1448,7 +1448,7 @@ async fn test_apply_redaction_when_redaction_comes_later() { assert_eq!(events.len(), 2); // The initial event (that's been redacted), - let ev = events[0].raw().cast_ref::().deserialize().unwrap(); + let ev = events[0].raw().cast_ref_unchecked::().deserialize().unwrap(); assert!(ev.is_redacted()); // And the redacted event. diff --git a/crates/matrix-sdk/tests/integration/notification.rs b/crates/matrix-sdk/tests/integration/notification.rs index e81eec653..a559f757e 100644 --- a/crates/matrix-sdk/tests/integration/notification.rs +++ b/crates/matrix-sdk/tests/integration/notification.rs @@ -33,7 +33,7 @@ async fn test_notifications_joined() { // Set up the room state, no notifications. let mut sync_builder = SyncResponseBuilder::new(); let joined_room = JoinedRoomBuilder::new(room_id).add_state_bulk([ - Raw::new(&*test_json::POWER_LEVELS).unwrap().cast(), + Raw::new(&*test_json::POWER_LEVELS).unwrap().cast_unchecked(), sync_state_event!({ "content": { "avatar_url": null, @@ -109,7 +109,7 @@ async fn test_notifications_invite() { let mut sync_builder = SyncResponseBuilder::new(); let invited_room = InvitedRoomBuilder::new(room_id).add_state_bulk([ - Raw::new(&*test_json::POWER_LEVELS).unwrap().cast(), + Raw::new(&*test_json::POWER_LEVELS).unwrap().cast_unchecked(), stripped_state_event!({ "content": { "membership": "join" diff --git a/crates/matrix-sdk/tests/integration/widget.rs b/crates/matrix-sdk/tests/integration/widget.rs index 9d548c645..f5924f0e6 100644 --- a/crates/matrix-sdk/tests/integration/widget.rs +++ b/crates/matrix-sdk/tests/integration/widget.rs @@ -619,7 +619,7 @@ async fn test_accept_encrypted_to_device_in_e2ee_room() { "call_id": "", })) .unwrap() - .cast(); + .cast_unchecked(); let event_synced_future = mock_server.mock_capture_put_to_device_then_sync_back(bob.user_id().unwrap(), &alice).await; diff --git a/testing/matrix-sdk-integration-testing/src/tests/e2ee/mod.rs b/testing/matrix-sdk-integration-testing/src/tests/e2ee/mod.rs index 587866f54..e482037b1 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/e2ee/mod.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/e2ee/mod.rs @@ -1087,7 +1087,7 @@ async fn test_secret_gossip_after_interactive_verification() -> Result<()> { .expect("The event should have been encrypted and successfully decrypted."); let event: OriginalSyncMessageLikeEvent = - timeline_event.raw().deserialize_as()?; + timeline_event.raw().deserialize_as_unchecked()?; let message = event.content.msgtype; assert_let!(MessageType::Text(message) = message); @@ -1141,7 +1141,7 @@ async fn test_recovery_disabling_deletes_secret_storage_secrets() -> Result<()> .expect("The secret event should still exist"); let event = event - .deserialize_as::() + .deserialize_as_unchecked::() .expect("We should be able to deserialize the content of known secrets"); assert!( @@ -1165,7 +1165,7 @@ async fn test_recovery_disabling_deletes_secret_storage_secrets() -> Result<()> .expect("The secret event should still exist"); let event = event - .deserialize_as::() + .deserialize_as_unchecked::() .expect("We should be able to deserialize the content since that's what we uploaded"); assert!( diff --git a/testing/matrix-sdk-test/src/event_factory.rs b/testing/matrix-sdk-test/src/event_factory.rs index eaae11c49..f28c76849 100644 --- a/testing/matrix-sdk-test/src/event_factory.rs +++ b/testing/matrix-sdk-test/src/event_factory.rs @@ -312,7 +312,7 @@ where /// The generic argument `T` allows you to automatically cast the [`Raw`] /// event into any desired type. pub fn into_raw(self) -> Raw { - Raw::new(&self.construct_json(true)).unwrap().cast() + Raw::new(&self.construct_json(true)).unwrap().cast_unchecked() } pub fn into_raw_timeline(self) -> Raw { @@ -320,7 +320,7 @@ where } pub fn into_raw_sync(self) -> Raw { - Raw::new(&self.construct_json(false)).unwrap().cast() + Raw::new(&self.construct_json(false)).unwrap().cast_unchecked() } pub fn into_event(self) -> TimelineEvent { @@ -488,13 +488,13 @@ where impl From> for Raw { fn from(val: EventBuilder) -> Self { - Raw::new(&val.construct_json(false)).unwrap().cast() + Raw::new(&val.construct_json(false)).unwrap().cast_unchecked() } } impl From> for Raw { fn from(val: EventBuilder) -> Self { - Raw::new(&val.construct_json(true)).unwrap().cast() + Raw::new(&val.construct_json(true)).unwrap().cast_unchecked() } } diff --git a/testing/matrix-sdk-test/src/lib.rs b/testing/matrix-sdk-test/src/lib.rs index 78a861512..b96e3fc09 100644 --- a/testing/matrix-sdk-test/src/lib.rs +++ b/testing/matrix-sdk-test/src/lib.rs @@ -18,7 +18,7 @@ macro_rules! message_like_event_content { ($( $tt:tt )*) => { ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* )) .unwrap() - .cast::<::ruma::events::AnyMessageLikeEventContent>() + .cast_unchecked::<::ruma::events::AnyMessageLikeEventContent>() } } @@ -30,7 +30,7 @@ macro_rules! timeline_event { ($( $tt:tt )*) => { ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* )) .unwrap() - .cast::<::ruma::events::AnyTimelineEvent>() + .cast_unchecked::<::ruma::events::AnyTimelineEvent>() } } @@ -42,7 +42,7 @@ macro_rules! sync_timeline_event { ($( $tt:tt )*) => { ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* )) .unwrap() - .cast::<::ruma::events::AnySyncTimelineEvent>() + .cast_unchecked::<::ruma::events::AnySyncTimelineEvent>() } } @@ -54,7 +54,7 @@ macro_rules! sync_state_event { ($( $tt:tt )*) => { ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* )) .unwrap() - .cast::<::ruma::events::AnySyncStateEvent>() + .cast_unchecked::<::ruma::events::AnySyncStateEvent>() } } @@ -66,7 +66,7 @@ macro_rules! stripped_state_event { ($( $tt:tt )*) => { ::ruma::serde::Raw::new(&::serde_json::json!( $($tt)* )) .unwrap() - .cast::<::ruma::events::AnyStrippedStateEvent>() + .cast_unchecked::<::ruma::events::AnyStrippedStateEvent>() } }