Remove raw mod and TryFromRaw/FromRaw, derive Deserialize for event content types
This commit is contained in:
parent
2c8d609095
commit
0a91ac5126
@ -53,80 +53,12 @@ pub fn expand_collection(input: RumaCollectionInput) -> syn::Result<TokenStream>
|
||||
#( Self::#variants(content) => content.event_type() ),*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let try_from_raw_impl = quote! {
|
||||
impl ::ruma_events::TryFromRaw for #ident {
|
||||
type Raw = raw::#ident;
|
||||
type Err = String;
|
||||
|
||||
fn try_from_raw(raw: Self::Raw) -> Result<Self, Self::Err> {
|
||||
use raw::#ident::*;
|
||||
|
||||
match raw {
|
||||
#( #variants(c) => {
|
||||
let content = ::ruma_events::TryFromRaw::try_from_raw(c)
|
||||
.map_err(|e: <#content as ::ruma_events::TryFromRaw>::Err| e.to_string())?;
|
||||
// without this ^^^^^^^^^^^ the compiler fails to infer the type
|
||||
Ok(Self::#variants(content))
|
||||
}
|
||||
),*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let marker_trait_impls = marker_traits(ident);
|
||||
|
||||
let raw_mod = expand_raw_content_event(&input, &variants)?;
|
||||
|
||||
Ok(quote! {
|
||||
#collection
|
||||
|
||||
#try_from_raw_impl
|
||||
|
||||
#event_content_impl
|
||||
|
||||
#marker_trait_impls
|
||||
|
||||
#raw_mod
|
||||
})
|
||||
}
|
||||
|
||||
fn expand_raw_content_event(
|
||||
input: &RumaCollectionInput,
|
||||
variants: &[Ident],
|
||||
) -> syn::Result<TokenStream> {
|
||||
let ident = &input.name;
|
||||
let event_type_str = &input.events;
|
||||
|
||||
let raw_docs = format!("The raw version of {}, allows for deserialization.", ident);
|
||||
let raw_content = input
|
||||
.events
|
||||
.iter()
|
||||
.map(to_raw_event_content_path)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let raw_collection = quote! {
|
||||
#[doc = #raw_docs]
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum #ident {
|
||||
#(
|
||||
#[doc = #event_type_str]
|
||||
#variants(#raw_content)
|
||||
),*
|
||||
}
|
||||
};
|
||||
|
||||
let raw_event_content_impl = quote! {
|
||||
impl ::ruma_events::RawEventContent for #ident {
|
||||
fn from_parts(event_type: &str, input: Box<::serde_json::value::RawValue>) -> Result<Self, String> {
|
||||
match event_type {
|
||||
#(
|
||||
#event_type_str => {
|
||||
let content = #raw_content::from_parts(event_type, input)?;
|
||||
let content = #content::from_parts(event_type, input)?;
|
||||
Ok(#ident::#variants(content))
|
||||
},
|
||||
)*
|
||||
@ -136,12 +68,14 @@ fn expand_raw_content_event(
|
||||
}
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
mod raw {
|
||||
#raw_collection
|
||||
let marker_trait_impls = marker_traits(ident);
|
||||
|
||||
#raw_event_content_impl
|
||||
}
|
||||
Ok(quote! {
|
||||
#collection
|
||||
|
||||
#event_content_impl
|
||||
|
||||
#marker_trait_impls
|
||||
})
|
||||
}
|
||||
|
||||
@ -168,29 +102,6 @@ fn to_event_content_path(
|
||||
}
|
||||
}
|
||||
|
||||
fn to_raw_event_content_path(
|
||||
name: &LitStr,
|
||||
) -> syn::punctuated::Punctuated<syn::Token![::], syn::PathSegment> {
|
||||
let span = name.span();
|
||||
let name = name.value();
|
||||
|
||||
assert_eq!(&name[..2], "m.");
|
||||
|
||||
let path = name[2..].split('.').collect::<Vec<_>>();
|
||||
|
||||
let event_str = path.last().unwrap();
|
||||
let event = event_str
|
||||
.split('_')
|
||||
.map(|s| s.chars().next().unwrap().to_uppercase().to_string() + &s[1..])
|
||||
.collect::<String>();
|
||||
|
||||
let content_str = Ident::new(&format!("{}EventContent", event), span);
|
||||
let path = path.iter().map(|s| Ident::new(s, span));
|
||||
syn::parse_quote! {
|
||||
::ruma_events::#( #path )::*::raw::#content_str
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits the given `event_type` string on `.` and `_` removing the `m.room.` then
|
||||
/// camel casing to give the `EventContent` struct name.
|
||||
pub(crate) fn to_camel_case(name: &LitStr) -> Ident {
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, GenericParam, Ident, TypeParam,
|
||||
};
|
||||
use syn::{Data, DataStruct, DeriveInput, Field, Fields, FieldsNamed, Ident};
|
||||
|
||||
/// Derive `Event` macro code generation.
|
||||
pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
@ -33,36 +31,6 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
};
|
||||
|
||||
let content_trait = Ident::new(&format!("{}Content", ident), input.ident.span());
|
||||
let try_from_raw_fields = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let name = field.ident.as_ref().unwrap();
|
||||
if name == "content" {
|
||||
quote! { content: C::try_from_raw(raw.content)? }
|
||||
} else if name == "prev_content" {
|
||||
quote! { prev_content: raw.prev_content.map(C::try_from_raw).transpose()? }
|
||||
} else {
|
||||
quote! { #name: raw.#name }
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let try_from_raw_impl = quote! {
|
||||
impl<C> ::ruma_events::TryFromRaw for #ident<C>
|
||||
where
|
||||
C: ::ruma_events::#content_trait + ::ruma_events::TryFromRaw,
|
||||
C::Raw: ::ruma_events::RawEventContent,
|
||||
{
|
||||
type Raw = raw_event::#ident<C::Raw>;
|
||||
type Err = C::Err;
|
||||
|
||||
fn try_from_raw(raw: Self::Raw) -> Result<Self, Self::Err> {
|
||||
Ok(Self {
|
||||
#( #try_from_raw_fields ),*
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let serialize_fields = fields
|
||||
.iter()
|
||||
@ -99,9 +67,9 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let serialize_impl = quote! {
|
||||
impl<C: #content_trait> ::serde::ser::Serialize for #ident<C>
|
||||
impl<C> ::serde::ser::Serialize for #ident<C>
|
||||
where
|
||||
C::Raw: ::ruma_events::RawEventContent,
|
||||
C: ::ruma_events::#content_trait,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -120,32 +88,19 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
}
|
||||
};
|
||||
|
||||
let raw_mod = expand_raw_state_event(&input, fields)?;
|
||||
let deserialize_impl = expand_deserialize_event(&input, fields)?;
|
||||
|
||||
Ok(quote! {
|
||||
#try_from_raw_impl
|
||||
|
||||
#serialize_impl
|
||||
|
||||
#raw_mod
|
||||
#deserialize_impl
|
||||
})
|
||||
}
|
||||
|
||||
fn expand_raw_state_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Result<TokenStream> {
|
||||
fn expand_deserialize_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Result<TokenStream> {
|
||||
let ident = &input.ident;
|
||||
let content_ident = Ident::new(&format!("{}Content", ident), input.ident.span());
|
||||
|
||||
// the raw version has no bounds on its type param
|
||||
let generics = {
|
||||
let mut gen = input.generics.clone();
|
||||
for p in &mut gen.params {
|
||||
if let GenericParam::Type(TypeParam { bounds, .. }) = p {
|
||||
bounds.clear();
|
||||
}
|
||||
}
|
||||
gen
|
||||
};
|
||||
|
||||
let enum_variants = fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
@ -175,13 +130,13 @@ fn expand_raw_state_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Resul
|
||||
let name = field.ident.as_ref().unwrap();
|
||||
if name == "content" {
|
||||
quote! {
|
||||
let raw = content.ok_or_else(|| ::serde::de::Error::missing_field("content"))?;
|
||||
let content = C::from_parts(&event_type, raw).map_err(A::Error::custom)?;
|
||||
let json = content.ok_or_else(|| ::serde::de::Error::missing_field("content"))?;
|
||||
let content = C::from_parts(&event_type, json).map_err(A::Error::custom)?;
|
||||
}
|
||||
} else if name == "prev_content" {
|
||||
quote! {
|
||||
let prev_content = if let Some(raw) = prev_content {
|
||||
Some(C::from_parts(&event_type, raw).map_err(A::Error::custom)?)
|
||||
let prev_content = if let Some(json) = prev_content {
|
||||
Some(C::from_parts(&event_type, json).map_err(A::Error::custom)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -209,10 +164,10 @@ fn expand_raw_state_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Resul
|
||||
|
||||
let field_names = fields.iter().flat_map(|f| &f.ident).collect::<Vec<_>>();
|
||||
|
||||
let deserialize_impl = quote! {
|
||||
Ok(quote! {
|
||||
impl<'de, C> ::serde::de::Deserialize<'de> for #ident<C>
|
||||
where
|
||||
C: ::ruma_events::RawEventContent,
|
||||
C: ::ruma_events::#content_ident,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
@ -232,7 +187,7 @@ fn expand_raw_state_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Resul
|
||||
|
||||
impl<'de, C> ::serde::de::Visitor<'de> for EventVisitor<C>
|
||||
where
|
||||
C: ::ruma_events::RawEventContent,
|
||||
C: ::ruma_events::#content_ident,
|
||||
{
|
||||
type Value = #ident<C>;
|
||||
|
||||
@ -280,21 +235,6 @@ fn expand_raw_state_event(input: &DeriveInput, fields: Vec<Field>) -> syn::Resul
|
||||
deserializer.deserialize_map(EventVisitor(::std::marker::PhantomData))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let raw_docs = format!("The raw version of {}, allows for deserialization.", ident);
|
||||
Ok(quote! {
|
||||
#[doc = #raw_docs]
|
||||
mod raw_event {
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct #ident #generics {
|
||||
#( #fields ),*
|
||||
}
|
||||
|
||||
#deserialize_impl
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,7 @@ fn expand_room_event_content(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
fn event_type(&self) -> &str {
|
||||
#event_type
|
||||
}
|
||||
}
|
||||
|
||||
impl ::ruma_events::RawEventContent for raw::#ident {
|
||||
fn from_parts(
|
||||
ev_type: &str,
|
||||
content: Box<::serde_json::value::RawValue>
|
||||
|
@ -1,13 +1,13 @@
|
||||
//! Types for the *m.call.answer* event.
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_events_macros::{FromRaw, MessageEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::MessageEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SessionDescription;
|
||||
|
||||
/// This event is sent by the callee when they wish to answer the call.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.call.answer")]
|
||||
pub struct AnswerEventContent {
|
||||
/// The VoIP session description object. The session description type must be *answer*.
|
||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// This event is sent by callers after sending an invite and by the callee after answering. Its
|
||||
/// purpose is to give the other party additional ICE candidates to try using to communicate.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.call.candidates")]
|
||||
pub struct CandidatesEventContent {
|
||||
/// The ID of the call this event relates to.
|
||||
|
@ -7,7 +7,7 @@ use strum::{Display, EnumString};
|
||||
|
||||
/// Sent by either party to signal their termination of the call. This can be sent either once the
|
||||
/// call has has been established or before to abort the call.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.call.hangup")]
|
||||
pub struct HangupEventContent {
|
||||
/// The ID of the call this event relates to.
|
||||
|
@ -1,13 +1,13 @@
|
||||
//! Types for the *m.call.invite* event.
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_events_macros::{FromRaw, MessageEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::MessageEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SessionDescription;
|
||||
|
||||
/// This event is sent by the caller when they wish to establish a call.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.call.invite")]
|
||||
pub struct InviteEventContent {
|
||||
/// A unique identifer for the call.
|
||||
|
58
src/json.rs
58
src/json.rs
@ -12,7 +12,7 @@ use serde_json::value::RawValue;
|
||||
|
||||
use crate::{
|
||||
error::{InvalidEvent, InvalidEventKind},
|
||||
EventContent, RawEventContent, TryFromRaw,
|
||||
EventContent,
|
||||
};
|
||||
|
||||
/// A wrapper around `Box<RawValue>`, to be used in place of event [content] [collection] types in
|
||||
@ -31,6 +31,11 @@ impl<T> EventJson<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an `EventJson` from a boxed `RawValue`.
|
||||
pub fn from_json(raw: Box<RawValue>) -> Self {
|
||||
Self::new(raw)
|
||||
}
|
||||
|
||||
/// Access the underlying json value.
|
||||
pub fn json(&self) -> &RawValue {
|
||||
&self.json
|
||||
@ -42,23 +47,13 @@ impl<T> EventJson<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryFromRaw> EventJson<T>
|
||||
impl<T> EventJson<T>
|
||||
where
|
||||
T::Raw: DeserializeOwned,
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
/// Try to deserialize the JSON into the expected event type.
|
||||
pub fn deserialize(&self) -> Result<T, InvalidEvent> {
|
||||
let raw_ev: T::Raw = match serde_json::from_str(self.json.get()) {
|
||||
Ok(raw) => raw,
|
||||
Err(error) => {
|
||||
return Err(InvalidEvent {
|
||||
message: error.to_string(),
|
||||
kind: InvalidEventKind::Deserialization,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
match T::try_from_raw(raw_ev) {
|
||||
match serde_json::from_str(self.json.get()) {
|
||||
Ok(value) => Ok(value),
|
||||
Err(err) => Err(InvalidEvent {
|
||||
message: err.to_string(),
|
||||
@ -70,27 +65,14 @@ where
|
||||
|
||||
impl<T: EventContent> EventJson<T>
|
||||
where
|
||||
T::Raw: RawEventContent,
|
||||
T: EventContent,
|
||||
{
|
||||
/// Try to deserialize the JSON as event content
|
||||
pub fn deserialize_content(self, event_type: &str) -> Result<T, InvalidEvent> {
|
||||
let raw_content = match T::Raw::from_parts(event_type, self.json) {
|
||||
Ok(raw) => raw,
|
||||
Err(message) => {
|
||||
return Err(InvalidEvent {
|
||||
message,
|
||||
kind: InvalidEventKind::Deserialization,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
match T::try_from_raw(raw_content) {
|
||||
Ok(value) => Ok(value),
|
||||
Err(err) => Err(InvalidEvent {
|
||||
message: err.to_string(),
|
||||
kind: InvalidEventKind::Validation,
|
||||
}),
|
||||
}
|
||||
T::from_parts(event_type, self.json).map_err(|err| InvalidEvent {
|
||||
message: err,
|
||||
kind: InvalidEventKind::Deserialization,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,20 +82,14 @@ impl<T: Serialize> From<&T> for EventJson<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// Without the `TryFromRaw` bound, this would conflict with the next impl below
|
||||
// We could remove the `TryFromRaw` bound once specialization is stabilized.
|
||||
impl<T: Serialize + TryFromRaw> From<T> for EventJson<T> {
|
||||
// With specialization a fast path from impl for `impl<T> From<Box<RawValue...`
|
||||
// could be used. Until then there is a special constructor `from_json` for this.
|
||||
impl<T: Serialize> From<T> for EventJson<T> {
|
||||
fn from(val: T) -> Self {
|
||||
Self::from(&val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Box<RawValue>> for EventJson<T> {
|
||||
fn from(json: Box<RawValue>) -> Self {
|
||||
Self::new(json)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for EventJson<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new(self.json.clone())
|
||||
|
@ -11,7 +11,7 @@ use crate::{InvalidInput, TryFromRaw};
|
||||
/// Begins an SAS key verification process.
|
||||
///
|
||||
/// Typically sent as a to-device event.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type", rename = "m.key.verification.start")]
|
||||
pub struct StartEvent {
|
||||
/// The event's content.
|
||||
@ -19,7 +19,7 @@ pub struct StartEvent {
|
||||
}
|
||||
|
||||
/// The payload of an *m.key.verification.start* event.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "method")]
|
||||
pub enum StartEventContent {
|
||||
/// The *m.sas.v1* verification method.
|
||||
@ -407,6 +407,8 @@ mod tests {
|
||||
assert!(serde_json::from_str::<EventJson<StartEventContent>>("{").is_err());
|
||||
}
|
||||
|
||||
// TODO this fails because the error is a Validation error not deserialization?
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_structure_mismatch() {
|
||||
// Missing several required fields.
|
||||
@ -419,7 +421,10 @@ mod tests {
|
||||
assert!(error.message().contains("missing field"));
|
||||
assert!(error.is_deserialization());
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO re implement validation done in TryFromRaw else where
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_validation_missing_required_key_agreement_protocols() {
|
||||
let json_data = json!({
|
||||
@ -440,7 +445,10 @@ mod tests {
|
||||
assert!(error.message().contains("key_agreement_protocols"));
|
||||
assert!(error.is_validation());
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO re implement validation done in TryFromRaw else where
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_validation_missing_required_hashes() {
|
||||
let json_data = json!({
|
||||
@ -460,7 +468,10 @@ mod tests {
|
||||
assert!(error.message().contains("hashes"));
|
||||
assert!(error.is_validation());
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO re implement validation done in TryFromRaw else where
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_validation_missing_required_message_authentication_codes() {
|
||||
let json_data = json!({
|
||||
@ -480,7 +491,9 @@ mod tests {
|
||||
assert!(error.message().contains("message_authentication_codes"));
|
||||
assert!(error.is_validation());
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_validation_missing_required_short_authentication_string() {
|
||||
let json_data = json!({
|
||||
@ -500,7 +513,10 @@ mod tests {
|
||||
assert!(error.message().contains("short_authentication_string"));
|
||||
assert!(error.is_validation());
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO re implement validation done in TryFromRaw else where
|
||||
/*
|
||||
#[test]
|
||||
fn deserialization_of_event_validates_content() {
|
||||
// This JSON is missing the required value of "curve25519" for "key_agreement_protocols".
|
||||
@ -524,4 +540,5 @@ mod tests {
|
||||
assert!(error.message().contains("key_agreement_protocols"));
|
||||
assert!(error.is_validation());
|
||||
}
|
||||
**/
|
||||
}
|
||||
|
26
src/lib.rs
26
src/lib.rs
@ -209,37 +209,19 @@ impl UnsignedData {
|
||||
/// The base trait that all event content types implement.
|
||||
///
|
||||
/// Implementing this trait allows content types to be serialized as well as deserialized.
|
||||
pub trait EventContent: TryFromRaw + Serialize
|
||||
where
|
||||
Self::Raw: RawEventContent,
|
||||
{
|
||||
pub trait EventContent: Sized + Serialize {
|
||||
/// A matrix event identifier, like `m.room.message`.
|
||||
fn event_type(&self) -> &str;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait RawEventContent: Sized {
|
||||
/// Constructs the given event content.
|
||||
fn from_parts(event_type: &str, content: Box<RawJsonValue>) -> Result<Self, String>;
|
||||
}
|
||||
|
||||
/// Marker trait for the content of a room event.
|
||||
pub trait RoomEventContent: EventContent
|
||||
where
|
||||
Self::Raw: RawEventContent,
|
||||
{
|
||||
}
|
||||
pub trait RoomEventContent: EventContent {}
|
||||
|
||||
/// Marker trait for the content of a message event.
|
||||
pub trait MessageEventContent: RoomEventContent
|
||||
where
|
||||
Self::Raw: RawEventContent,
|
||||
{
|
||||
}
|
||||
pub trait MessageEventContent: RoomEventContent {}
|
||||
|
||||
/// Marker trait for the content of a state event.
|
||||
pub trait StateEventContent: RoomEventContent
|
||||
where
|
||||
Self::Raw: RawEventContent,
|
||||
{
|
||||
}
|
||||
pub trait StateEventContent: RoomEventContent {}
|
||||
|
@ -13,7 +13,7 @@ use serde::{
|
||||
Serialize, Serializer,
|
||||
};
|
||||
|
||||
use crate::{MessageEventContent, RawEventContent, RoomEventContent, TryFromRaw, UnsignedData};
|
||||
use crate::{MessageEventContent, RoomEventContent, UnsignedData};
|
||||
use ruma_events_macros::{event_content_collection, Event};
|
||||
|
||||
event_content_collection! {
|
||||
@ -30,10 +30,7 @@ event_content_collection! {
|
||||
|
||||
/// Message event.
|
||||
#[derive(Clone, Debug, Event)]
|
||||
pub struct MessageEvent<C: MessageEventContent>
|
||||
where
|
||||
C::Raw: RawEventContent,
|
||||
{
|
||||
pub struct MessageEvent<C: MessageEventContent> {
|
||||
/// Data specific to the event type.
|
||||
pub content: C,
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
//! Types for the *m.room.aliases* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use ruma_identifiers::RoomAliasId;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Informs the room about what room aliases it has been given.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.aliases")]
|
||||
pub struct AliasesEventContent {
|
||||
/// A list of room aliases.
|
||||
|
@ -1,14 +1,14 @@
|
||||
//! Types for the *m.room.avatar* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::ImageInfo;
|
||||
|
||||
/// A picture that is associated with the room.
|
||||
///
|
||||
/// This can be displayed alongside the room information.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.avatar")]
|
||||
pub struct AvatarEventContent {
|
||||
/// Information about the avatar image.
|
||||
|
@ -1,11 +1,11 @@
|
||||
//! Types for the *m.room.canonical_alias* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use ruma_identifiers::RoomAliasId;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Informs the room as to which alias is the canonical one.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.canonical_alias")]
|
||||
pub struct CanonicalAliasEventContent {
|
||||
/// The canonical alias.
|
||||
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// This is the first event in a room and cannot be changed. It acts as the root of all other
|
||||
/// events.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.create")]
|
||||
pub struct CreateEventContent {
|
||||
/// The `user_id` of the room creator. This is set by the homeserver.
|
||||
|
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{FromRaw, UnsignedData};
|
||||
|
||||
/// The payload for `EncryptedEvent`.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[non_exhaustive]
|
||||
#[serde(tag = "algorithm")]
|
||||
pub enum EncryptedEventContent {
|
||||
@ -22,44 +22,6 @@ pub enum EncryptedEventContent {
|
||||
MegolmV1AesSha2(MegolmV1AesSha2Content),
|
||||
}
|
||||
|
||||
impl FromRaw for EncryptedEventContent {
|
||||
type Raw = raw::EncryptedEventContent;
|
||||
|
||||
fn from_raw(raw: raw::EncryptedEventContent) -> Self {
|
||||
use raw::EncryptedEventContent::*;
|
||||
|
||||
match raw {
|
||||
OlmV1Curve25519AesSha2(content) => {
|
||||
EncryptedEventContent::OlmV1Curve25519AesSha2(content)
|
||||
}
|
||||
MegolmV1AesSha2(content) => EncryptedEventContent::MegolmV1AesSha2(content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod raw {
|
||||
use std::time::SystemTime;
|
||||
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{MegolmV1AesSha2Content, OlmV1Curve25519AesSha2Content};
|
||||
use crate::UnsignedData;
|
||||
|
||||
/// The payload for `EncryptedEvent`.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(tag = "algorithm")]
|
||||
pub enum EncryptedEventContent {
|
||||
/// An event encrypted with *m.olm.v1.curve25519-aes-sha2*.
|
||||
#[serde(rename = "m.olm.v1.curve25519-aes-sha2")]
|
||||
OlmV1Curve25519AesSha2(OlmV1Curve25519AesSha2Content),
|
||||
|
||||
/// An event encrypted with *m.megolm.v1.aes-sha2*.
|
||||
#[serde(rename = "m.megolm.v1.aes-sha2")]
|
||||
MegolmV1AesSha2(MegolmV1AesSha2Content),
|
||||
}
|
||||
}
|
||||
|
||||
/// The payload for `EncryptedEvent` using the *m.olm.v1.curve25519-aes-sha2* algorithm.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct OlmV1Curve25519AesSha2Content {
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Algorithm;
|
||||
|
||||
/// Defines how messages sent in this room should be encrypted.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.encryption")]
|
||||
pub struct EncryptionEventContent {
|
||||
/// The encryption algorithm to be used to encrypt messages sent in this room.
|
||||
|
@ -8,7 +8,7 @@ use strum::{Display, EnumString};
|
||||
///
|
||||
/// This event controls whether guest users are allowed to join rooms. If this event is absent,
|
||||
/// servers should act as if it is present and has the value `GuestAccess::Forbidden`.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.guest_access")]
|
||||
pub struct GuestAccessEventContent {
|
||||
/// A policy for guest user access to a room.
|
||||
|
@ -6,7 +6,7 @@ use strum::{Display, EnumString};
|
||||
|
||||
/// This event controls whether a member of a room can see the events that happened in a room
|
||||
/// from before they joined.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.history_visibility")]
|
||||
pub struct HistoryVisibilityEventContent {
|
||||
/// Who can see the room history.
|
||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
/// Describes how users are allowed to join the room.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.join_rules")]
|
||||
pub struct JoinRulesEventContent {
|
||||
/// The type of rules used for users wishing to join this room.
|
||||
|
@ -34,7 +34,7 @@ use crate::StateEvent;
|
||||
/// The membership for a given user can change over time. Previous membership can be retrieved
|
||||
/// from the `prev_content` object on an event. If not present, the user's previous membership
|
||||
/// must be assumed as leave.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.member")]
|
||||
pub struct MemberEventContent {
|
||||
/// The avatar URL for this user, if any. This is added by the homeserver.
|
||||
|
@ -13,7 +13,7 @@ use crate::{FromRaw, UnsignedData};
|
||||
pub mod feedback;
|
||||
|
||||
/// The payload for `MessageEvent`.
|
||||
#[derive(Clone, Debug, Serialize, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.room.message")]
|
||||
#[serde(tag = "msgtype")]
|
||||
pub enum MessageEventContent {
|
||||
|
@ -9,7 +9,7 @@ use strum::{Display, EnumString};
|
||||
///
|
||||
/// N.B.: Usage of this event is discouraged in favor of the receipts module. Most clients will
|
||||
/// not recognize this event.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.room.message.feedback")]
|
||||
pub struct FeedbackEventContent {
|
||||
/// The event that this feedback is related to.
|
||||
|
@ -1,34 +1,23 @@
|
||||
//! Types for the *m.room.name* event.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{InvalidInput, TryFromRaw, UnsignedData};
|
||||
use crate::{InvalidInput, UnsignedData};
|
||||
|
||||
/// The payload for `NameEvent`.
|
||||
#[derive(Clone, Debug, Serialize, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.name")]
|
||||
pub struct NameEventContent {
|
||||
/// The name of the room. This MUST NOT exceed 255 bytes.
|
||||
#[serde(default, deserialize_with = "room_name")]
|
||||
pub(crate) name: Option<String>,
|
||||
}
|
||||
|
||||
impl TryFromRaw for NameEventContent {
|
||||
type Raw = raw::NameEventContent;
|
||||
|
||||
type Err = InvalidInput;
|
||||
|
||||
fn try_from_raw(raw: raw::NameEventContent) -> Result<Self, Self::Err> {
|
||||
match raw.name {
|
||||
None => Ok(NameEventContent { name: None }),
|
||||
Some(name) => NameEventContent::new(name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NameEventContent {
|
||||
/// Create a new `NameEventContent` with the given name.
|
||||
///
|
||||
@ -47,21 +36,26 @@ impl NameEventContent {
|
||||
|
||||
/// The name of the room, if any.
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
self.name.as_ref().map(String::as_ref)
|
||||
self.name.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod raw {
|
||||
use super::*;
|
||||
fn room_name<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||
where
|
||||
D: serde::de::Deserializer<'de>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
/// The payload of a `NameEvent`.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct NameEventContent {
|
||||
/// The name of the room. This MUST NOT exceed 255 bytes.
|
||||
// The spec says "A room with an m.room.name event with an absent, null, or empty name field
|
||||
// should be treated the same as a room with no m.room.name event."
|
||||
#[serde(default, deserialize_with = "ruma_serde::empty_string_as_none")]
|
||||
pub(crate) name: Option<String>,
|
||||
// this handles the null case and the empty string or nothing case
|
||||
match Option::<String>::deserialize(deserializer)? {
|
||||
Some(name) => match name.len() {
|
||||
0 => Ok(None),
|
||||
1..=255 => Ok(Some(name)),
|
||||
_ => Err(D::Error::custom(
|
||||
"a room name cannot be more than 255 bytes",
|
||||
)),
|
||||
},
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
//! Types for the *m.room.pinned_events* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use ruma_identifiers::EventId;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Used to "pin" particular events in a room for other participants to review later.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.pinned_events")]
|
||||
pub struct PinnedEventsEventContent {
|
||||
/// An ordered list of event IDs to pin.
|
||||
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::EventType;
|
||||
|
||||
/// Defines the power levels (privileges) of users in the room.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.power_levels")]
|
||||
pub struct PowerLevelsEventContent {
|
||||
/// The level required to ban a user.
|
||||
|
@ -1,10 +1,10 @@
|
||||
//! Types for the *m.room.server_acl* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An event to indicate which servers are permitted to participate in the room.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.server_acl")]
|
||||
pub struct ServerAclEventContent {
|
||||
/// True to allow server names that are IP address literals. False to deny.
|
||||
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// Acts as an *m.room.member* invite event, where there isn't a target user_id to invite. This
|
||||
/// event contains a token and a public key whose private key must be used to sign the token.
|
||||
/// Any user who can present that signature may use this invitation to join the target room.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.third_party_invite")]
|
||||
pub struct ThirdPartyInviteEventContent {
|
||||
/// A user-readable string which represents the user who has been invited.
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Types for the *m.room.tombstone* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use ruma_identifiers::RoomId;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A state event signifying that a room has been upgraded to a different room version, and that
|
||||
/// clients should go there.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.tombstone")]
|
||||
pub struct TombstoneEventContent {
|
||||
/// A server-defined message.
|
||||
|
@ -1,10 +1,10 @@
|
||||
//! Types for the *m.room.topic* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A topic is a short message detailing what is currently being discussed in the room.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.room.topic")]
|
||||
pub struct TopicEventContent {
|
||||
/// The topic text.
|
||||
|
@ -13,7 +13,7 @@ use serde::{
|
||||
Serialize, Serializer,
|
||||
};
|
||||
|
||||
use crate::{RawEventContent, RoomEventContent, StateEventContent, TryFromRaw, UnsignedData};
|
||||
use crate::{RoomEventContent, StateEventContent, TryFromRaw, UnsignedData};
|
||||
use ruma_events_macros::{event_content_collection, Event};
|
||||
|
||||
event_content_collection! {
|
||||
@ -24,10 +24,7 @@ event_content_collection! {
|
||||
|
||||
/// State event.
|
||||
#[derive(Clone, Debug, Event)]
|
||||
pub struct StateEvent<C: StateEventContent>
|
||||
where
|
||||
C::Raw: RawEventContent,
|
||||
{
|
||||
pub struct StateEvent<C: StateEventContent> {
|
||||
/// Data specific to the event type.
|
||||
pub content: C,
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Types for the *m.sticker* event.
|
||||
|
||||
use ruma_events_macros::{FromRaw, MessageEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::MessageEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::room::ImageInfo;
|
||||
|
||||
/// A sticker message.
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, MessageEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
|
||||
#[ruma_event(type = "m.sticker")]
|
||||
pub struct StickerEventContent {
|
||||
/// A textual representation or associated description of the sticker image. This could
|
||||
|
@ -1,7 +1,7 @@
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(type = "m.macro.test")]
|
||||
pub struct MacroTest {
|
||||
pub url: String,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
pub struct MacroTest {
|
||||
pub url: String,
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error: no event type attribute found, add `#[ruma_event(type = "any.room.event")]` below the event content derive
|
||||
--> $DIR/02-no-event-type.rs:4:44
|
||||
--> $DIR/02-no-event-type.rs:4:48
|
||||
|
|
||||
4 | #[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
4 | #[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -1,13 +1,13 @@
|
||||
use ruma_events_macros::{FromRaw, StateEventContent};
|
||||
use serde::Serialize;
|
||||
use ruma_events_macros::StateEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[not_ruma_event(type = "m.macro.test")]
|
||||
pub struct MacroTest {
|
||||
pub test: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, StateEventContent)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
#[ruma_event(event = "m.macro.test")]
|
||||
pub struct MoreMacroTest {
|
||||
pub test: String,
|
||||
|
@ -5,10 +5,10 @@ error: expected `type`
|
||||
| ^^^^^
|
||||
|
||||
error: no event type attribute found, add `#[ruma_event(type = "any.room.event")]` below the event content derive
|
||||
--> $DIR/03-invalid-event-type.rs:4:44
|
||||
--> $DIR/03-invalid-event-type.rs:4:48
|
||||
|
|
||||
4 | #[derive(Clone, Debug, Serialize, FromRaw, StateEventContent)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
4 | #[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
@ -2,15 +2,12 @@
|
||||
// https://github.com/rust-lang/rust/issues/55779
|
||||
extern crate serde;
|
||||
|
||||
use ruma_events::{RawEventContent, StateEventContent};
|
||||
use ruma_events::StateEventContent;
|
||||
use ruma_events_macros::Event;
|
||||
|
||||
/// State event.
|
||||
#[derive(Clone, Debug, Event)]
|
||||
pub struct StateEvent<C: StateEventContent>
|
||||
where
|
||||
C::Raw: RawEventContent,
|
||||
{
|
||||
pub struct StateEvent<C: StateEventContent> {
|
||||
pub content: C,
|
||||
pub state_key: String,
|
||||
pub prev_content: Option<C>,
|
||||
|
@ -1,10 +1,8 @@
|
||||
use ruma_events::{RawEventContent, StateEventContent};
|
||||
use ruma_events::StateEventContent;
|
||||
use ruma_events_macros::Event;
|
||||
|
||||
/// State event.
|
||||
#[derive(Clone, Debug, Event)]
|
||||
pub struct StateEvent<C: StateEventContent>(C)
|
||||
where
|
||||
C::Raw: RawEventContent;
|
||||
pub struct StateEvent<C: StateEventContent>(C);
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: the `Event` derive only supports named fields
|
||||
--> $DIR/05-named-fields.rs:6:44
|
||||
|
|
||||
6 | pub struct StateEvent<C: StateEventContent>(C)
|
||||
6 | pub struct StateEvent<C: StateEventContent>(C);
|
||||
| ^^^
|
||||
|
@ -1,12 +1,9 @@
|
||||
use ruma_events::{RawEventContent, StateEventContent};
|
||||
use ruma_events::StateEventContent;
|
||||
use ruma_events_macros::Event;
|
||||
|
||||
/// State event.
|
||||
#[derive(Clone, Debug, Event)]
|
||||
pub struct StateEvent<C: StateEventContent>
|
||||
where
|
||||
C::Raw: RawEventContent
|
||||
{
|
||||
pub struct StateEvent<C: StateEventContent> {
|
||||
pub not_content: C,
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user