From c9362b8605de89219e8dd4db8fe349574383e4a4 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 29 Nov 2025 02:01:30 +0000 Subject: [PATCH] Optimize formatted event serializations. Signed-off-by: Jason Volk --- Cargo.lock | 20 +-- Cargo.toml | 2 +- src/core/matrix/event/format.rs | 246 +++++++++++++++----------------- 3 files changed, 125 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e61ecbf8..d94142d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3659,7 +3659,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.13.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "assign", "js_int", @@ -3678,7 +3678,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.13.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "js_int", "ruma-common", @@ -3690,7 +3690,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.21.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "as_variant", "assign", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.16.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "as_variant", "base64", @@ -3749,7 +3749,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.31.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "as_variant", "indexmap", @@ -3776,7 +3776,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.12.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "bytes", "headers", @@ -3799,7 +3799,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.11.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "js_int", "thiserror 2.0.17", @@ -3808,7 +3808,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.16.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3823,7 +3823,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.12.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "js_int", "ruma-common", @@ -3835,7 +3835,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.18.0" -source = "git+https://github.com/matrix-construct/ruma?rev=4a3dd12e76c80eb60ba5f9324435c8a749cff303#4a3dd12e76c80eb60ba5f9324435c8a749cff303" +source = "git+https://github.com/matrix-construct/ruma?rev=f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2#f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" dependencies = [ "base64", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index df287250..df012a6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -320,7 +320,7 @@ default-features = false [workspace.dependencies.ruma] git = "https://github.com/matrix-construct/ruma" -rev = "4a3dd12e76c80eb60ba5f9324435c8a749cff303" +rev = "f8aa292ce48f28ee6c82b29a811d26c6ccb5aad2" features = [ "__compat", "appservice-api-c", diff --git a/src/core/matrix/event/format.rs b/src/core/matrix/event/format.rs index 20a048b1..57fb259a 100644 --- a/src/core/matrix/event/format.rs +++ b/src/core/matrix/event/format.rs @@ -1,4 +1,5 @@ use ruma::{ + CanonicalJsonMemberOptional as JsonMember, CanonicalJsonMembersOptional as JsonMembers, events::{ AnyMessageLikeEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, @@ -6,7 +7,7 @@ use ruma::{ }, serde::Raw, }; -use serde_json::json; +use serde_json::value::to_raw_value; use super::{Event, redact}; @@ -22,25 +23,20 @@ impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; let (redacts, content) = redact::copy(event); - let mut json = json!({ - "content": content, - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "sender": event.sender(), - "type": event.event_type(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(content.into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("redacts", redacts.map(|e| e.as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(redacts) = redacts { - json["redacts"] = json!(redacts); - } - if let Some(state_key) = event.state_key() { - json["state_key"] = json!(state_key); - } - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -52,26 +48,21 @@ impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; let (redacts, content) = redact::copy(event); - let mut json = json!({ - "content": content, - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "room_id": event.room_id(), - "sender": event.sender(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(content.into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("redacts", redacts.map(|e| e.as_str().into())), + ("room_id", Some(event.room_id().as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(redacts) = redacts { - json["redacts"] = json!(redacts); - } - if let Some(state_key) = event.state_key() { - json["state_key"] = json!(state_key); - } - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -83,26 +74,21 @@ impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; let (redacts, content) = redact::copy(event); - let mut json = json!({ - "content": content, - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "room_id": event.room_id(), - "sender": event.sender(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(content.into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("redacts", redacts.map(|e| e.as_str().into())), + ("room_id", Some(event.room_id().as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(redacts) = &redacts { - json["redacts"] = json!(redacts); - } - if let Some(state_key) = event.state_key() { - json["state_key"] = json!(state_key); - } - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -114,25 +100,20 @@ impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; let (redacts, content) = redact::copy(event); - let mut json = json!({ - "content": content, - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "sender": event.sender(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(content.into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("redacts", redacts.map(|e| e.as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(redacts) = &redacts { - json["redacts"] = json!(redacts); - } - if let Some(state_key) = event.state_key() { - json["state_key"] = json!(state_key); - } - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -143,21 +124,20 @@ impl From> for Raw { impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; - let mut json = json!({ - "content": event.content(), - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "room_id": event.room_id(), - "sender": event.sender(), - "state_key": event.state_key(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(event.content().into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("room_id", Some(event.room_id().as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -168,20 +148,19 @@ impl From> for Raw { impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; - let mut json = json!({ - "content": event.content(), - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "sender": event.sender(), - "state_key": event.state_key(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(event.content().into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -192,14 +171,16 @@ impl From> for Raw { impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; - let json = json!({ - "content": event.content(), - "sender": event.sender(), - "state_key": event.state_key(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(event.content().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ]; - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -210,15 +191,17 @@ impl From> for Raw { impl<'a, E: Event> From> for Raw { fn from(event: Ref<'a, E>) -> Self { let event = event.0; - let json = json!({ - "content": event.content(), - "origin_server_ts": event.origin_server_ts(), - "sender": event.sender(), - "state_key": event.state_key(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(event.content().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ]; - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } } @@ -229,21 +212,20 @@ impl From> for Raw> { impl<'a, E: Event> From> for Raw> { fn from(event: Ref<'a, E>) -> Self { let event = event.0; - let mut json = json!({ - "content": event.content(), - "event_id": event.event_id(), - "origin_server_ts": event.origin_server_ts(), - "redacts": event.redacts(), - "room_id": event.room_id(), - "sender": event.sender(), - "state_key": event.state_key(), - "type": event.kind(), - }); + let members: [JsonMember<_>; _] = [ + ("content", Some(event.content().into())), + ("event_id", Some(event.event_id().as_str().into())), + ("origin_server_ts", Some(event.origin_server_ts().get().into())), + ("redacts", event.redacts().map(|e| e.as_str().into())), + ("room_id", Some(event.room_id().as_str().into())), + ("sender", Some(event.sender().as_str().into())), + ("state_key", event.state_key().map(Into::into)), + ("type", Some(event.event_type().to_string().into())), + ("unsigned", event.unsigned().map(Into::into)), + ]; - if let Some(unsigned) = event.unsigned() { - json["unsigned"] = json!(unsigned); - } - - serde_json::from_value(json).expect("Failed to serialize Event value") + to_raw_value(&JsonMembers(&members)) + .map(Self::from_json) + .expect("Failed to serialize Event value") } }