Add into_full_event and From<> impls to convert between sync and full events
This commit is contained in:
parent
3329dc7345
commit
4be63127f7
@ -4,13 +4,13 @@ use proc_macro2::{Span, TokenStream};
|
|||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
||||||
|
|
||||||
use crate::event_parse::{to_kind_variation, EventKindVariation};
|
use crate::event_parse::{to_kind_variation, EventKind, EventKindVariation};
|
||||||
|
|
||||||
/// Derive `Event` macro code generation.
|
/// Derive `Event` macro code generation.
|
||||||
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
|
|
||||||
let (_kind, var) = to_kind_variation(ident).ok_or_else(|| {
|
let (kind, var) = to_kind_variation(ident).ok_or_else(|| {
|
||||||
syn::Error::new(Span::call_site(), "not a valid ruma event struct identifier")
|
syn::Error::new(Span::call_site(), "not a valid ruma event struct identifier")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -99,9 +99,13 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let deserialize_impl = expand_deserialize_event(input, &var, fields, is_generic)?;
|
let deserialize_impl = expand_deserialize_event(&input, &var, &fields, is_generic)?;
|
||||||
|
|
||||||
|
let conversion_impl = expand_from_into(&input, &kind, &var, &fields);
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
|
#conversion_impl
|
||||||
|
|
||||||
#serialize_impl
|
#serialize_impl
|
||||||
|
|
||||||
#deserialize_impl
|
#deserialize_impl
|
||||||
@ -109,9 +113,9 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expand_deserialize_event(
|
fn expand_deserialize_event(
|
||||||
input: DeriveInput,
|
input: &DeriveInput,
|
||||||
var: &EventKindVariation,
|
var: &EventKindVariation,
|
||||||
fields: Vec<Field>,
|
fields: &[Field],
|
||||||
is_generic: bool,
|
is_generic: bool,
|
||||||
) -> syn::Result<TokenStream> {
|
) -> syn::Result<TokenStream> {
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
@ -309,6 +313,58 @@ fn expand_deserialize_event(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expand_from_into(
|
||||||
|
input: &DeriveInput,
|
||||||
|
kind: &EventKind,
|
||||||
|
var: &EventKindVariation,
|
||||||
|
fields: &[Field],
|
||||||
|
) -> Option<TokenStream> {
|
||||||
|
let ident = &input.ident;
|
||||||
|
|
||||||
|
let (impl_generics, ty_gen, where_clause) = input.generics.split_for_impl();
|
||||||
|
|
||||||
|
let fields = fields.iter().flat_map(|f| &f.ident).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let fields_without_unsigned =
|
||||||
|
fields.iter().filter(|id| id.to_string().as_str() != "unsigned").collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let (into, into_full_event) = if var.is_redacted() {
|
||||||
|
(quote! { unsigned: unsigned.into(), }, quote! { unsigned: unsigned.into_full(room_id), })
|
||||||
|
} else if kind == &EventKind::Ephemeral {
|
||||||
|
(TokenStream::new(), TokenStream::new())
|
||||||
|
} else {
|
||||||
|
(quote! { unsigned, }, quote! { unsigned, })
|
||||||
|
};
|
||||||
|
|
||||||
|
if let EventKindVariation::Sync | EventKindVariation::RedactedSync = var {
|
||||||
|
let full_struct = kind.to_event_ident(&var.to_full_variation());
|
||||||
|
Some(quote! {
|
||||||
|
impl #impl_generics From<#full_struct #ty_gen> for #ident #ty_gen #where_clause {
|
||||||
|
fn from(event: #full_struct #ty_gen) -> Self {
|
||||||
|
let #full_struct {
|
||||||
|
#( #fields, )* ..
|
||||||
|
} = event;
|
||||||
|
Self { #( #fields_without_unsigned, )* #into }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl #impl_generics #ident #ty_gen #where_clause {
|
||||||
|
/// Convert this sync event into a full event, one with a room_id field.
|
||||||
|
pub fn into_full_event(self, room_id: ::ruma_identifiers::RoomId) -> #full_struct #ty_gen {
|
||||||
|
let Self { #( #fields, )* } = self;
|
||||||
|
#full_struct {
|
||||||
|
#( #fields_without_unsigned, )*
|
||||||
|
room_id: room_id.clone(),
|
||||||
|
#into_full_event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// CamelCase's a field ident like "foo_bar" to "FooBar".
|
/// CamelCase's a field ident like "foo_bar" to "FooBar".
|
||||||
fn to_camel_case(name: &Ident) -> Ident {
|
fn to_camel_case(name: &Ident) -> Ident {
|
||||||
let span = name.span();
|
let span = name.span();
|
||||||
|
@ -122,6 +122,8 @@ fn expand_any_with_deser(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let event_enum_to_from_sync = expand_conversion_impl(kind, var, &variants);
|
||||||
|
|
||||||
let redacted_enum = expand_redacted_enum(kind, var);
|
let redacted_enum = expand_redacted_enum(kind, var);
|
||||||
|
|
||||||
let field_accessor_impl = accessor_methods(kind, var, &variants);
|
let field_accessor_impl = accessor_methods(kind, var, &variants);
|
||||||
@ -131,6 +133,8 @@ fn expand_any_with_deser(
|
|||||||
Some(quote! {
|
Some(quote! {
|
||||||
#any_enum
|
#any_enum
|
||||||
|
|
||||||
|
#event_enum_to_from_sync
|
||||||
|
|
||||||
#field_accessor_impl
|
#field_accessor_impl
|
||||||
|
|
||||||
#redact_impl
|
#redact_impl
|
||||||
@ -141,6 +145,104 @@ fn expand_any_with_deser(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expand_conversion_impl(
|
||||||
|
kind: &EventKind,
|
||||||
|
var: &EventKindVariation,
|
||||||
|
variants: &[Ident],
|
||||||
|
) -> Option<TokenStream> {
|
||||||
|
let ident = kind.to_event_enum_ident(var)?;
|
||||||
|
let variants = &variants
|
||||||
|
.iter()
|
||||||
|
.filter(|id| {
|
||||||
|
// We filter this variant out only for non redacted events.
|
||||||
|
// The type of the struct held in the enum variant is different in this case
|
||||||
|
// so we construct the variant manually.
|
||||||
|
!(id.to_string().as_str() == "RoomRedaction"
|
||||||
|
&& matches!(var, EventKindVariation::Full | EventKindVariation::Sync))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
match var {
|
||||||
|
EventKindVariation::Full | EventKindVariation::Redacted => {
|
||||||
|
// the opposite event variation full -> sync, redacted -> redacted sync
|
||||||
|
let variation = if var == &EventKindVariation::Full {
|
||||||
|
EventKindVariation::Sync
|
||||||
|
} else {
|
||||||
|
EventKindVariation::RedactedSync
|
||||||
|
};
|
||||||
|
|
||||||
|
let sync = kind.to_event_enum_ident(&variation)?;
|
||||||
|
let sync_struct = kind.to_event_ident(&variation)?;
|
||||||
|
|
||||||
|
let redaction = if let (EventKind::Message, EventKindVariation::Full) = (kind, var) {
|
||||||
|
quote! {
|
||||||
|
#ident::RoomRedaction(event) => {
|
||||||
|
Self::RoomRedaction(::ruma_events::room::redaction::SyncRedactionEvent::from(event))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TokenStream::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
impl From<#ident> for #sync {
|
||||||
|
fn from(event: #ident) -> Self {
|
||||||
|
match event {
|
||||||
|
#(
|
||||||
|
#ident::#variants(event) => {
|
||||||
|
Self::#variants(::ruma_events::#sync_struct::from(event))
|
||||||
|
},
|
||||||
|
)*
|
||||||
|
#redaction
|
||||||
|
#ident::Custom(event) => {
|
||||||
|
Self::Custom(::ruma_events::#sync_struct::from(event))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
EventKindVariation::Sync | EventKindVariation::RedactedSync => {
|
||||||
|
let variation = if var == &EventKindVariation::Sync {
|
||||||
|
EventKindVariation::Full
|
||||||
|
} else {
|
||||||
|
EventKindVariation::Redacted
|
||||||
|
};
|
||||||
|
let full = kind.to_event_enum_ident(&variation)?;
|
||||||
|
|
||||||
|
let redaction = if let (EventKind::Message, EventKindVariation::Sync) = (kind, var) {
|
||||||
|
quote! {
|
||||||
|
Self::RoomRedaction(event) => {
|
||||||
|
#full::RoomRedaction(event.into_full_event(room_id))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TokenStream::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
impl #ident {
|
||||||
|
/// Convert this sync event into a full event, one with a room_id field.
|
||||||
|
pub fn into_full_event(self, room_id: ::ruma_identifiers::RoomId) -> #full {
|
||||||
|
match self {
|
||||||
|
#(
|
||||||
|
Self::#variants(event) => {
|
||||||
|
#full::#variants(event.into_full_event(room_id))
|
||||||
|
},
|
||||||
|
)*
|
||||||
|
#redaction
|
||||||
|
Self::Custom(event) => {
|
||||||
|
#full::Custom(event.into_full_event(room_id))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generates the 3 redacted state enums, 2 redacted message enums,
|
/// Generates the 3 redacted state enums, 2 redacted message enums,
|
||||||
/// and `Deserialize` implementations.
|
/// and `Deserialize` implementations.
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use matches::matches;
|
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use quote::format_ident;
|
use quote::format_ident;
|
||||||
use syn::{
|
use syn::{
|
||||||
@ -44,9 +43,21 @@ impl EventKindVariation {
|
|||||||
pub fn is_redacted(&self) -> bool {
|
pub fn is_redacted(&self) -> bool {
|
||||||
matches!(self, Self::Redacted | Self::RedactedSync | Self::RedactedStripped)
|
matches!(self, Self::Redacted | Self::RedactedSync | Self::RedactedStripped)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_full_variation(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
EventKindVariation::Redacted
|
||||||
|
| EventKindVariation::RedactedSync
|
||||||
|
| EventKindVariation::RedactedStripped => EventKindVariation::Redacted,
|
||||||
|
EventKindVariation::Full | EventKindVariation::Sync | EventKindVariation::Stripped => {
|
||||||
|
EventKindVariation::Full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the variants of this enum change `to_event_path` needs to be updated as well.
|
// If the variants of this enum change `to_event_path` needs to be updated as well.
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum EventKind {
|
pub enum EventKind {
|
||||||
Basic,
|
Basic,
|
||||||
Ephemeral,
|
Ephemeral,
|
||||||
|
@ -121,6 +121,7 @@ use std::fmt::Debug;
|
|||||||
|
|
||||||
use js_int::Int;
|
use js_int::Int;
|
||||||
use ruma_common::Raw;
|
use ruma_common::Raw;
|
||||||
|
use ruma_identifiers::RoomId;
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{self, IgnoredAny},
|
de::{self, IgnoredAny},
|
||||||
Deserialize, Serialize,
|
Deserialize, Serialize,
|
||||||
@ -246,6 +247,32 @@ pub struct RedactedSyncUnsigned {
|
|||||||
pub redacted_because: Option<Box<SyncRedactionEvent>>,
|
pub redacted_because: Option<Box<SyncRedactionEvent>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RedactedUnsigned> for RedactedSyncUnsigned {
|
||||||
|
fn from(redacted: RedactedUnsigned) -> Self {
|
||||||
|
match redacted.redacted_because.map(|b| *b) {
|
||||||
|
Some(RedactionEvent {
|
||||||
|
sender,
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
redacts,
|
||||||
|
unsigned,
|
||||||
|
content,
|
||||||
|
..
|
||||||
|
}) => Self {
|
||||||
|
redacted_because: Some(Box::new(SyncRedactionEvent {
|
||||||
|
sender,
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
redacts,
|
||||||
|
unsigned,
|
||||||
|
content,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
_ => Self { redacted_because: None },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RedactedSyncUnsigned {
|
impl RedactedSyncUnsigned {
|
||||||
/// Whether this unsigned data is empty (`redacted_because` is `None`).
|
/// Whether this unsigned data is empty (`redacted_because` is `None`).
|
||||||
///
|
///
|
||||||
@ -256,6 +283,32 @@ impl RedactedSyncUnsigned {
|
|||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.redacted_because.is_none()
|
self.redacted_because.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a `RedactedSyncUnsigned` into `RedactedUnsigned`, converting the
|
||||||
|
/// underlying sync redaction event to a full redaction event (with room_id).
|
||||||
|
pub fn into_full(self, room_id: RoomId) -> RedactedUnsigned {
|
||||||
|
match self.redacted_because.map(|b| *b) {
|
||||||
|
Some(SyncRedactionEvent {
|
||||||
|
sender,
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
redacts,
|
||||||
|
unsigned,
|
||||||
|
content,
|
||||||
|
}) => RedactedUnsigned {
|
||||||
|
redacted_because: Some(Box::new(RedactionEvent {
|
||||||
|
room_id,
|
||||||
|
sender,
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
redacts,
|
||||||
|
unsigned,
|
||||||
|
content,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
_ => RedactedUnsigned { redacted_because: None },
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The base trait that all event content types implement.
|
/// The base trait that all event content types implement.
|
||||||
|
@ -3,14 +3,14 @@ use std::{
|
|||||||
time::{Duration, UNIX_EPOCH},
|
time::{Duration, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::{uint, UInt};
|
||||||
use matches::assert_matches;
|
use matches::assert_matches;
|
||||||
use ruma_common::Raw;
|
use ruma_common::Raw;
|
||||||
use ruma_events::{
|
use ruma_events::{
|
||||||
call::{answer::AnswerEventContent, SessionDescription, SessionDescriptionType},
|
call::{answer::AnswerEventContent, SessionDescription, SessionDescriptionType},
|
||||||
room::{ImageInfo, ThumbnailInfo},
|
room::{ImageInfo, ThumbnailInfo},
|
||||||
sticker::StickerEventContent,
|
sticker::StickerEventContent,
|
||||||
AnyMessageEventContent, MessageEvent, RawExt, Unsigned,
|
AnyMessageEventContent, AnySyncMessageEvent, MessageEvent, RawExt, Unsigned,
|
||||||
};
|
};
|
||||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||||
@ -222,3 +222,58 @@ fn deserialize_message_sticker() {
|
|||||||
&& unsigned.is_empty()
|
&& unsigned.is_empty()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_message_then_convert_to_full() {
|
||||||
|
let rid = RoomId::try_from("!roomid:room.com").unwrap();
|
||||||
|
let json_data = json!({
|
||||||
|
"content": {
|
||||||
|
"answer": {
|
||||||
|
"type": "answer",
|
||||||
|
"sdp": "Hello"
|
||||||
|
},
|
||||||
|
"call_id": "foofoo",
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"event_id": "$h29iv0s8:example.com",
|
||||||
|
"origin_server_ts": 1,
|
||||||
|
"sender": "@carl:example.com",
|
||||||
|
"type": "m.call.answer"
|
||||||
|
});
|
||||||
|
|
||||||
|
let sync_ev =
|
||||||
|
from_json_value::<Raw<AnySyncMessageEvent>>(json_data).unwrap().deserialize().unwrap();
|
||||||
|
|
||||||
|
// Test conversion method
|
||||||
|
let full = sync_ev.into_full_event(rid);
|
||||||
|
let full_json = to_json_value(full).unwrap();
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
from_json_value::<Raw<MessageEvent<AnyMessageEventContent>>>(full_json)
|
||||||
|
.unwrap()
|
||||||
|
.deserialize()
|
||||||
|
.unwrap(),
|
||||||
|
MessageEvent {
|
||||||
|
content: AnyMessageEventContent::CallAnswer(AnswerEventContent {
|
||||||
|
answer: SessionDescription {
|
||||||
|
session_type: SessionDescriptionType::Answer,
|
||||||
|
sdp,
|
||||||
|
},
|
||||||
|
call_id,
|
||||||
|
version,
|
||||||
|
}),
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
room_id,
|
||||||
|
sender,
|
||||||
|
unsigned,
|
||||||
|
} if sdp == "Hello"
|
||||||
|
&& call_id == "foofoo"
|
||||||
|
&& version == uint!(1)
|
||||||
|
&& event_id == "$h29iv0s8:example.com"
|
||||||
|
&& origin_server_ts == UNIX_EPOCH + Duration::from_millis(1)
|
||||||
|
&& room_id == "!roomid:room.com"
|
||||||
|
&& sender == "@carl:example.com"
|
||||||
|
&& unsigned.is_empty()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -8,8 +8,8 @@ use matches::assert_matches;
|
|||||||
use ruma_common::Raw;
|
use ruma_common::Raw;
|
||||||
use ruma_events::{
|
use ruma_events::{
|
||||||
room::{aliases::AliasesEventContent, avatar::AvatarEventContent, ImageInfo, ThumbnailInfo},
|
room::{aliases::AliasesEventContent, avatar::AvatarEventContent, ImageInfo, ThumbnailInfo},
|
||||||
AnyRoomEvent, AnyStateEvent, AnyStateEventContent, RawExt, StateEvent, SyncStateEvent,
|
AnyRoomEvent, AnyStateEvent, AnyStateEventContent, AnySyncStateEvent, RawExt, StateEvent,
|
||||||
Unsigned,
|
SyncStateEvent, Unsigned,
|
||||||
};
|
};
|
||||||
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
|
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
|
||||||
use serde_json::{
|
use serde_json::{
|
||||||
@ -134,6 +134,7 @@ fn deserialize_aliases_with_prev_content() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_aliases_sync_with_room_id() {
|
fn deserialize_aliases_sync_with_room_id() {
|
||||||
|
// The same JSON can be used to create a sync event, it just ignores the `room_id` field
|
||||||
let json_data = aliases_event_with_prev_content();
|
let json_data = aliases_event_with_prev_content();
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
@ -284,3 +285,36 @@ fn deserialize_member_event_with_top_level_membership_field() {
|
|||||||
&& content.displayname == Some("example".into())
|
&& content.displayname == Some("example".into())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_full_event_convert_to_sync() {
|
||||||
|
let json_data = aliases_event_with_prev_content();
|
||||||
|
|
||||||
|
let full_ev = from_json_value::<Raw<AnyStateEvent>>(json_data).unwrap().deserialize().unwrap();
|
||||||
|
|
||||||
|
// Test conversion to sync event (without room_id field)
|
||||||
|
let sync: AnySyncStateEvent = full_ev.into();
|
||||||
|
let sync_json = to_json_value(sync).unwrap();
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
from_json_value::<Raw<AnySyncStateEvent>>(sync_json)
|
||||||
|
.unwrap()
|
||||||
|
.deserialize()
|
||||||
|
.unwrap(),
|
||||||
|
AnySyncStateEvent::RoomAliases(SyncStateEvent {
|
||||||
|
content,
|
||||||
|
event_id,
|
||||||
|
origin_server_ts,
|
||||||
|
prev_content: Some(prev_content),
|
||||||
|
sender,
|
||||||
|
state_key,
|
||||||
|
unsigned,
|
||||||
|
}) if content.aliases == vec![RoomAliasId::try_from("#somewhere:localhost").unwrap()]
|
||||||
|
&& event_id == "$h29iv0s8:example.com"
|
||||||
|
&& origin_server_ts == UNIX_EPOCH + Duration::from_millis(1)
|
||||||
|
&& prev_content.aliases == vec![RoomAliasId::try_from("#inner:localhost").unwrap()]
|
||||||
|
&& sender == "@carl:example.com"
|
||||||
|
&& state_key == ""
|
||||||
|
&& unsigned.is_empty()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -385,8 +385,6 @@ mod tests {
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_official_room_id() {
|
fn deserialize_official_room_id() {
|
||||||
use matches::assert_matches;
|
|
||||||
|
|
||||||
let deserialized =
|
let deserialized =
|
||||||
from_str::<RoomVersionId>(r#""1""#).expect("Failed to convert RoomVersionId to JSON.");
|
from_str::<RoomVersionId>(r#""1""#).expect("Failed to convert RoomVersionId to JSON.");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user