Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add is_compatible method to event content enums to fix Any*Event deserialization #52

Merged
merged 5 commits into from Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion ruma-events-macros/src/content_enum.rs
Expand Up @@ -9,7 +9,7 @@ use syn::{

/// Create a content enum from `ContentEnumInput`.
///
/// The is the internals of the `event_content_enum!` macro.
/// This is the internals of the `event_content_enum!` macro.
pub fn expand_content_enum(input: ContentEnumInput) -> syn::Result<TokenStream> {
let attrs = &input.attrs;
let ident = &input.name;
Expand Down
113 changes: 46 additions & 67 deletions ruma-events/benches/event_deserialize.rs
@@ -1,18 +1,18 @@
// In order to run use either `cargo bench` or to save if you
// want to save the result to compare branches use
// `cargo bench --bench event_deserialize -- --save-baseline test-output`
// Since we are in a workspace the default `cargo bench` still picks up
// the args passed to it to avoid this use the above command.
// `cargo bench` works but if you use `cargo bench -- --save-baseline <name>`
DevinR528 marked this conversation as resolved.
Show resolved Hide resolved
// or pass any other args to it it fails with the error
jplatte marked this conversation as resolved.
Show resolved Hide resolved
// `cargo bench unknown option --save-baseline`.
// To pass args to criterion use this form
jplatte marked this conversation as resolved.
Show resolved Hide resolved
// `cargo bench --bench <name of the bench> -- --save-baseline <name>`

use criterion::{criterion_group, criterion_main, Criterion};
use ruma_events::{
room::{message::MessageEventContent, power_levels::PowerLevelsEventContent},
AnyRoomEventStub, EventJson, MessageEvent, StateEventStub,
room::power_levels::PowerLevelsEventContent, AnyEvent, AnyRoomEvent, AnyStateEvent, EventJson,
StateEvent,
};
use serde_json::json;

fn deserialize_any_event_stub(c: &mut Criterion) {
let json_data = json!({
fn power_levels() -> serde_json::Value {
json!({
"content": {
"ban": 50,
"events": {
Expand All @@ -35,82 +35,60 @@ fn deserialize_any_event_stub(c: &mut Criterion) {
"event_id": "$15139375512JaHAW:localhost",
"origin_server_ts": 45,
"sender": "@example:localhost",
"room_id": "!room:localhost",
"state_key": "",
"type": "m.room.power_levels",
"unsigned": {
"age": 45
}
});
c.bench_function("deserialize to `AnyRoomEventStub`", |b| {
})
}

fn deserialize_any_event(c: &mut Criterion) {
let json_data = power_levels();

c.bench_function("deserialize to `AnyEvent`", |b| {
b.iter(|| {
let _ = serde_json::from_value::<EventJson<AnyRoomEventStub>>(json_data.clone())
let _ = serde_json::from_value::<EventJson<AnyEvent>>(json_data.clone())
.unwrap()
.deserialize()
.unwrap();
})
});
}

fn deserialize_specific_event_stub(c: &mut Criterion) {
let json_data = json!({
"content": {
"ban": 50,
"events": {
"m.room.avatar": 50,
"m.room.canonical_alias": 50,
"m.room.history_visibility": 100,
"m.room.name": 50,
"m.room.power_levels": 100
},
"events_default": 0,
"invite": 0,
"kick": 50,
"redact": 50,
"state_default": 50,
"users": {
"@example:localhost": 100
},
"users_default": 0
},
"event_id": "$15139375512JaHAW:localhost",
"origin_server_ts": 45,
"sender": "@example:localhost",
"state_key": "",
"type": "m.room.power_levels",
"unsigned": {
"age": 45
}
});
c.bench_function("deserialize to `StateEventStub<PowerLevelsEventContent>`", |b| {
fn deserialize_any_room_event(c: &mut Criterion) {
let json_data = power_levels();

c.bench_function("deserialize to `AnyRoomEvent`", |b| {
b.iter(|| {
let _ = serde_json::from_value::<EventJson<StateEventStub<PowerLevelsEventContent>>>(
json_data.clone(),
)
.unwrap()
.deserialize()
.unwrap();
let _ = serde_json::from_value::<EventJson<AnyRoomEvent>>(json_data.clone())
.unwrap()
.deserialize()
.unwrap();
})
});
}

fn deserialize_message_event(c: &mut Criterion) {
let json_data = json!({
"type": "m.room.message",
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 10_000,
"room_id": "!testroomid:example.org",
"sender": "@user:example.org",
"content": {
"body": "Hello, World!",
"msgtype": "m.text",
"format": "org.matrix.custom.html",
"formatted_body": "Hello, <em>World</em>!",
}
fn deserialize_any_state_event(c: &mut Criterion) {
let json_data = power_levels();

c.bench_function("deserialize to `AnyStateEvent`", |b| {
b.iter(|| {
let _ = serde_json::from_value::<EventJson<AnyStateEvent>>(json_data.clone())
.unwrap()
.deserialize()
.unwrap();
})
});
}

fn deserialize_specific_event(c: &mut Criterion) {
let json_data = power_levels();

c.bench_function("deserialize to `MessageEvent<MessageEventContent>`", |b| {
c.bench_function("deserialize to `StateEvent<PowerLevelsEventContent>`", |b| {
b.iter(|| {
let _ = serde_json::from_value::<EventJson<MessageEvent<MessageEventContent>>>(
let _ = serde_json::from_value::<EventJson<StateEvent<PowerLevelsEventContent>>>(
json_data.clone(),
)
.unwrap()
Expand All @@ -122,9 +100,10 @@ fn deserialize_message_event(c: &mut Criterion) {

criterion_group!(
benches,
deserialize_any_event_stub,
deserialize_specific_event_stub,
deserialize_message_event
deserialize_any_event,
deserialize_any_room_event,
deserialize_any_state_event,
deserialize_specific_event
);

criterion_main!(benches);
6 changes: 3 additions & 3 deletions ruma-events/src/enums.rs
Expand Up @@ -126,12 +126,12 @@ pub type AnyToDeviceEvent = ToDeviceEvent<AnyToDeviceEventContent>;
pub enum AnyEvent {
/// Any basic event.
Basic(AnyBasicEvent),
/// `"m.presence"`, the only non-room event with a `sender` field.
Presence(PresenceEvent),
/// Any ephemeral room event.
Ephemeral(AnyEphemeralRoomEvent),
/// Any message event.
Message(AnyMessageEvent),
/// `"m.presence"`, the only non-room event with a `sender` field.
Presence(PresenceEvent),
/// `"m.room.redaction"`, the only room event with a `redacts` field.
Redaction(RedactionEvent),
/// Any state event.
Expand Down Expand Up @@ -163,7 +163,7 @@ pub enum AnyRoomEventStub {
}

// FIXME `#[serde(untagged)]` deserialization fails for these enums which
// is odd as
// is odd as we are doing basically the same thing here, investigate?
impl<'de> de::Deserialize<'de> for AnyEvent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down