Update existing events for spec r0.5.0 and add m.fully_read and
m.room.message.feedback.
This commit is contained in:
		
							parent
							
								
									9f43f37f41
								
							
						
					
					
						commit
						ba2538dda9
					
				@ -15,4 +15,29 @@ pub struct HangupEventContent {
 | 
				
			|||||||
    pub call_id: String,
 | 
					    pub call_id: String,
 | 
				
			||||||
    /// The version of the VoIP specification this messages adheres to.
 | 
					    /// The version of the VoIP specification this messages adheres to.
 | 
				
			||||||
    pub version: u64,
 | 
					    pub version: u64,
 | 
				
			||||||
 | 
					    /// Optional error reason for the hangup.
 | 
				
			||||||
 | 
					    pub reason: Option<Reason>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A reason for a hangup.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This should not be provided when the user naturally ends or rejects the call. When there was an
 | 
				
			||||||
 | 
					/// error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails or
 | 
				
			||||||
 | 
					/// `invite_timeout` for when the other party did not answer in time.
 | 
				
			||||||
 | 
					#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub enum Reason {
 | 
				
			||||||
 | 
					    /// ICE negotiation failure.
 | 
				
			||||||
 | 
					    #[serde(rename = "ice_failed")]
 | 
				
			||||||
 | 
					    IceFailed,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Party did not answer in time.
 | 
				
			||||||
 | 
					    #[serde(rename = "invite_timeout")]
 | 
				
			||||||
 | 
					    InviteTimeout,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl_enum! {
 | 
				
			||||||
 | 
					    Reason {
 | 
				
			||||||
 | 
					        IceFailed => "ice_failed",
 | 
				
			||||||
 | 
					        InviteTimeout => "invite_timeout",
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,15 +6,25 @@ use crate::{
 | 
				
			|||||||
        answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
 | 
					        answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    direct::DirectEvent,
 | 
					    direct::DirectEvent,
 | 
				
			||||||
 | 
					    fully_read::FullyReadEvent,
 | 
				
			||||||
    presence::PresenceEvent,
 | 
					    presence::PresenceEvent,
 | 
				
			||||||
    receipt::ReceiptEvent,
 | 
					    receipt::ReceiptEvent,
 | 
				
			||||||
    room::{
 | 
					    room::{
 | 
				
			||||||
        aliases::AliasesEvent, avatar::AvatarEvent, canonical_alias::CanonicalAliasEvent,
 | 
					        aliases::AliasesEvent,
 | 
				
			||||||
        create::CreateEvent, guest_access::GuestAccessEvent,
 | 
					        avatar::AvatarEvent,
 | 
				
			||||||
        history_visibility::HistoryVisibilityEvent, join_rules::JoinRulesEvent,
 | 
					        canonical_alias::CanonicalAliasEvent,
 | 
				
			||||||
        member::MemberEvent, message::MessageEvent, name::NameEvent,
 | 
					        create::CreateEvent,
 | 
				
			||||||
        pinned_events::PinnedEventsEvent, power_levels::PowerLevelsEvent,
 | 
					        guest_access::GuestAccessEvent,
 | 
				
			||||||
        redaction::RedactionEvent, third_party_invite::ThirdPartyInviteEvent, topic::TopicEvent,
 | 
					        history_visibility::HistoryVisibilityEvent,
 | 
				
			||||||
 | 
					        join_rules::JoinRulesEvent,
 | 
				
			||||||
 | 
					        member::MemberEvent,
 | 
				
			||||||
 | 
					        message::{feedback::FeedbackEvent, MessageEvent},
 | 
				
			||||||
 | 
					        name::NameEvent,
 | 
				
			||||||
 | 
					        pinned_events::PinnedEventsEvent,
 | 
				
			||||||
 | 
					        power_levels::PowerLevelsEvent,
 | 
				
			||||||
 | 
					        redaction::RedactionEvent,
 | 
				
			||||||
 | 
					        third_party_invite::ThirdPartyInviteEvent,
 | 
				
			||||||
 | 
					        topic::TopicEvent,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    tag::TagEvent,
 | 
					    tag::TagEvent,
 | 
				
			||||||
    typing::TypingEvent,
 | 
					    typing::TypingEvent,
 | 
				
			||||||
@ -38,6 +48,8 @@ pub enum Event {
 | 
				
			|||||||
    CallInvite(InviteEvent),
 | 
					    CallInvite(InviteEvent),
 | 
				
			||||||
    /// m.direct
 | 
					    /// m.direct
 | 
				
			||||||
    Direct(DirectEvent),
 | 
					    Direct(DirectEvent),
 | 
				
			||||||
 | 
					    /// m.fully_read
 | 
				
			||||||
 | 
					    FullyRead(FullyReadEvent),
 | 
				
			||||||
    /// m.presence
 | 
					    /// m.presence
 | 
				
			||||||
    Presence(PresenceEvent),
 | 
					    Presence(PresenceEvent),
 | 
				
			||||||
    /// m.receipt
 | 
					    /// m.receipt
 | 
				
			||||||
@ -60,6 +72,8 @@ pub enum Event {
 | 
				
			|||||||
    RoomMember(MemberEvent),
 | 
					    RoomMember(MemberEvent),
 | 
				
			||||||
    /// m.room.message
 | 
					    /// m.room.message
 | 
				
			||||||
    RoomMessage(MessageEvent),
 | 
					    RoomMessage(MessageEvent),
 | 
				
			||||||
 | 
					    /// m.room.message.feedback
 | 
				
			||||||
 | 
					    RoomMessageFeedback(FeedbackEvent),
 | 
				
			||||||
    /// m.room.name
 | 
					    /// m.room.name
 | 
				
			||||||
    RoomName(NameEvent),
 | 
					    RoomName(NameEvent),
 | 
				
			||||||
    /// m.room.pinned_events
 | 
					    /// m.room.pinned_events
 | 
				
			||||||
@ -114,6 +128,8 @@ pub enum RoomEvent {
 | 
				
			|||||||
    RoomMember(MemberEvent),
 | 
					    RoomMember(MemberEvent),
 | 
				
			||||||
    /// m.room.message
 | 
					    /// m.room.message
 | 
				
			||||||
    RoomMessage(MessageEvent),
 | 
					    RoomMessage(MessageEvent),
 | 
				
			||||||
 | 
					    /// m.room.message.feedback
 | 
				
			||||||
 | 
					    RoomMessageFeedback(FeedbackEvent),
 | 
				
			||||||
    /// m.room.name
 | 
					    /// m.room.name
 | 
				
			||||||
    RoomName(NameEvent),
 | 
					    RoomName(NameEvent),
 | 
				
			||||||
    /// m.room.pinned_events
 | 
					    /// m.room.pinned_events
 | 
				
			||||||
@ -177,6 +193,7 @@ impl Serialize for Event {
 | 
				
			|||||||
            Event::CallHangup(ref event) => event.serialize(serializer),
 | 
					            Event::CallHangup(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::CallInvite(ref event) => event.serialize(serializer),
 | 
					            Event::CallInvite(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Direct(ref event) => event.serialize(serializer),
 | 
					            Event::Direct(ref event) => event.serialize(serializer),
 | 
				
			||||||
 | 
					            Event::FullyRead(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Presence(ref event) => event.serialize(serializer),
 | 
					            Event::Presence(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Receipt(ref event) => event.serialize(serializer),
 | 
					            Event::Receipt(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomAliases(ref event) => event.serialize(serializer),
 | 
					            Event::RoomAliases(ref event) => event.serialize(serializer),
 | 
				
			||||||
@ -188,6 +205,7 @@ impl Serialize for Event {
 | 
				
			|||||||
            Event::RoomJoinRules(ref event) => event.serialize(serializer),
 | 
					            Event::RoomJoinRules(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomMember(ref event) => event.serialize(serializer),
 | 
					            Event::RoomMember(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomMessage(ref event) => event.serialize(serializer),
 | 
					            Event::RoomMessage(ref event) => event.serialize(serializer),
 | 
				
			||||||
 | 
					            Event::RoomMessageFeedback(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomName(ref event) => event.serialize(serializer),
 | 
					            Event::RoomName(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomPinnedEvents(ref event) => event.serialize(serializer),
 | 
					            Event::RoomPinnedEvents(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::RoomPowerLevels(ref event) => event.serialize(serializer),
 | 
					            Event::RoomPowerLevels(ref event) => event.serialize(serializer),
 | 
				
			||||||
@ -261,6 +279,14 @@ impl<'de> Deserialize<'de> for Event {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Ok(Event::Direct(event))
 | 
					                Ok(Event::Direct(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EventType::FullyRead => {
 | 
				
			||||||
 | 
					                let event = match from_value::<FullyReadEvent>(value) {
 | 
				
			||||||
 | 
					                    Ok(event) => event,
 | 
				
			||||||
 | 
					                    Err(error) => return Err(D::Error::custom(error.to_string())),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(Event::FullyRead(event))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EventType::Presence => {
 | 
					            EventType::Presence => {
 | 
				
			||||||
                let event = match from_value::<PresenceEvent>(value) {
 | 
					                let event = match from_value::<PresenceEvent>(value) {
 | 
				
			||||||
                    Ok(event) => event,
 | 
					                    Ok(event) => event,
 | 
				
			||||||
@ -349,6 +375,14 @@ impl<'de> Deserialize<'de> for Event {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Ok(Event::RoomMessage(event))
 | 
					                Ok(Event::RoomMessage(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EventType::RoomMessageFeedback => {
 | 
				
			||||||
 | 
					                let event = match from_value::<FeedbackEvent>(value) {
 | 
				
			||||||
 | 
					                    Ok(event) => event,
 | 
				
			||||||
 | 
					                    Err(error) => return Err(D::Error::custom(error.to_string())),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(Event::RoomMessageFeedback(event))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EventType::RoomName => {
 | 
					            EventType::RoomName => {
 | 
				
			||||||
                let event = match from_value::<NameEvent>(value) {
 | 
					                let event = match from_value::<NameEvent>(value) {
 | 
				
			||||||
                    Ok(event) => event,
 | 
					                    Ok(event) => event,
 | 
				
			||||||
@ -463,6 +497,7 @@ impl Serialize for RoomEvent {
 | 
				
			|||||||
            RoomEvent::RoomJoinRules(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomJoinRules(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomMember(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomMember(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
 | 
				
			||||||
 | 
					            RoomEvent::RoomMessageFeedback(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomName(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomName(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomPinnedEvents(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomPinnedEvents(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomPowerLevels(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomPowerLevels(ref event) => event.serialize(serializer),
 | 
				
			||||||
@ -597,6 +632,14 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Ok(RoomEvent::RoomMessage(event))
 | 
					                Ok(RoomEvent::RoomMessage(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EventType::RoomMessageFeedback => {
 | 
				
			||||||
 | 
					                let event = match from_value::<FeedbackEvent>(value) {
 | 
				
			||||||
 | 
					                    Ok(event) => event,
 | 
				
			||||||
 | 
					                    Err(error) => return Err(D::Error::custom(error.to_string())),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(RoomEvent::RoomMessageFeedback(event))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EventType::RoomName => {
 | 
					            EventType::RoomName => {
 | 
				
			||||||
                let event = match from_value::<NameEvent>(value) {
 | 
					                let event = match from_value::<NameEvent>(value) {
 | 
				
			||||||
                    Ok(event) => event,
 | 
					                    Ok(event) => event,
 | 
				
			||||||
@ -663,6 +706,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            EventType::Direct
 | 
					            EventType::Direct
 | 
				
			||||||
 | 
					            | EventType::FullyRead
 | 
				
			||||||
            | EventType::Presence
 | 
					            | EventType::Presence
 | 
				
			||||||
            | EventType::Receipt
 | 
					            | EventType::Receipt
 | 
				
			||||||
            | EventType::Tag
 | 
					            | EventType::Tag
 | 
				
			||||||
@ -830,9 +874,11 @@ impl<'de> Deserialize<'de> for StateEvent {
 | 
				
			|||||||
            | EventType::CallHangup
 | 
					            | EventType::CallHangup
 | 
				
			||||||
            | EventType::CallInvite
 | 
					            | EventType::CallInvite
 | 
				
			||||||
            | EventType::Direct
 | 
					            | EventType::Direct
 | 
				
			||||||
 | 
					            | EventType::FullyRead
 | 
				
			||||||
            | EventType::Presence
 | 
					            | EventType::Presence
 | 
				
			||||||
            | EventType::Receipt
 | 
					            | EventType::Receipt
 | 
				
			||||||
            | EventType::RoomMessage
 | 
					            | EventType::RoomMessage
 | 
				
			||||||
 | 
					            | EventType::RoomMessageFeedback
 | 
				
			||||||
            | EventType::RoomRedaction
 | 
					            | EventType::RoomRedaction
 | 
				
			||||||
            | EventType::Tag
 | 
					            | EventType::Tag
 | 
				
			||||||
            | EventType::Typing => Err(D::Error::custom("not a state event".to_string())),
 | 
					            | EventType::Typing => Err(D::Error::custom("not a state event".to_string())),
 | 
				
			||||||
@ -855,6 +901,7 @@ impl_from_t_for_event!(CandidatesEvent, CallCandidates);
 | 
				
			|||||||
impl_from_t_for_event!(HangupEvent, CallHangup);
 | 
					impl_from_t_for_event!(HangupEvent, CallHangup);
 | 
				
			||||||
impl_from_t_for_event!(InviteEvent, CallInvite);
 | 
					impl_from_t_for_event!(InviteEvent, CallInvite);
 | 
				
			||||||
impl_from_t_for_event!(DirectEvent, Direct);
 | 
					impl_from_t_for_event!(DirectEvent, Direct);
 | 
				
			||||||
 | 
					impl_from_t_for_event!(FullyReadEvent, FullyRead);
 | 
				
			||||||
impl_from_t_for_event!(PresenceEvent, Presence);
 | 
					impl_from_t_for_event!(PresenceEvent, Presence);
 | 
				
			||||||
impl_from_t_for_event!(ReceiptEvent, Receipt);
 | 
					impl_from_t_for_event!(ReceiptEvent, Receipt);
 | 
				
			||||||
impl_from_t_for_event!(AliasesEvent, RoomAliases);
 | 
					impl_from_t_for_event!(AliasesEvent, RoomAliases);
 | 
				
			||||||
@ -866,6 +913,7 @@ impl_from_t_for_event!(HistoryVisibilityEvent, RoomHistoryVisibility);
 | 
				
			|||||||
impl_from_t_for_event!(JoinRulesEvent, RoomJoinRules);
 | 
					impl_from_t_for_event!(JoinRulesEvent, RoomJoinRules);
 | 
				
			||||||
impl_from_t_for_event!(MemberEvent, RoomMember);
 | 
					impl_from_t_for_event!(MemberEvent, RoomMember);
 | 
				
			||||||
impl_from_t_for_event!(MessageEvent, RoomMessage);
 | 
					impl_from_t_for_event!(MessageEvent, RoomMessage);
 | 
				
			||||||
 | 
					impl_from_t_for_event!(FeedbackEvent, RoomMessageFeedback);
 | 
				
			||||||
impl_from_t_for_event!(NameEvent, RoomName);
 | 
					impl_from_t_for_event!(NameEvent, RoomName);
 | 
				
			||||||
impl_from_t_for_event!(PinnedEventsEvent, RoomPinnedEvents);
 | 
					impl_from_t_for_event!(PinnedEventsEvent, RoomPinnedEvents);
 | 
				
			||||||
impl_from_t_for_event!(PowerLevelsEvent, RoomPowerLevels);
 | 
					impl_from_t_for_event!(PowerLevelsEvent, RoomPowerLevels);
 | 
				
			||||||
@ -901,6 +949,7 @@ impl_from_t_for_room_event!(HistoryVisibilityEvent, RoomHistoryVisibility);
 | 
				
			|||||||
impl_from_t_for_room_event!(JoinRulesEvent, RoomJoinRules);
 | 
					impl_from_t_for_room_event!(JoinRulesEvent, RoomJoinRules);
 | 
				
			||||||
impl_from_t_for_room_event!(MemberEvent, RoomMember);
 | 
					impl_from_t_for_room_event!(MemberEvent, RoomMember);
 | 
				
			||||||
impl_from_t_for_room_event!(MessageEvent, RoomMessage);
 | 
					impl_from_t_for_room_event!(MessageEvent, RoomMessage);
 | 
				
			||||||
 | 
					impl_from_t_for_room_event!(FeedbackEvent, RoomMessageFeedback);
 | 
				
			||||||
impl_from_t_for_room_event!(NameEvent, RoomName);
 | 
					impl_from_t_for_room_event!(NameEvent, RoomName);
 | 
				
			||||||
impl_from_t_for_room_event!(PinnedEventsEvent, RoomPinnedEvents);
 | 
					impl_from_t_for_room_event!(PinnedEventsEvent, RoomPinnedEvents);
 | 
				
			||||||
impl_from_t_for_room_event!(PowerLevelsEvent, RoomPowerLevels);
 | 
					impl_from_t_for_room_event!(PowerLevelsEvent, RoomPowerLevels);
 | 
				
			||||||
 | 
				
			|||||||
@ -10,9 +10,13 @@ use crate::{
 | 
				
			|||||||
        answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
 | 
					        answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    direct::DirectEvent,
 | 
					    direct::DirectEvent,
 | 
				
			||||||
 | 
					    fully_read::FullyReadEvent,
 | 
				
			||||||
    presence::PresenceEvent,
 | 
					    presence::PresenceEvent,
 | 
				
			||||||
    receipt::ReceiptEvent,
 | 
					    receipt::ReceiptEvent,
 | 
				
			||||||
    room::{message::MessageEvent, redaction::RedactionEvent},
 | 
					    room::{
 | 
				
			||||||
 | 
					        message::{feedback::FeedbackEvent, MessageEvent},
 | 
				
			||||||
 | 
					        redaction::RedactionEvent,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    tag::TagEvent,
 | 
					    tag::TagEvent,
 | 
				
			||||||
    typing::TypingEvent,
 | 
					    typing::TypingEvent,
 | 
				
			||||||
    CustomEvent, CustomRoomEvent, EventType,
 | 
					    CustomEvent, CustomRoomEvent, EventType,
 | 
				
			||||||
@ -23,6 +27,8 @@ use crate::{
 | 
				
			|||||||
pub enum Event {
 | 
					pub enum Event {
 | 
				
			||||||
    /// m.direct
 | 
					    /// m.direct
 | 
				
			||||||
    Direct(DirectEvent),
 | 
					    Direct(DirectEvent),
 | 
				
			||||||
 | 
					    /// m.fully_read
 | 
				
			||||||
 | 
					    FullyRead(FullyReadEvent),
 | 
				
			||||||
    /// m.presence
 | 
					    /// m.presence
 | 
				
			||||||
    Presence(PresenceEvent),
 | 
					    Presence(PresenceEvent),
 | 
				
			||||||
    /// m.receipt
 | 
					    /// m.receipt
 | 
				
			||||||
@ -49,6 +55,8 @@ pub enum RoomEvent {
 | 
				
			|||||||
    CallInvite(InviteEvent),
 | 
					    CallInvite(InviteEvent),
 | 
				
			||||||
    /// m.room.message
 | 
					    /// m.room.message
 | 
				
			||||||
    RoomMessage(MessageEvent),
 | 
					    RoomMessage(MessageEvent),
 | 
				
			||||||
 | 
					    /// m.room.message.feedback
 | 
				
			||||||
 | 
					    RoomMessageFeedback(FeedbackEvent),
 | 
				
			||||||
    /// m.room.redaction
 | 
					    /// m.room.redaction
 | 
				
			||||||
    RoomRedaction(RedactionEvent),
 | 
					    RoomRedaction(RedactionEvent),
 | 
				
			||||||
    /// Any room event that is not part of the specification.
 | 
					    /// Any room event that is not part of the specification.
 | 
				
			||||||
@ -62,6 +70,7 @@ impl Serialize for Event {
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        match *self {
 | 
					        match *self {
 | 
				
			||||||
            Event::Direct(ref event) => event.serialize(serializer),
 | 
					            Event::Direct(ref event) => event.serialize(serializer),
 | 
				
			||||||
 | 
					            Event::FullyRead(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Presence(ref event) => event.serialize(serializer),
 | 
					            Event::Presence(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Receipt(ref event) => event.serialize(serializer),
 | 
					            Event::Receipt(ref event) => event.serialize(serializer),
 | 
				
			||||||
            Event::Tag(ref event) => event.serialize(serializer),
 | 
					            Event::Tag(ref event) => event.serialize(serializer),
 | 
				
			||||||
@ -97,6 +106,14 @@ impl<'de> Deserialize<'de> for Event {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Ok(Event::Direct(event))
 | 
					                Ok(Event::Direct(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EventType::FullyRead => {
 | 
				
			||||||
 | 
					                let event = match from_value::<FullyReadEvent>(value) {
 | 
				
			||||||
 | 
					                    Ok(event) => event,
 | 
				
			||||||
 | 
					                    Err(error) => return Err(D::Error::custom(error.to_string())),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(Event::FullyRead(event))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EventType::Presence => {
 | 
					            EventType::Presence => {
 | 
				
			||||||
                let event = match from_value::<PresenceEvent>(value) {
 | 
					                let event = match from_value::<PresenceEvent>(value) {
 | 
				
			||||||
                    Ok(event) => event,
 | 
					                    Ok(event) => event,
 | 
				
			||||||
@ -150,6 +167,7 @@ impl<'de> Deserialize<'de> for Event {
 | 
				
			|||||||
            | EventType::RoomJoinRules
 | 
					            | EventType::RoomJoinRules
 | 
				
			||||||
            | EventType::RoomMember
 | 
					            | EventType::RoomMember
 | 
				
			||||||
            | EventType::RoomMessage
 | 
					            | EventType::RoomMessage
 | 
				
			||||||
 | 
					            | EventType::RoomMessageFeedback
 | 
				
			||||||
            | EventType::RoomName
 | 
					            | EventType::RoomName
 | 
				
			||||||
            | EventType::RoomPinnedEvents
 | 
					            | EventType::RoomPinnedEvents
 | 
				
			||||||
            | EventType::RoomPowerLevels
 | 
					            | EventType::RoomPowerLevels
 | 
				
			||||||
@ -173,6 +191,7 @@ impl Serialize for RoomEvent {
 | 
				
			|||||||
            RoomEvent::CallHangup(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::CallHangup(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::CallInvite(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::CallInvite(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomMessage(ref event) => event.serialize(serializer),
 | 
				
			||||||
 | 
					            RoomEvent::RoomMessageFeedback(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::RoomRedaction(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::RoomRedaction(ref event) => event.serialize(serializer),
 | 
				
			||||||
            RoomEvent::CustomRoom(ref event) => event.serialize(serializer),
 | 
					            RoomEvent::CustomRoom(ref event) => event.serialize(serializer),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -237,6 +256,14 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                Ok(RoomEvent::RoomMessage(event))
 | 
					                Ok(RoomEvent::RoomMessage(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EventType::RoomMessageFeedback => {
 | 
				
			||||||
 | 
					                let event = match from_value::<FeedbackEvent>(value) {
 | 
				
			||||||
 | 
					                    Ok(event) => event,
 | 
				
			||||||
 | 
					                    Err(error) => return Err(D::Error::custom(error.to_string())),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Ok(RoomEvent::RoomMessageFeedback(event))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EventType::RoomRedaction => {
 | 
					            EventType::RoomRedaction => {
 | 
				
			||||||
                let event = match from_value::<RedactionEvent>(value) {
 | 
					                let event = match from_value::<RedactionEvent>(value) {
 | 
				
			||||||
                    Ok(event) => event,
 | 
					                    Ok(event) => event,
 | 
				
			||||||
@ -254,6 +281,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
				
			|||||||
                Ok(RoomEvent::CustomRoom(event))
 | 
					                Ok(RoomEvent::CustomRoom(event))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            EventType::Direct
 | 
					            EventType::Direct
 | 
				
			||||||
 | 
					            | EventType::FullyRead
 | 
				
			||||||
            | EventType::Presence
 | 
					            | EventType::Presence
 | 
				
			||||||
            | EventType::Receipt
 | 
					            | EventType::Receipt
 | 
				
			||||||
            | EventType::RoomAliases
 | 
					            | EventType::RoomAliases
 | 
				
			||||||
@ -287,6 +315,7 @@ macro_rules! impl_from_t_for_event {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_from_t_for_event!(DirectEvent, Direct);
 | 
					impl_from_t_for_event!(DirectEvent, Direct);
 | 
				
			||||||
 | 
					impl_from_t_for_event!(FullyReadEvent, FullyRead);
 | 
				
			||||||
impl_from_t_for_event!(PresenceEvent, Presence);
 | 
					impl_from_t_for_event!(PresenceEvent, Presence);
 | 
				
			||||||
impl_from_t_for_event!(ReceiptEvent, Receipt);
 | 
					impl_from_t_for_event!(ReceiptEvent, Receipt);
 | 
				
			||||||
impl_from_t_for_event!(TagEvent, Tag);
 | 
					impl_from_t_for_event!(TagEvent, Tag);
 | 
				
			||||||
@ -308,5 +337,6 @@ impl_from_t_for_room_event!(CandidatesEvent, CallCandidates);
 | 
				
			|||||||
impl_from_t_for_room_event!(HangupEvent, CallHangup);
 | 
					impl_from_t_for_room_event!(HangupEvent, CallHangup);
 | 
				
			||||||
impl_from_t_for_room_event!(InviteEvent, CallInvite);
 | 
					impl_from_t_for_room_event!(InviteEvent, CallInvite);
 | 
				
			||||||
impl_from_t_for_room_event!(MessageEvent, RoomMessage);
 | 
					impl_from_t_for_room_event!(MessageEvent, RoomMessage);
 | 
				
			||||||
 | 
					impl_from_t_for_room_event!(FeedbackEvent, RoomMessageFeedback);
 | 
				
			||||||
impl_from_t_for_room_event!(RedactionEvent, RoomRedaction);
 | 
					impl_from_t_for_room_event!(RedactionEvent, RoomRedaction);
 | 
				
			||||||
impl_from_t_for_room_event!(CustomRoomEvent, CustomRoom);
 | 
					impl_from_t_for_room_event!(CustomRoomEvent, CustomRoom);
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,7 @@ mod tests {
 | 
				
			|||||||
                assert!(direct_rooms.contains(&rooms[0]));
 | 
					                assert!(direct_rooms.contains(&rooms[0]));
 | 
				
			||||||
                assert!(direct_rooms.contains(&rooms[1]));
 | 
					                assert!(direct_rooms.contains(&rooms[1]));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => assert!(false),
 | 
					            _ => unreachable!(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match from_str::<collections::only::Event>(&json_data).unwrap() {
 | 
					        match from_str::<collections::only::Event>(&json_data).unwrap() {
 | 
				
			||||||
@ -96,7 +96,7 @@ mod tests {
 | 
				
			|||||||
                assert!(direct_rooms.contains(&rooms[0]));
 | 
					                assert!(direct_rooms.contains(&rooms[0]));
 | 
				
			||||||
                assert!(direct_rooms.contains(&rooms[1]));
 | 
					                assert!(direct_rooms.contains(&rooms[1]));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => assert!(false),
 | 
					            _ => unreachable!(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/fully_read.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/fully_read.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					//! Types for the *m.fully_read* event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ruma_identifiers::{EventId, RoomId};
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					event! {
 | 
				
			||||||
 | 
					    /// The current location of the user's read marker in a room.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// This event appears in the user's room account data for the room the marker is applicable
 | 
				
			||||||
 | 
					    /// for.
 | 
				
			||||||
 | 
					    pub struct FullyReadEvent(FullyReadEventContent) {
 | 
				
			||||||
 | 
					        /// The unique identifier for the room associated with this event.
 | 
				
			||||||
 | 
					        pub room_id: RoomId
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// The payload of a `FullyReadEvent`.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct FullyReadEventContent {
 | 
				
			||||||
 | 
					    /// The event the user's read marker is located at in the room.
 | 
				
			||||||
 | 
					    pub event_id: EventId,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -118,6 +118,7 @@ pub mod collections {
 | 
				
			|||||||
    pub mod only;
 | 
					    pub mod only;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
pub mod direct;
 | 
					pub mod direct;
 | 
				
			||||||
 | 
					pub mod fully_read;
 | 
				
			||||||
pub mod presence;
 | 
					pub mod presence;
 | 
				
			||||||
pub mod receipt;
 | 
					pub mod receipt;
 | 
				
			||||||
pub mod room;
 | 
					pub mod room;
 | 
				
			||||||
@ -142,6 +143,8 @@ pub enum EventType {
 | 
				
			|||||||
    CallInvite,
 | 
					    CallInvite,
 | 
				
			||||||
    /// m.direct
 | 
					    /// m.direct
 | 
				
			||||||
    Direct,
 | 
					    Direct,
 | 
				
			||||||
 | 
					    /// m.fully_read
 | 
				
			||||||
 | 
					    FullyRead,
 | 
				
			||||||
    /// m.presence
 | 
					    /// m.presence
 | 
				
			||||||
    Presence,
 | 
					    Presence,
 | 
				
			||||||
    /// m.receipt
 | 
					    /// m.receipt
 | 
				
			||||||
@ -164,6 +167,8 @@ pub enum EventType {
 | 
				
			|||||||
    RoomMember,
 | 
					    RoomMember,
 | 
				
			||||||
    /// m.room.message
 | 
					    /// m.room.message
 | 
				
			||||||
    RoomMessage,
 | 
					    RoomMessage,
 | 
				
			||||||
 | 
					    /// m.room.message.feedback
 | 
				
			||||||
 | 
					    RoomMessageFeedback,
 | 
				
			||||||
    /// m.room.name
 | 
					    /// m.room.name
 | 
				
			||||||
    RoomName,
 | 
					    RoomName,
 | 
				
			||||||
    /// m.room.pinned_events
 | 
					    /// m.room.pinned_events
 | 
				
			||||||
@ -253,6 +258,7 @@ impl Display for EventType {
 | 
				
			|||||||
            EventType::CallHangup => "m.call.hangup",
 | 
					            EventType::CallHangup => "m.call.hangup",
 | 
				
			||||||
            EventType::CallInvite => "m.call.invite",
 | 
					            EventType::CallInvite => "m.call.invite",
 | 
				
			||||||
            EventType::Direct => "m.direct",
 | 
					            EventType::Direct => "m.direct",
 | 
				
			||||||
 | 
					            EventType::FullyRead => "m.fully_read",
 | 
				
			||||||
            EventType::Presence => "m.presence",
 | 
					            EventType::Presence => "m.presence",
 | 
				
			||||||
            EventType::Receipt => "m.receipt",
 | 
					            EventType::Receipt => "m.receipt",
 | 
				
			||||||
            EventType::RoomAliases => "m.room.aliases",
 | 
					            EventType::RoomAliases => "m.room.aliases",
 | 
				
			||||||
@ -264,6 +270,7 @@ impl Display for EventType {
 | 
				
			|||||||
            EventType::RoomJoinRules => "m.room.join_rules",
 | 
					            EventType::RoomJoinRules => "m.room.join_rules",
 | 
				
			||||||
            EventType::RoomMember => "m.room.member",
 | 
					            EventType::RoomMember => "m.room.member",
 | 
				
			||||||
            EventType::RoomMessage => "m.room.message",
 | 
					            EventType::RoomMessage => "m.room.message",
 | 
				
			||||||
 | 
					            EventType::RoomMessageFeedback => "m.room.message.feedback",
 | 
				
			||||||
            EventType::RoomName => "m.room.name",
 | 
					            EventType::RoomName => "m.room.name",
 | 
				
			||||||
            EventType::RoomPinnedEvents => "m.room.pinned_events",
 | 
					            EventType::RoomPinnedEvents => "m.room.pinned_events",
 | 
				
			||||||
            EventType::RoomPowerLevels => "m.room.power_levels",
 | 
					            EventType::RoomPowerLevels => "m.room.power_levels",
 | 
				
			||||||
@ -287,6 +294,7 @@ impl<'a> From<&'a str> for EventType {
 | 
				
			|||||||
            "m.call.hangup" => EventType::CallHangup,
 | 
					            "m.call.hangup" => EventType::CallHangup,
 | 
				
			||||||
            "m.call.invite" => EventType::CallInvite,
 | 
					            "m.call.invite" => EventType::CallInvite,
 | 
				
			||||||
            "m.direct" => EventType::Direct,
 | 
					            "m.direct" => EventType::Direct,
 | 
				
			||||||
 | 
					            "m.fully_read" => EventType::FullyRead,
 | 
				
			||||||
            "m.presence" => EventType::Presence,
 | 
					            "m.presence" => EventType::Presence,
 | 
				
			||||||
            "m.receipt" => EventType::Receipt,
 | 
					            "m.receipt" => EventType::Receipt,
 | 
				
			||||||
            "m.room.aliases" => EventType::RoomAliases,
 | 
					            "m.room.aliases" => EventType::RoomAliases,
 | 
				
			||||||
@ -298,6 +306,7 @@ impl<'a> From<&'a str> for EventType {
 | 
				
			|||||||
            "m.room.join_rules" => EventType::RoomJoinRules,
 | 
					            "m.room.join_rules" => EventType::RoomJoinRules,
 | 
				
			||||||
            "m.room.member" => EventType::RoomMember,
 | 
					            "m.room.member" => EventType::RoomMember,
 | 
				
			||||||
            "m.room.message" => EventType::RoomMessage,
 | 
					            "m.room.message" => EventType::RoomMessage,
 | 
				
			||||||
 | 
					            "m.room.message.feedback" => EventType::RoomMessageFeedback,
 | 
				
			||||||
            "m.room.name" => EventType::RoomName,
 | 
					            "m.room.name" => EventType::RoomName,
 | 
				
			||||||
            "m.room.pinned_events" => EventType::RoomPinnedEvents,
 | 
					            "m.room.pinned_events" => EventType::RoomPinnedEvents,
 | 
				
			||||||
            "m.room.power_levels" => EventType::RoomPowerLevels,
 | 
					            "m.room.power_levels" => EventType::RoomPowerLevels,
 | 
				
			||||||
 | 
				
			|||||||
@ -78,7 +78,7 @@ mod tests {
 | 
				
			|||||||
                avatar_url: Some("mxc://localhost:wefuiwegh8742w".to_string()),
 | 
					                avatar_url: Some("mxc://localhost:wefuiwegh8742w".to_string()),
 | 
				
			||||||
                currently_active: Some(false),
 | 
					                currently_active: Some(false),
 | 
				
			||||||
                displayname: None,
 | 
					                displayname: None,
 | 
				
			||||||
                last_active_ago: Some(2478593),
 | 
					                last_active_ago: Some(2_478_593),
 | 
				
			||||||
                presence: PresenceState::Online,
 | 
					                presence: PresenceState::Online,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            event_type: EventType::Presence,
 | 
					            event_type: EventType::Presence,
 | 
				
			||||||
 | 
				
			|||||||
@ -9,11 +9,7 @@ event! {
 | 
				
			|||||||
    /// Informs the client of new receipts.
 | 
					    /// Informs the client of new receipts.
 | 
				
			||||||
    pub struct ReceiptEvent(ReceiptEventContent) {
 | 
					    pub struct ReceiptEvent(ReceiptEventContent) {
 | 
				
			||||||
        /// The unique identifier for the room associated with this event.
 | 
					        /// The unique identifier for the room associated with this event.
 | 
				
			||||||
        ///
 | 
					        pub room_id: RoomId
 | 
				
			||||||
        /// This can be `None` if the event came from a context where there is
 | 
					 | 
				
			||||||
        /// no ambiguity which room it belongs to, like a `/sync` response for example.
 | 
					 | 
				
			||||||
        #[serde(skip_serializing_if="Option::is_none")]
 | 
					 | 
				
			||||||
        pub room_id: Option<RoomId>
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29,7 +25,7 @@ pub struct Receipts {
 | 
				
			|||||||
    /// A collection of users who have sent *m.read* receipts for this event.
 | 
					    /// A collection of users who have sent *m.read* receipts for this event.
 | 
				
			||||||
    #[serde(rename = "m.read")]
 | 
					    #[serde(rename = "m.read")]
 | 
				
			||||||
    #[serde(default)]
 | 
					    #[serde(default)]
 | 
				
			||||||
    pub m_read: UserReceipts,
 | 
					    pub read: UserReceipts,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A mapping of user ID to receipt.
 | 
					/// A mapping of user ID to receipt.
 | 
				
			||||||
@ -40,6 +36,6 @@ pub type UserReceipts = HashMap<UserId, Receipt>;
 | 
				
			|||||||
/// An acknowledgement of an event.
 | 
					/// An acknowledgement of an event.
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
				
			||||||
pub struct Receipt {
 | 
					pub struct Receipt {
 | 
				
			||||||
    /// The timestamp the receipt was sent at.
 | 
					    /// The timestamp (milliseconds since the Unix epoch) when the receipt was sent.
 | 
				
			||||||
    pub ts: u64,
 | 
					    pub ts: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,11 +18,6 @@ pub struct AvatarEventContent {
 | 
				
			|||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub info: Option<ImageInfo>,
 | 
					    pub info: Option<ImageInfo>,
 | 
				
			||||||
    /// Information about the avatar thumbnail image.
 | 
					    /// Information about the avatar thumbnail image.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					 | 
				
			||||||
    pub thumbnail_info: Option<ImageInfo>,
 | 
					 | 
				
			||||||
    /// URL of the avatar thumbnail image.
 | 
					 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					 | 
				
			||||||
    pub thumbnail_url: Option<String>,
 | 
					 | 
				
			||||||
    /// URL of the avatar image.
 | 
					    /// URL of the avatar image.
 | 
				
			||||||
    pub url: String,
 | 
					    pub url: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
//! Types for the *m.room.create* event.
 | 
					//! Types for the *m.room.create* event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use ruma_identifiers::UserId;
 | 
					use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId};
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
state_event! {
 | 
					state_event! {
 | 
				
			||||||
@ -10,11 +10,24 @@ state_event! {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a `CreateEvent`.
 | 
					/// The payload of a `CreateEvent`.
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
pub struct CreateEventContent {
 | 
					pub struct CreateEventContent {
 | 
				
			||||||
    /// The `user_id` of the room creator. This is set by the homeserver.
 | 
					    /// The `user_id` of the room creator. This is set by the homeserver.
 | 
				
			||||||
    pub creator: UserId,
 | 
					    pub creator: UserId,
 | 
				
			||||||
    /// Whether or not this room's data should be transferred to other homeservers.
 | 
					    /// Whether or not this room's data should be transferred to other homeservers.
 | 
				
			||||||
    #[serde(rename = "m.federate")]
 | 
					    #[serde(rename = "m.federate")]
 | 
				
			||||||
    pub federate: Option<bool>,
 | 
					    pub federate: Option<bool>,
 | 
				
			||||||
 | 
					    /// The version of the room. Defaults to "1" if the key does not exist.
 | 
				
			||||||
 | 
					    pub room_version: RoomVersionId,
 | 
				
			||||||
 | 
					    /// A reference to the room this room replaces, if the previous room was upgraded.
 | 
				
			||||||
 | 
					    pub predecessor: PreviousRoom,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A reference to an old room replaced during a room version upgrade.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct PreviousRoom {
 | 
				
			||||||
 | 
					    /// The ID of the old room.
 | 
				
			||||||
 | 
					    pub room_id: RoomId,
 | 
				
			||||||
 | 
					    /// The event ID of the last known event in the old room.
 | 
				
			||||||
 | 
					    pub event_id: EventId,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,38 +4,40 @@ use ruma_identifiers::UserId;
 | 
				
			|||||||
use ruma_signatures::Signatures;
 | 
					use ruma_signatures::Signatures;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::stripped::StrippedState;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
state_event! {
 | 
					state_event! {
 | 
				
			||||||
    /// The current membership state of a user in the room.
 | 
					    /// The current membership state of a user in the room.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Adjusts the membership state for a user in a room. It is preferable to use the membership
 | 
					    /// Adjusts the membership state for a user in a room. It is preferable to use the membership
 | 
				
			||||||
    /// APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than
 | 
					    /// APIs (`/rooms/<room id>/invite` etc) when performing membership actions rather than
 | 
				
			||||||
    /// adjusting the state directly as there are a restricted set of valid transformations. For
 | 
					    /// adjusting the state directly as there are a restricted set of valid transformations. For
 | 
				
			||||||
    /// example, user A cannot force user B to join a room, and trying to force this state change
 | 
					    /// example, user A cannot force user B to join a room, and trying to force this state change
 | 
				
			||||||
    /// directly will fail.
 | 
					    /// directly will fail.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// The *third_party_invite* property will be set if this invite is an *invite* event and is the
 | 
					    /// The `third_party_invite` property will be set if this invite is an *invite* event and is the
 | 
				
			||||||
    /// successor of an *m.room.third_party_invite* event, and absent otherwise.
 | 
					    /// successor of an *m.room.third_party_invite* event, and absent otherwise.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This event may also include an *invite_room_state* key outside the *content* key. If
 | 
					    /// This event may also include an `invite_room_state` key inside the event's unsigned data. If
 | 
				
			||||||
    /// present, this contains an array of `StrippedState` events. These events provide information
 | 
					    /// present, this contains an array of `StrippedState` events. These events provide information
 | 
				
			||||||
    /// on a few select state events such as the room name.
 | 
					    /// on a subset of state events such as the room name.
 | 
				
			||||||
    pub struct MemberEvent(MemberEventContent) {
 | 
					    ///
 | 
				
			||||||
        /// A subset of the state of the room at the time of the invite.
 | 
					    /// The user for which a membership applies is represented by the `state_key`. Under some
 | 
				
			||||||
        #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    /// conditions, the `sender` and `state_key` may not match - this may be interpreted as the
 | 
				
			||||||
        pub invite_room_state: Option<Vec<StrippedState>>
 | 
					    /// `sender` affecting the membership state of the `state_key` user.
 | 
				
			||||||
    }
 | 
					    ///
 | 
				
			||||||
 | 
					    /// 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.
 | 
				
			||||||
 | 
					    pub struct MemberEvent(MemberEventContent) {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a `MemberEvent`.
 | 
					/// The payload of a `MemberEvent`.
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
				
			||||||
pub struct MemberEventContent {
 | 
					pub struct MemberEventContent {
 | 
				
			||||||
    /// The avatar URL for this user.
 | 
					    /// The avatar URL for this user, if any. This is added by the homeserver.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub avatar_url: Option<String>,
 | 
					    pub avatar_url: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The display name for this user.
 | 
					    /// The display name for this user, if any. This is added by the homeserver.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub displayname: Option<String>,
 | 
					    pub displayname: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,12 @@
 | 
				
			|||||||
//! Types for the *m.room.message* event.
 | 
					//! Types for the *m.room.message* event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ruma_identifiers::EventId;
 | 
				
			||||||
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
 | 
					use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
 | 
				
			||||||
use serde_json::{from_value, Value};
 | 
					use serde_json::{from_value, Value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{ImageInfo, ThumbnailInfo};
 | 
					use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod feedback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
room_event! {
 | 
					room_event! {
 | 
				
			||||||
    /// A message sent to a room.
 | 
					    /// A message sent to a room.
 | 
				
			||||||
@ -47,6 +50,7 @@ pub enum MessageType {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a message event.
 | 
					/// The payload of a message event.
 | 
				
			||||||
 | 
					#[allow(clippy::large_enum_variant)]
 | 
				
			||||||
#[derive(Clone, Debug, PartialEq)]
 | 
					#[derive(Clone, Debug, PartialEq)]
 | 
				
			||||||
pub enum MessageEventContent {
 | 
					pub enum MessageEventContent {
 | 
				
			||||||
    /// An audio message.
 | 
					    /// An audio message.
 | 
				
			||||||
@ -84,8 +88,13 @@ pub struct AudioMessageEventContent {
 | 
				
			|||||||
    pub info: Option<AudioInfo>,
 | 
					    pub info: Option<AudioInfo>,
 | 
				
			||||||
    /// The message type. Always *m.audio*.
 | 
					    /// The message type. Always *m.audio*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
    /// The URL to the audio clip.
 | 
					    /// The URL to the audio clip. Required if the file is unencrypted. The URL (typically
 | 
				
			||||||
    pub url: String,
 | 
					    /// [MXC URI](https://matrix.org/docs/spec/client_server/r0.5.0#mxc-uri)) to the audio clip.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub url: Option<String>,
 | 
				
			||||||
 | 
					    /// Required if the audio clip is encrypted. Information on the encrypted audio clip.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Metadata about an audio clip.
 | 
					/// Metadata about an audio clip.
 | 
				
			||||||
@ -109,6 +118,13 @@ pub struct EmoteMessageEventContent {
 | 
				
			|||||||
    pub body: String,
 | 
					    pub body: String,
 | 
				
			||||||
    /// The message type. Always *m.emote*.
 | 
					    /// The message type. Always *m.emote*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
 | 
					    /// The format used in the `formatted_body`. Currently only `org.matrix.custom.html` is
 | 
				
			||||||
 | 
					    /// supported.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub format: Option<String>,
 | 
				
			||||||
 | 
					    /// The formatted version of the `body`. This is required if `format` is specified.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub formatted_body: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a file message.
 | 
					/// The payload of a file message.
 | 
				
			||||||
@ -118,14 +134,20 @@ pub struct FileMessageEventContent {
 | 
				
			|||||||
    /// original upload.
 | 
					    /// original upload.
 | 
				
			||||||
    pub body: String,
 | 
					    pub body: String,
 | 
				
			||||||
    /// The original filename of the uploaded file.
 | 
					    /// The original filename of the uploaded file.
 | 
				
			||||||
    pub filename: String,
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub filename: Option<String>,
 | 
				
			||||||
    /// Metadata about the file referred to in `url`.
 | 
					    /// Metadata about the file referred to in `url`.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub info: Option<FileInfo>,
 | 
					    pub info: Option<FileInfo>,
 | 
				
			||||||
    /// The message type. Always *m.file*.
 | 
					    /// The message type. Always *m.file*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
    /// The URL to the file.
 | 
					    /// The URL to the file. Required if the file is unencrypted. The URL (typically
 | 
				
			||||||
    pub url: String,
 | 
					    /// [MXC URI](https://matrix.org/docs/spec/client_server/r0.5.0#mxc-uri)) to the file.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub url: Option<String>,
 | 
				
			||||||
 | 
					    /// Required if file is encrypted. Information on the encrypted file.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Metadata about a file.
 | 
					/// Metadata about a file.
 | 
				
			||||||
@ -138,9 +160,12 @@ pub struct FileInfo {
 | 
				
			|||||||
    /// Metadata about the image referred to in `thumbnail_url`.
 | 
					    /// Metadata about the image referred to in `thumbnail_url`.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
					    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
				
			||||||
    /// The URL to the thumbnail of the file.
 | 
					    /// The URL to the thumbnail of the file. Only present if the thumbnail is unencrypted.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_url: Option<String>,
 | 
					    pub thumbnail_url: Option<String>,
 | 
				
			||||||
 | 
					    /// Information on the encrypted thumbnail file. Only present if the thumbnail is encrypted.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub thumbnail_file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of an image message.
 | 
					/// The payload of an image message.
 | 
				
			||||||
@ -154,8 +179,12 @@ pub struct ImageMessageEventContent {
 | 
				
			|||||||
    pub info: Option<ImageInfo>,
 | 
					    pub info: Option<ImageInfo>,
 | 
				
			||||||
    /// The message type. Always *m.image*.
 | 
					    /// The message type. Always *m.image*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
    /// The URL to the image.
 | 
					    /// The URL to the image.  Required if the file is unencrypted. The URL (typically
 | 
				
			||||||
    pub url: String,
 | 
					    /// [MXC URI](https://matrix.org/docs/spec/client_server/r0.5.0#mxc-uri)) to the image.
 | 
				
			||||||
 | 
					    pub url: Option<String>,
 | 
				
			||||||
 | 
					    /// Required if image is encrypted. Information on the encrypted image.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a location message.
 | 
					/// The payload of a location message.
 | 
				
			||||||
@ -176,12 +205,17 @@ pub struct LocationMessageEventContent {
 | 
				
			|||||||
/// Thumbnail info associated with a location.
 | 
					/// Thumbnail info associated with a location.
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
pub struct LocationInfo {
 | 
					pub struct LocationInfo {
 | 
				
			||||||
    /// Metadata about the image referred to in `thumbnail_url`.
 | 
					    /// Metadata about the image referred to in `thumbnail_url` or `thumbnail_file`.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
					    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
				
			||||||
    /// The URL to a thumbnail of the location being represented.
 | 
					    /// The URL to a thumbnail of the location being represented. Only present if the thumbnail is
 | 
				
			||||||
 | 
					    /// unencrypted.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_url: Option<String>,
 | 
					    pub thumbnail_url: Option<String>,
 | 
				
			||||||
 | 
					    /// Information on an encrypted thumbnail of the location being represented. Only present if the
 | 
				
			||||||
 | 
					    /// thumbnail is encrypted.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub thumbnail_file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a notice message.
 | 
					/// The payload of a notice message.
 | 
				
			||||||
@ -191,6 +225,11 @@ pub struct NoticeMessageEventContent {
 | 
				
			|||||||
    pub body: String,
 | 
					    pub body: String,
 | 
				
			||||||
    /// The message type. Always *m.notice*.
 | 
					    /// The message type. Always *m.notice*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
 | 
					    /// Information about related messages for
 | 
				
			||||||
 | 
					    /// [rich replies](https://matrix.org/docs/spec/client_server/r0.5.0#rich-replies).
 | 
				
			||||||
 | 
					    #[serde(rename = "m.relates_to")]
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub relates_to: Option<RelatesTo>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a text message.
 | 
					/// The payload of a text message.
 | 
				
			||||||
@ -200,6 +239,18 @@ pub struct TextMessageEventContent {
 | 
				
			|||||||
    pub body: String,
 | 
					    pub body: String,
 | 
				
			||||||
    /// The message type. Always *m.text*.
 | 
					    /// The message type. Always *m.text*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
 | 
					    /// The format used in the `formatted_body`. Currently only `org.matrix.custom.html` is
 | 
				
			||||||
 | 
					    /// supported.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub format: Option<String>,
 | 
				
			||||||
 | 
					    /// The formatted version of the `body`. This is required if `format` is specified.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub formatted_body: Option<String>,
 | 
				
			||||||
 | 
					    /// Information about related messages for
 | 
				
			||||||
 | 
					    /// [rich replies](https://matrix.org/docs/spec/client_server/r0.5.0#rich-replies).
 | 
				
			||||||
 | 
					    #[serde(rename = "m.relates_to")]
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub relates_to: Option<RelatesTo>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The payload of a video message.
 | 
					/// The payload of a video message.
 | 
				
			||||||
@ -213,8 +264,12 @@ pub struct VideoMessageEventContent {
 | 
				
			|||||||
    pub info: Option<VideoInfo>,
 | 
					    pub info: Option<VideoInfo>,
 | 
				
			||||||
    /// The message type. Always *m.video*.
 | 
					    /// The message type. Always *m.video*.
 | 
				
			||||||
    pub msgtype: MessageType,
 | 
					    pub msgtype: MessageType,
 | 
				
			||||||
    /// The URL to the video clip.
 | 
					    /// The URL to the video clip.  Required if the file is unencrypted. The URL (typically
 | 
				
			||||||
    pub url: String,
 | 
					    /// [MXC URI](https://matrix.org/docs/spec/client_server/r0.5.0#mxc-uri)) to the video clip.
 | 
				
			||||||
 | 
					    pub url: Option<String>,
 | 
				
			||||||
 | 
					    /// Required if video clip is encrypted. Information on the encrypted video clip.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub file: Option<EncryptedFile>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Metadata about a video.
 | 
					/// Metadata about a video.
 | 
				
			||||||
@ -236,15 +291,35 @@ pub struct VideoInfo {
 | 
				
			|||||||
    /// Metadata about an image.
 | 
					    /// Metadata about an image.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
					    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
				
			||||||
    /// The URL to a thumbnail of the video clip.
 | 
					    /// The URL (typically [MXC URI](https://matrix.org/docs/spec/client_server/r0.5.0#mxc-uri)) to
 | 
				
			||||||
 | 
					    /// an image thumbnail of the video clip. Only present if the thumbnail is unencrypted.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_url: Option<String>,
 | 
					    pub thumbnail_url: Option<String>,
 | 
				
			||||||
 | 
					    /// Information on the encrypted thumbnail file.  Only present if the thumbnail is encrypted.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub thumbnail_file: Option<EncryptedFile>,
 | 
				
			||||||
    /// The width of the video in pixels.
 | 
					    /// The width of the video in pixels.
 | 
				
			||||||
    #[serde(rename = "w")]
 | 
					    #[serde(rename = "w")]
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub width: Option<u64>,
 | 
					    pub width: Option<u64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Information about related messages for
 | 
				
			||||||
 | 
					/// [rich replies](https://matrix.org/docs/spec/client_server/r0.5.0#rich-replies).
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct RelatesTo {
 | 
				
			||||||
 | 
					    /// Information about another message being replied to.
 | 
				
			||||||
 | 
					    #[serde(rename = "m.in_reply_to")]
 | 
				
			||||||
 | 
					    pub in_reply_to: InReplyTo,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Information about the event a "rich reply" is replying to.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct InReplyTo {
 | 
				
			||||||
 | 
					    /// The event being replied to.
 | 
				
			||||||
 | 
					    pub event_id: EventId,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_enum! {
 | 
					impl_enum! {
 | 
				
			||||||
    MessageType {
 | 
					    MessageType {
 | 
				
			||||||
        Audio => "m.audio",
 | 
					        Audio => "m.audio",
 | 
				
			||||||
@ -374,7 +449,8 @@ mod tests {
 | 
				
			|||||||
            body: "test".to_string(),
 | 
					            body: "test".to_string(),
 | 
				
			||||||
            info: None,
 | 
					            info: None,
 | 
				
			||||||
            msgtype: MessageType::Audio,
 | 
					            msgtype: MessageType::Audio,
 | 
				
			||||||
            url: "http://example.com/audio.mp3".to_string(),
 | 
					            url: Some("http://example.com/audio.mp3".to_string()),
 | 
				
			||||||
 | 
					            file: None,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
@ -389,7 +465,8 @@ mod tests {
 | 
				
			|||||||
            body: "test".to_string(),
 | 
					            body: "test".to_string(),
 | 
				
			||||||
            info: None,
 | 
					            info: None,
 | 
				
			||||||
            msgtype: MessageType::Audio,
 | 
					            msgtype: MessageType::Audio,
 | 
				
			||||||
            url: "http://example.com/audio.mp3".to_string(),
 | 
					            url: Some("http://example.com/audio.mp3".to_string()),
 | 
				
			||||||
 | 
					            file: None,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										41
									
								
								src/room/message/feedback.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/room/message/feedback.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					//! Types for the *m.room.message.feedback* event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ruma_identifiers::EventId;
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					room_event! {
 | 
				
			||||||
 | 
					    /// An acknowledgement of a message.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// N.B.: Usage of this event is discouraged in favor of the receipts module. Most clients will
 | 
				
			||||||
 | 
					    /// not recognise this event.
 | 
				
			||||||
 | 
					    pub struct FeedbackEvent(FeedbackEventContent) {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// The payload of an *m.room.message.feedback* event.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct FeedbackEventContent {
 | 
				
			||||||
 | 
					    /// The event that this feedback is related to.
 | 
				
			||||||
 | 
					    pub target_event_id: EventId,
 | 
				
			||||||
 | 
					    /// The type of feedback.
 | 
				
			||||||
 | 
					    #[serde(rename = "type")]
 | 
				
			||||||
 | 
					    pub feedback_type: FeedbackType,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A type of feedback.
 | 
				
			||||||
 | 
					#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub enum FeedbackType {
 | 
				
			||||||
 | 
					    /// Sent when a message is received.
 | 
				
			||||||
 | 
					    #[serde(rename = "delivered")]
 | 
				
			||||||
 | 
					    Delivered,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sent when a message has been observed by the end user.
 | 
				
			||||||
 | 
					    #[serde(rename = "read")]
 | 
				
			||||||
 | 
					    Read,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl_enum! {
 | 
				
			||||||
 | 
					    FeedbackType {
 | 
				
			||||||
 | 
					        Delivered => "delivered",
 | 
				
			||||||
 | 
					        Read => "read",
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,6 +2,8 @@
 | 
				
			|||||||
//!
 | 
					//!
 | 
				
			||||||
//! This module also contains types shared by events in its child namespaces.
 | 
					//! This module also contains types shared by events in its child namespaces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod aliases;
 | 
					pub mod aliases;
 | 
				
			||||||
@ -33,9 +35,12 @@ pub struct ImageInfo {
 | 
				
			|||||||
    /// Metadata about the image referred to in `thumbnail_url`.
 | 
					    /// Metadata about the image referred to in `thumbnail_url`.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
					    pub thumbnail_info: Option<ThumbnailInfo>,
 | 
				
			||||||
    /// The URL to the thumbnail of the image.
 | 
					    /// The URL to the thumbnail of the image. Only present if the thumbnail is unencrypted.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub thumbnail_url: Option<String>,
 | 
					    pub thumbnail_url: Option<String>,
 | 
				
			||||||
 | 
					    /// Information on the encrypted thumbnail image. Only present if the thumbnail is encrypted.
 | 
				
			||||||
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					    pub thumbnail_file: Option<EncryptedFile>,
 | 
				
			||||||
    /// The width of the image in pixels.
 | 
					    /// The width of the image in pixels.
 | 
				
			||||||
    #[serde(rename = "w")]
 | 
					    #[serde(rename = "w")]
 | 
				
			||||||
    pub width: u64,
 | 
					    pub width: u64,
 | 
				
			||||||
@ -55,3 +60,35 @@ pub struct ThumbnailInfo {
 | 
				
			|||||||
    #[serde(rename = "w")]
 | 
					    #[serde(rename = "w")]
 | 
				
			||||||
    pub width: u64,
 | 
					    pub width: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A file sent to a room with end-to-end encryption enabled.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct EncryptedFile {
 | 
				
			||||||
 | 
					    /// The URL to the file.
 | 
				
			||||||
 | 
					    pub url: String,
 | 
				
			||||||
 | 
					    /// A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object.
 | 
				
			||||||
 | 
					    pub key: JsonWebKey,
 | 
				
			||||||
 | 
					    /// The initialization vector used by AES-CTR, encoded as unpadded base64.
 | 
				
			||||||
 | 
					    pub iv: String,
 | 
				
			||||||
 | 
					    /// A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64.
 | 
				
			||||||
 | 
					    /// Clients should support the SHA-256 hash, which uses the key sha256.
 | 
				
			||||||
 | 
					    pub hashes: HashMap<String, String>,
 | 
				
			||||||
 | 
					    /// Version of the encrypted attachments protocol. Must be `v2`.
 | 
				
			||||||
 | 
					    pub v: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object.
 | 
				
			||||||
 | 
					#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
				
			||||||
 | 
					pub struct JsonWebKey {
 | 
				
			||||||
 | 
					    /// Key type. Must be `oct`.
 | 
				
			||||||
 | 
					    pub kty: String,
 | 
				
			||||||
 | 
					    /// Key operations. Must at least contain `encrypt` and `decrypt`.
 | 
				
			||||||
 | 
					    pub key_ops: Vec<String>,
 | 
				
			||||||
 | 
					    /// Required. Algorithm. Must be `A256CTR`.
 | 
				
			||||||
 | 
					    pub alg: String,
 | 
				
			||||||
 | 
					    /// The key, encoded as urlsafe unpadded base64.
 | 
				
			||||||
 | 
					    pub k: String,
 | 
				
			||||||
 | 
					    /// Extractable. Must be `true`. This is a
 | 
				
			||||||
 | 
					    /// [W3C extension](https://w3c.github.io/webcrypto/#iana-section-jwk).
 | 
				
			||||||
 | 
					    pub ext: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,6 @@ state_event! {
 | 
				
			|||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
					#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
				
			||||||
pub struct NameEventContent {
 | 
					pub struct NameEventContent {
 | 
				
			||||||
    /// The name of the room. This MUST NOT exceed 255 bytes.
 | 
					    /// The name of the room. This MUST NOT exceed 255 bytes.
 | 
				
			||||||
    /// Rooms with `name: None` should be treated the same as a room with no name.
 | 
					 | 
				
			||||||
    // The spec says “A room with an m.room.name event with an absent, null, or empty name field
 | 
					    // 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.”.
 | 
					    // should be treated the same as a room with no m.room.name event.”.
 | 
				
			||||||
    // Serde maps null fields to None by default, serde(default) maps an absent field to None,
 | 
					    // Serde maps null fields to None by default, serde(default) maps an absent field to None,
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,7 @@ mod tests {
 | 
				
			|||||||
            content: content.clone(),
 | 
					            content: content.clone(),
 | 
				
			||||||
            event_id: EventId::new("example.com").unwrap(),
 | 
					            event_id: EventId::new("example.com").unwrap(),
 | 
				
			||||||
            event_type: EventType::RoomPinnedEvents,
 | 
					            event_type: EventType::RoomPinnedEvents,
 | 
				
			||||||
            origin_server_ts: 1432804485886,
 | 
					            origin_server_ts: 1_432_804_485_886,
 | 
				
			||||||
            prev_content: None,
 | 
					            prev_content: None,
 | 
				
			||||||
            room_id: Some(RoomId::new("example.com").unwrap()),
 | 
					            room_id: Some(RoomId::new("example.com").unwrap()),
 | 
				
			||||||
            sender: UserId::new("example.com").unwrap(),
 | 
					            sender: UserId::new("example.com").unwrap(),
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,19 @@ pub struct PowerLevelsEventContent {
 | 
				
			|||||||
    /// The default power level for every user in the room.
 | 
					    /// The default power level for every user in the room.
 | 
				
			||||||
    #[serde(default)]
 | 
					    #[serde(default)]
 | 
				
			||||||
    pub users_default: u64,
 | 
					    pub users_default: u64,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The power level requirements for specific notification types.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// This is a mapping from `key` to power level for that notifications key.
 | 
				
			||||||
 | 
					    pub notifications: NotificationPowerLevels,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// The power level requirements for specific notification types.
 | 
				
			||||||
 | 
					#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
 | 
				
			||||||
 | 
					pub struct NotificationPowerLevels {
 | 
				
			||||||
 | 
					    /// The level required to trigger an `@room` notification.
 | 
				
			||||||
 | 
					    #[serde(default = "default_power_level")]
 | 
				
			||||||
 | 
					    pub room: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn default_power_level() -> u64 {
 | 
					fn default_power_level() -> u64 {
 | 
				
			||||||
 | 
				
			|||||||
@ -338,7 +338,7 @@ mod tests {
 | 
				
			|||||||
                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
					                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {
 | 
					            _ => {
 | 
				
			||||||
                assert!(false);
 | 
					                unreachable!();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -350,7 +350,7 @@ mod tests {
 | 
				
			|||||||
                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
					                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {
 | 
					            _ => {
 | 
				
			||||||
                assert!(false);
 | 
					                unreachable!();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -362,14 +362,14 @@ mod tests {
 | 
				
			|||||||
                assert_eq!(image_info.width, 128);
 | 
					                assert_eq!(image_info.width, 128);
 | 
				
			||||||
                assert_eq!(image_info.mimetype, "image/jpeg");
 | 
					                assert_eq!(image_info.mimetype, "image/jpeg");
 | 
				
			||||||
                assert_eq!(image_info.size, 1024);
 | 
					                assert_eq!(image_info.size, 1024);
 | 
				
			||||||
                assert_eq!(event.content.thumbnail_info.unwrap().size, 32);
 | 
					                assert_eq!(image_info.thumbnail_info.unwrap().size, 32);
 | 
				
			||||||
                assert_eq!(event.content.url, "https://domain.com/image.jpg");
 | 
					                assert_eq!(event.content.url, "https://domain.com/image.jpg");
 | 
				
			||||||
                assert_eq!(event.event_type, EventType::RoomAvatar);
 | 
					                assert_eq!(event.event_type, EventType::RoomAvatar);
 | 
				
			||||||
                assert_eq!(event.state_key, "");
 | 
					                assert_eq!(event.state_key, "");
 | 
				
			||||||
                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
					                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => {
 | 
					            _ => {
 | 
				
			||||||
                assert!(false);
 | 
					                unreachable!();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -21,5 +21,5 @@ pub struct TagEventContent {
 | 
				
			|||||||
pub struct TagInfo {
 | 
					pub struct TagInfo {
 | 
				
			||||||
    /// Value to use for lexicographically ordering rooms with this tag.
 | 
					    /// Value to use for lexicographically ordering rooms with this tag.
 | 
				
			||||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
					    #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
    pub order: Option<String>,
 | 
					    pub order: Option<f64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,11 +7,7 @@ event! {
 | 
				
			|||||||
    /// Informs the client of the list of users currently typing.
 | 
					    /// Informs the client of the list of users currently typing.
 | 
				
			||||||
    pub struct TypingEvent(TypingEventContent) {
 | 
					    pub struct TypingEvent(TypingEventContent) {
 | 
				
			||||||
        /// The unique identifier for the room associated with this event.
 | 
					        /// The unique identifier for the room associated with this event.
 | 
				
			||||||
        ///
 | 
					        pub room_id: RoomId
 | 
				
			||||||
        /// This can be `None` if the event came from a context where there is
 | 
					 | 
				
			||||||
        /// no ambiguity which room it belongs to, like a `/sync` response for example.
 | 
					 | 
				
			||||||
        #[serde(skip_serializing_if="Option::is_none")]
 | 
					 | 
				
			||||||
        pub room_id: Option<RoomId>
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user