events: Remove StateUnsignedFromParts
Replace it with a bound on DeserializeOwned
This commit is contained in:
parent
97b212795a
commit
dc591647f8
@ -51,6 +51,8 @@ Breaking changes:
|
|||||||
* Rename `RoomEventType` to `TimelineEventType`
|
* Rename `RoomEventType` to `TimelineEventType`
|
||||||
* Remove `SecretStorageKeyEventContent`'s implementation of `Deserialize`
|
* Remove `SecretStorageKeyEventContent`'s implementation of `Deserialize`
|
||||||
* Use `EventContentFromType::from_parts` instead
|
* Use `EventContentFromType::from_parts` instead
|
||||||
|
* Remove `StateUnsignedFromParts`
|
||||||
|
* Replace it with a bound on `DeserializeOwned`
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
@ -173,10 +173,7 @@ pub use self::{
|
|||||||
kinds::*,
|
kinds::*,
|
||||||
relation::BundledRelations,
|
relation::BundledRelations,
|
||||||
state_key::EmptyStateKey,
|
state_key::EmptyStateKey,
|
||||||
unsigned::{
|
unsigned::{MessageLikeUnsigned, RedactedUnsigned, StateUnsigned, UnsignedRoomRedactionEvent},
|
||||||
MessageLikeUnsigned, RedactedUnsigned, StateUnsigned, StateUnsignedFromParts,
|
|
||||||
UnsignedRoomRedactionEvent,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Trait to define the behavior of redact an event's content object.
|
/// Trait to define the behavior of redact an event's content object.
|
||||||
|
@ -4,9 +4,9 @@ use serde_json::value::RawValue as RawJsonValue;
|
|||||||
use super::{
|
use super::{
|
||||||
EphemeralRoomEventContent, EphemeralRoomEventType, EventContent, EventContentFromType,
|
EphemeralRoomEventContent, EphemeralRoomEventType, EventContent, EventContentFromType,
|
||||||
GlobalAccountDataEventContent, GlobalAccountDataEventType, MessageLikeEventContent,
|
GlobalAccountDataEventContent, GlobalAccountDataEventType, MessageLikeEventContent,
|
||||||
MessageLikeEventType, OriginalStateEventContent, RedactContent, RedactedEventContent,
|
MessageLikeEventType, MessageLikeUnsigned, OriginalStateEventContent, RedactContent,
|
||||||
RedactedMessageLikeEventContent, RedactedStateEventContent, RoomAccountDataEventContent,
|
RedactedEventContent, RedactedMessageLikeEventContent, RedactedStateEventContent,
|
||||||
RoomAccountDataEventType, StateEventContent, StateEventType, StateUnsigned,
|
RoomAccountDataEventContent, RoomAccountDataEventType, StateEventContent, StateEventType,
|
||||||
ToDeviceEventContent, ToDeviceEventType,
|
ToDeviceEventContent, ToDeviceEventType,
|
||||||
};
|
};
|
||||||
use crate::RoomVersionId;
|
use crate::RoomVersionId;
|
||||||
@ -77,7 +77,10 @@ impl StateEventContent for CustomStateEventContent {
|
|||||||
type StateKey = String;
|
type StateKey = String;
|
||||||
}
|
}
|
||||||
impl OriginalStateEventContent for CustomStateEventContent {
|
impl OriginalStateEventContent for CustomStateEventContent {
|
||||||
type Unsigned = StateUnsigned<Self>;
|
// Like `StateUnsigned`, but without `prev_content`.
|
||||||
|
// We don't care about `prev_content` since we'd only store the event type that is the same
|
||||||
|
// as in the content.
|
||||||
|
type Unsigned = MessageLikeUnsigned;
|
||||||
type PossiblyRedacted = Self;
|
type PossiblyRedacted = Self;
|
||||||
}
|
}
|
||||||
impl RedactedStateEventContent for CustomStateEventContent {}
|
impl RedactedStateEventContent for CustomStateEventContent {}
|
||||||
|
@ -7,7 +7,7 @@ use crate::serde::{CanBeEmpty, Raw};
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType, RedactContent,
|
EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType, RedactContent,
|
||||||
RoomAccountDataEventType, StateEventType, StateUnsignedFromParts, ToDeviceEventType,
|
RoomAccountDataEventType, StateEventType, ToDeviceEventType,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The base trait that all event content types implement.
|
/// The base trait that all event content types implement.
|
||||||
@ -129,7 +129,7 @@ pub trait StateEventContent: EventContent<EventType = StateEventType> {
|
|||||||
/// Content of a non-redacted state event.
|
/// Content of a non-redacted state event.
|
||||||
pub trait OriginalStateEventContent: StateEventContent + RedactContent {
|
pub trait OriginalStateEventContent: StateEventContent + RedactContent {
|
||||||
/// The type of the event's `unsigned` field.
|
/// The type of the event's `unsigned` field.
|
||||||
type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + StateUnsignedFromParts;
|
type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + DeserializeOwned;
|
||||||
|
|
||||||
/// The possibly redacted form of the event's content.
|
/// The possibly redacted form of the event's content.
|
||||||
type PossiblyRedacted: StateEventContent;
|
type PossiblyRedacted: StateEventContent;
|
||||||
|
@ -7,13 +7,12 @@ use std::collections::BTreeMap;
|
|||||||
use js_int::Int;
|
use js_int::Int;
|
||||||
use ruma_macros::EventContent;
|
use ruma_macros::EventContent;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::{
|
events::{
|
||||||
AnyStrippedStateEvent, BundledRelations, EventContent, RedactContent, RedactedEventContent,
|
AnyStrippedStateEvent, BundledRelations, EventContent, RedactContent, RedactedEventContent,
|
||||||
RedactedStateEventContent, StateEventContent, StateEventType, StateUnsignedFromParts,
|
RedactedStateEventContent, StateEventContent, StateEventType,
|
||||||
StaticEventContent,
|
|
||||||
},
|
},
|
||||||
serde::{CanBeEmpty, Raw, StringEnum},
|
serde::{CanBeEmpty, Raw, StringEnum},
|
||||||
OwnedMxcUri, OwnedServerName, OwnedServerSigningKeyId, OwnedTransactionId, OwnedUserId,
|
OwnedMxcUri, OwnedServerName, OwnedServerSigningKeyId, OwnedTransactionId, OwnedUserId,
|
||||||
@ -550,20 +549,6 @@ impl CanBeEmpty for RoomMemberUnsigned {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateUnsignedFromParts for RoomMemberUnsigned {
|
|
||||||
fn _from_parts(event_type: &str, object: &RawJsonValue) -> serde_json::Result<Self> {
|
|
||||||
const EVENT_TYPE: &str = <RoomMemberEventContent as StaticEventContent>::TYPE;
|
|
||||||
|
|
||||||
if event_type != EVENT_TYPE {
|
|
||||||
return Err(serde::de::Error::custom(format!(
|
|
||||||
"expected event type of `{EVENT_TYPE}`, found `{event_type}`",
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
from_json_str(object.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use js_int::Int;
|
use js_int::Int;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
relation::BundledRelations, room::redaction::RoomRedactionEventContent, StateEventContent,
|
relation::BundledRelations, room::redaction::RoomRedactionEventContent, StateEventContent,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
serde::{CanBeEmpty, Raw},
|
serde::CanBeEmpty, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, OwnedUserId,
|
||||||
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, OwnedUserId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Extra information about a message event that is not incorporated into the event's hash.
|
/// Extra information about a message event that is not incorporated into the event's hash.
|
||||||
@ -96,45 +94,6 @@ impl<C: StateEventContent> CanBeEmpty for StateUnsigned<C> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper functions for proc-macro code.
|
|
||||||
///
|
|
||||||
/// Needs to be public for state events defined outside ruma-common.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait StateUnsignedFromParts: Sized {
|
|
||||||
fn _from_parts(event_type: &str, object: &RawJsonValue) -> serde_json::Result<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: StateEventContent> StateUnsignedFromParts for StateUnsigned<C> {
|
|
||||||
fn _from_parts(event_type: &str, object: &RawJsonValue) -> serde_json::Result<Self> {
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(bound = "")] // Disable default C: Deserialize bound
|
|
||||||
struct WithRawPrevContent<C> {
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
age: Option<Int>,
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
transaction_id: Option<OwnedTransactionId>,
|
|
||||||
prev_content: Option<Raw<C>>,
|
|
||||||
#[serde(
|
|
||||||
rename = "m.relations",
|
|
||||||
default,
|
|
||||||
skip_serializing_if = "BundledRelations::is_empty"
|
|
||||||
)]
|
|
||||||
relations: BundledRelations,
|
|
||||||
}
|
|
||||||
|
|
||||||
let raw: WithRawPrevContent<C> = from_json_str(object.get())?;
|
|
||||||
let prev_content =
|
|
||||||
raw.prev_content.map(|r| r.deserialize_content(event_type.into())).transpose()?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
age: raw.age,
|
|
||||||
transaction_id: raw.transaction_id,
|
|
||||||
relations: raw.relations,
|
|
||||||
prev_content,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: StateEventContent> Default for StateUnsigned<C> {
|
impl<C: StateEventContent> Default for StateUnsigned<C> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
// Required, probably until Rust 1.57
|
|
||||||
// https://github.com/rust-lang/rust/issues/55779
|
|
||||||
#[allow(unused_extern_crates)]
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use ruma_common::{
|
use ruma_common::{
|
||||||
events::{StateEventContent, StateUnsigned},
|
events::{StateEventContent, StateUnsigned},
|
||||||
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId,
|
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId,
|
||||||
};
|
};
|
||||||
use ruma_macros::Event;
|
use ruma_macros::Event;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
/// State event.
|
/// State event.
|
||||||
#[derive(Clone, Debug, Event)]
|
#[derive(Clone, Debug, Event)]
|
||||||
pub struct OriginalStateEvent<C: StateEventContent> {
|
pub struct OriginalStateEvent<C: StateEventContent + DeserializeOwned> {
|
||||||
pub content: C,
|
pub content: C,
|
||||||
pub event_id: OwnedEventId,
|
pub event_id: OwnedEventId,
|
||||||
pub sender: OwnedUserId,
|
pub sender: OwnedUserId,
|
||||||
|
@ -6,7 +6,7 @@ use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed};
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_parse::{to_kind_variation, EventKind, EventKindVariation},
|
event_parse::{to_kind_variation, EventKind, EventKindVariation},
|
||||||
util::{has_prev_content, is_non_stripped_room_event},
|
util::is_non_stripped_room_event,
|
||||||
};
|
};
|
||||||
use crate::{import_ruma_common, util::to_camel_case};
|
use crate::{import_ruma_common, util::to_camel_case};
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
let mut res = TokenStream::new();
|
let mut res = TokenStream::new();
|
||||||
|
|
||||||
res.extend(
|
res.extend(
|
||||||
expand_deserialize_event(&input, kind, var, &fields, &ruma_common)
|
expand_deserialize_event(&input, var, &fields, &ruma_common)
|
||||||
.unwrap_or_else(syn::Error::into_compile_error),
|
.unwrap_or_else(syn::Error::into_compile_error),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -59,7 +59,6 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||||||
|
|
||||||
fn expand_deserialize_event(
|
fn expand_deserialize_event(
|
||||||
input: &DeriveInput,
|
input: &DeriveInput,
|
||||||
kind: EventKind,
|
|
||||||
var: EventKindVariation,
|
var: EventKindVariation,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
ruma_common: &TokenStream,
|
ruma_common: &TokenStream,
|
||||||
@ -91,7 +90,7 @@ fn expand_deserialize_event(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let name = field.ident.as_ref().unwrap();
|
let name = field.ident.as_ref().unwrap();
|
||||||
if name == "content" || (name == "unsigned" && has_prev_content(kind, var)) {
|
if name == "content" {
|
||||||
if is_generic {
|
if is_generic {
|
||||||
quote! { ::std::boxed::Box<#serde_json::value::RawValue> }
|
quote! { ::std::boxed::Box<#serde_json::value::RawValue> }
|
||||||
} else {
|
} else {
|
||||||
@ -137,20 +136,9 @@ fn expand_deserialize_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if name == "unsigned" && !var.is_redacted() {
|
} else if name == "unsigned" && !var.is_redacted() {
|
||||||
if has_prev_content(kind, var) {
|
|
||||||
quote! {
|
|
||||||
let unsigned = unsigned.map(|json| {
|
|
||||||
#ruma_common::events::StateUnsignedFromParts::_from_parts(
|
|
||||||
&event_type,
|
|
||||||
&json,
|
|
||||||
).map_err(#serde::de::Error::custom)
|
|
||||||
}).transpose()?.unwrap_or_default();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote! {
|
quote! {
|
||||||
let unsigned = unsigned.unwrap_or_default();
|
let unsigned = unsigned.unwrap_or_default();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if name == "state_key" && var == EventKindVariation::Initial {
|
} else if name == "state_key" && var == EventKindVariation::Initial {
|
||||||
let ty = &field.ty;
|
let ty = &field.ty;
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -10,8 +10,3 @@ pub(crate) fn is_non_stripped_room_event(kind: EventKind, var: EventKindVariatio
|
|||||||
| EventKindVariation::RedactedSync
|
| EventKindVariation::RedactedSync
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn has_prev_content(kind: EventKind, var: EventKindVariation) -> bool {
|
|
||||||
matches!(kind, EventKind::State)
|
|
||||||
&& matches!(var, EventKindVariation::Original | EventKindVariation::OriginalSync)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user