Upgrade Ruma again

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 <zecakeh@tedomum.fr>
This commit is contained in:
Kévin Commaille
2025-07-22 14:59:26 +02:00
committed by GitHub
parent 37626b5ad9
commit 4931c0749e
72 changed files with 288 additions and 221 deletions
Generated
+8 -8
View File
@@ -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",
+2 -2
View File
@@ -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"] }
@@ -172,7 +172,7 @@ impl TryFrom<SdkPushCondition> 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<PushCondition> for SdkPushCondition {
},
},
PushCondition::SenderNotificationPermission { key } => {
Self::SenderNotificationPermission { key }
Self::SenderNotificationPermission { key: key.into() }
}
PushCondition::EventPropertyIs { key, value } => {
Self::EventPropertyIs { key, value: value.into() }
+1 -1
View File
@@ -1040,7 +1040,7 @@ impl BaseClient {
) -> Result<Ruleset> {
if let Some(event) = global_account_data_processor
.push_rules()
.and_then(|ev| ev.deserialize_as::<PushRulesEvent>().ok())
.and_then(|ev| ev.deserialize_as_unchecked::<PushRulesEvent>().ok())
{
Ok(event.content.global)
} else if let Some(event) = self
@@ -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()),
}
}
}
+1 -2
View File
@@ -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",
@@ -80,7 +80,7 @@ fn apply_changes(
if let Some(event) =
context.state_changes.account_data.get(&GlobalAccountDataEventType::IgnoredUserList)
{
match event.deserialize_as::<IgnoredUserListEvent>() {
match event.deserialize_as_unchecked::<IgnoredUserListEvent>() {
Ok(event) => {
let user_ids: Vec<String> =
event.content.ignored_users.keys().map(|id| id.to_string()).collect();
@@ -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) => {
@@ -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) => {
@@ -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,
}
}))
@@ -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(),
);
}
}
@@ -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<RoomCanonicalAliasEventContent> {
+3 -3
View File
@@ -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);
+4 -4
View File
@@ -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;
+7 -7
View File
@@ -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<C: StateEventContent, E>(
@@ -2796,6 +2796,6 @@ mod tests {
"unsigned": unsigned,
}))
.expect("Failed to create state event")
.cast()
.cast_unchecked()
}
}
@@ -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<StrippedRoomMemberE
"state_key": user_id,
});
Raw::new(&ev_json).unwrap().cast()
Raw::new(&ev_json).unwrap().cast_unchecked()
}
fn membership_event() -> Raw<SyncRoomMemberEvent> {
@@ -1986,7 +1987,7 @@ fn custom_membership_event(user_id: &UserId, event_id: &EventId) -> Raw<SyncRoom
"state_key": user_id,
});
Raw::new(&ev_json).unwrap().cast()
Raw::new(&ev_json).unwrap().cast_unchecked()
}
fn custom_presence_event(user_id: &UserId) -> Raw<PresenceEvent> {
@@ -1997,5 +1998,5 @@ fn custom_presence_event(user_id: &UserId) -> Raw<PresenceEvent> {
"sender": user_id,
});
Raw::new(&ev_json).unwrap().cast()
Raw::new(&ev_json).unwrap().cast_unchecked()
}
@@ -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::<SyncRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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::<SyncRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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::<StrippedRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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::<StrippedRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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();
}
}
}
+6 -2
View File
@@ -579,7 +579,11 @@ impl StateChanges {
C::StateKey: Borrow<K>,
K: AsRef<str> + ?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
+5 -2
View File
@@ -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.
+3 -1
View File
@@ -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")
@@ -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<SyncTimelineEventDeserializationHelperV0> 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()),
@@ -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),
@@ -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:?}")
});
@@ -587,12 +587,12 @@ impl IdentityManager {
master_key: &Raw<CrossSigningKey>,
response: &KeysQueryResponse,
) -> Option<(MasterPubkey, SelfSigningPubkey)> {
match master_key.deserialize_as::<MasterPubkey>() {
match master_key.deserialize_as_unchecked::<MasterPubkey>() {
Ok(master_key) => {
if let Some(self_signing) = response
.self_signing_keys
.get(master_key.user_id())
.and_then(|k| k.deserialize_as::<SelfSigningPubkey>().ok())
.and_then(|k| k.deserialize_as_unchecked::<SelfSigningPubkey>().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::<UserSigningPubkey>().ok())
.and_then(|k| k.deserialize_as_unchecked::<UserSigningPubkey>().ok())
else {
warn!(
"User identity for our own user didn't contain a user signing pubkey or the key \
+1 -1
View File
@@ -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;
///
+2 -2
View File
@@ -1067,7 +1067,7 @@ impl OlmMachine {
content: impl MessageLikeEventContent,
) -> MegolmResult<Raw<RoomEncryptedEventContent>> {
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::<ToDeviceStub<'_>>() {
if let Ok(event) = event.deserialize_as_unchecked::<ToDeviceStub<'_>>() {
Span::current().record("sender", event.sender);
Span::current().record("event_type", event.event_type);
Span::current().record("message_id", event.content.message_id);
@@ -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()
@@ -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::<RoomKeyWithheldContent>()
.deserialize_as_unchecked::<RoomKeyWithheldContent>()
.expect("Deserialize should work");
let event = ToDeviceEvent::new(alice.user_id().to_owned(), wh_content);
@@ -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.
@@ -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::<ContentStub<'_>>()
.deserialize_as_unchecked::<ContentStub<'_>>()
.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::<RoomKeyWithheldContent>().unwrap();
content.deserialize_as_unchecked::<RoomKeyWithheldContent>().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::<RoomKeyWithheldContent>().unwrap();
content.deserialize_as_unchecked::<RoomKeyWithheldContent>().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 {
@@ -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<ruma::api::client::backup::BackupAlgorithm> for RoomKeyBackupInfo {}
impl JsonCastable<RoomKeyBackupInfo> for ruma::api::client::backup::BackupAlgorithm {}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct BackupInfoHelper {
algorithm: String,
@@ -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<CrossSigningKey> 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
@@ -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.
@@ -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<DeviceKeys> for ruma::encryption::DeviceKeys {}
/// Additional data added to device key information by intermediate servers.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct UnsignedDeviceInfo {
@@ -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<EncryptedEvent>
for ruma::events::room::encrypted::OriginalSyncRoomEncryptedEvent
{
}
/// An m.room.encrypted to-device event.
pub type EncryptedToDeviceEvent = ToDeviceEvent<ToDeviceEncryptedEventContent>;
@@ -95,6 +100,8 @@ impl EventType for ToDeviceEncryptedEventContent {
const EVENT_TYPE: &'static str = "m.room.encrypted";
}
impl JsonCastable<AnyToDeviceEventContent> 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<ruma::events::AnyMessageLikeEventContent> for RoomEncryptedEventContent {}
/// An enum for per encryption algorithm event contents.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(try_from = "Helper")]
@@ -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<AnyToDeviceEventContent> 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")]
@@ -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<AnyToDeviceEventContent> for RoomKeyWithheldContent {}
#[derive(Debug, Deserialize, Serialize)]
struct WithheldHelper {
pub algorithm: EventEncryptionAlgorithm,
@@ -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<ToDeviceEvents> for ruma::events::AnyToDeviceEvent {}
impl JsonCastable<ruma::events::AnyToDeviceEvent> for ToDeviceEvents {}
/// A to-device event with an unknown type and content.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ToDeviceCustomEvent {
@@ -114,7 +114,7 @@ impl OneTimeKey {
) -> Result<Self, serde_json::Error> {
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}"))),
@@ -1234,12 +1234,13 @@ mod tests {
let room_id = room_id!("!room:localhost");
let member_event =
Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast::<SyncRoomMemberEvent>();
Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast_unchecked::<SyncRoomMemberEvent>();
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::<StrippedRoomMemberEvent>();
let stripped_member_event = Raw::new(&*test_json::MEMBER_STRIPPED)
.unwrap()
.cast_unchecked::<StrippedRoomMemberEvent>();
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::<SyncRoomMemberEvent>();
Raw::new(&*test_json::MEMBER_INVITE).unwrap().cast_unchecked::<SyncRoomMemberEvent>();
let invite_user_id = user_id!("@invited:localhost");
let ban_member_event =
Raw::new(&*test_json::MEMBER_BAN).unwrap().cast::<SyncRoomMemberEvent>();
Raw::new(&*test_json::MEMBER_BAN).unwrap().cast_unchecked::<SyncRoomMemberEvent>();
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::<StrippedRoomMemberEvent>();
let stripped_member_event = Raw::new(&*test_json::MEMBER_STRIPPED)
.unwrap()
.cast_unchecked::<StrippedRoomMemberEvent>();
let stripped_user_id = user_id!("@example:localhost");
// Populate DB with old table.
@@ -758,15 +758,16 @@ impl_state_store!({
stripped_state.delete(&key)?;
if *event_type == StateEventType::RoomMember {
let event = match raw_event.deserialize_as::<SyncRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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::<SyncRoomMemberEvent>() {
Ok(ev) => ev,
Err(e) => {
let event_id: Option<String> =
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::<StrippedRoomMemberEvent>()
let event = match raw_event
.deserialize_as_unchecked::<StrippedRoomMemberEvent>()
{
Ok(ev) => ev,
Err(e) => {
+2 -2
View File
@@ -1153,7 +1153,7 @@ impl StateStore for SqliteStateStore {
if event_type == StateEventType::RoomMember {
let member_event = match raw_state_event
.deserialize_as::<SyncRoomMemberEvent>()
.deserialize_as_unchecked::<SyncRoomMemberEvent>()
{
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::<StrippedRoomMemberEvent>(
.deserialize_as_unchecked::<StrippedRoomMemberEvent>(
) {
Ok(ev) => ev,
Err(e) => {
@@ -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, ..
@@ -185,7 +185,7 @@ mod tests {
"pinned": ids,
}))
.unwrap()
.cast::<PossiblyRedactedRoomPinnedEventsEventContent>()
.cast_unchecked::<PossiblyRedactedRoomPinnedEventsEventContent>()
.deserialize()
.ok()
}
@@ -1076,7 +1076,7 @@ mod tests {
.display_name("Alice Margatroid")
.reason("")
.into_raw_sync()
.deserialize_as::<OriginalMinimalStateEvent<RoomMemberEventContent>>()
.deserialize_as_unchecked::<OriginalMinimalStateEvent<RoomMemberEventContent>>()
.unwrap(),
);
@@ -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,
},
@@ -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))
+2 -2
View File
@@ -323,7 +323,7 @@ impl Decryptor for Room {
raw: &Raw<AnySyncTimelineEvent>,
push_ctx: Option<&PushContext>,
) -> Result<TimelineEvent> {
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) => {
@@ -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::<AnyStateEvent>()]
"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
@@ -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)
+3 -3
View File
@@ -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::<IgnoredUserListEventContent>()?;
/// let content = raw_content.deserialize_as_unchecked::<IgnoredUserListEventContent>()?;
///
/// 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<Ev, C>(raw: Option<Raw<Ev>>) -> Result<Option<Raw<C>>> {
}
Ok(raw
.map(|event| event.deserialize_as::<GetRawContent<C>>())
.map(|event| event.deserialize_as_unchecked::<GetRawContent<C>>())
.transpose()?
.map(|get_raw| get_raw.content))
}
@@ -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?;
}
}
@@ -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::<SecretEventContent>()?;
let mut secret_content =
secret_content.deserialize_as_unchecked::<SecretEventContent>()?;
// 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::<SecretEventContent>()
.deserialize_as_unchecked::<SecretEventContent>()
.unwrap_or_else(|_| SecretEventContent::new(Default::default()))
} else {
SecretEventContent::new(Default::default())
+4 -4
View File
@@ -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;
@@ -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::<SyncRoomRedactionEvent>(),
event.raw().cast_ref_unchecked::<SyncRoomRedactionEvent>(),
&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?;
}
+5 -4
View File
@@ -349,7 +349,7 @@ impl Client {
}
for raw_event in events {
let event_type = raw_event.deserialize_as::<ExtractType<'_>>()?.event_type;
let event_type = raw_event.deserialize_as_unchecked::<ExtractType<'_>>()?.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::<ExtractType<'_>>()?.event_type;
let event_type = raw_event.deserialize_as_unchecked::<ExtractType<'_>>()?.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 {
+10 -8
View File
@@ -579,7 +579,7 @@ impl Room {
SyncMessageLikeEvent::Original(_),
))) = event.deserialize_as::<AnySyncTimelineEvent>()
{
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::<RoomEncryptionEventContent>()?)
}
Ok(response) => Some(
response
.content
.deserialize_as_unchecked::<RoomEncryptionEventContent>()?,
),
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::<RoomPinnedEventsEventContent>()?.pinned))
}
Ok(response) => Ok(Some(
response.content.deserialize_as_unchecked::<RoomPinnedEventsEventContent>()?.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()),
@@ -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()
+2 -2
View File
@@ -126,7 +126,7 @@ impl IntoRawMessageLikeEventContent for JsonValue {
impl IntoRawMessageLikeEventContent for &JsonValue {
fn into_raw_message_like_event_content(self) -> Raw<AnyMessageLikeEventContent> {
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<AnyStateEventContent> {
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()
}
}
+11 -3
View File
@@ -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<AnyStateEvent>> for FilterInput<'a> {
}
}
impl<'a> JsonCastable<FilterInput<'a>> for AnyTimelineEvent {}
impl<'a> JsonCastable<FilterInput<'a>> for AnyStateEvent {}
impl<'a> JsonCastable<FilterInput<'a>> for AnyMessageLikeEvent {}
#[derive(Debug, Deserialize)]
pub struct FilterInputToDevice<'a> {
#[serde(rename = "type")]
@@ -252,6 +258,8 @@ impl<'a> TryFrom<&'a Raw<AnyToDeviceEvent>> for FilterInput<'a> {
}
}
impl<'a> JsonCastable<FilterInputToDevice<'a>> for AnyToDeviceEvent {}
impl<'a> From<&'a SendToDeviceRequest> for FilterInput<'a> {
fn from(request: &'a SendToDeviceRequest) -> Self {
FilterInput::ToDevice(FilterInputToDevice { event_type: &request.event_type })
+2 -2
View File
@@ -621,8 +621,8 @@ impl WidgetMachine {
response_data: impl Serialize,
) -> Action {
let f = || {
let mut object =
raw_request.deserialize_as::<IndexMap<String, Box<RawJsonValue>>>()?;
let mut object = raw_request
.deserialize_as_unchecked::<IndexMap<String, Box<RawJsonValue>>>()?;
let response_data = serde_json::value::to_raw_value(&response_data)?;
object.insert("response".to_owned(), response_data);
serde_json::to_string(&object)
+7 -6
View File
@@ -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::<String>("state_key").is_ok_and(|key| match state_key {
@@ -548,13 +548,14 @@ impl StateUpdateReceiver {
}
fn attach_room_id(raw_ev: &Raw<AnySyncTimelineEvent>, room_id: &RoomId) -> Raw<AnyTimelineEvent> {
let mut ev_obj = raw_ev.deserialize_as::<BTreeMap<String, Box<RawJsonValue>>>().unwrap();
let mut ev_obj =
raw_ev.deserialize_as_unchecked::<BTreeMap<String, Box<RawJsonValue>>>().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<AnySyncStateEvent>, room_id: &RoomId) -> Raw<AnyStateEvent> {
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);
@@ -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);
@@ -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");
@@ -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;
@@ -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"))
@@ -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::<AnySyncMessageLikeEvent>().deserialize().unwrap();
let ev = events[0].raw().cast_ref_unchecked::<AnySyncMessageLikeEvent>().deserialize().unwrap();
assert!(ev.is_redacted());
// And the redacted event.
@@ -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"
@@ -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;
@@ -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<RoomMessageEventContent> =
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::<SecretEventContent>()
.deserialize_as_unchecked::<SecretEventContent>()
.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::<SecretEventContent>()
.deserialize_as_unchecked::<SecretEventContent>()
.expect("We should be able to deserialize the content since that's what we uploaded");
assert!(
+4 -4
View File
@@ -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<T>(self) -> Raw<T> {
Raw::new(&self.construct_json(true)).unwrap().cast()
Raw::new(&self.construct_json(true)).unwrap().cast_unchecked()
}
pub fn into_raw_timeline(self) -> Raw<AnyTimelineEvent> {
@@ -320,7 +320,7 @@ where
}
pub fn into_raw_sync(self) -> Raw<AnySyncTimelineEvent> {
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<E: StaticEventContent + StateEventContent> From<EventBuilder<E>> for Raw<AnySyncStateEvent> {
fn from(val: EventBuilder<E>) -> Self {
Raw::new(&val.construct_json(false)).unwrap().cast()
Raw::new(&val.construct_json(false)).unwrap().cast_unchecked()
}
}
impl<E: StaticEventContent + StateEventContent> From<EventBuilder<E>> for Raw<AnyStateEvent> {
fn from(val: EventBuilder<E>) -> Self {
Raw::new(&val.construct_json(true)).unwrap().cast()
Raw::new(&val.construct_json(true)).unwrap().cast_unchecked()
}
}
+5 -5
View File
@@ -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>()
}
}