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,
 | 
			
		||||
    /// The version of the VoIP specification this messages adheres to.
 | 
			
		||||
    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,
 | 
			
		||||
    },
 | 
			
		||||
    direct::DirectEvent,
 | 
			
		||||
    fully_read::FullyReadEvent,
 | 
			
		||||
    presence::PresenceEvent,
 | 
			
		||||
    receipt::ReceiptEvent,
 | 
			
		||||
    room::{
 | 
			
		||||
        aliases::AliasesEvent, avatar::AvatarEvent, canonical_alias::CanonicalAliasEvent,
 | 
			
		||||
        create::CreateEvent, guest_access::GuestAccessEvent,
 | 
			
		||||
        history_visibility::HistoryVisibilityEvent, join_rules::JoinRulesEvent,
 | 
			
		||||
        member::MemberEvent, message::MessageEvent, name::NameEvent,
 | 
			
		||||
        pinned_events::PinnedEventsEvent, power_levels::PowerLevelsEvent,
 | 
			
		||||
        redaction::RedactionEvent, third_party_invite::ThirdPartyInviteEvent, topic::TopicEvent,
 | 
			
		||||
        aliases::AliasesEvent,
 | 
			
		||||
        avatar::AvatarEvent,
 | 
			
		||||
        canonical_alias::CanonicalAliasEvent,
 | 
			
		||||
        create::CreateEvent,
 | 
			
		||||
        guest_access::GuestAccessEvent,
 | 
			
		||||
        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,
 | 
			
		||||
    typing::TypingEvent,
 | 
			
		||||
@ -38,6 +48,8 @@ pub enum Event {
 | 
			
		||||
    CallInvite(InviteEvent),
 | 
			
		||||
    /// m.direct
 | 
			
		||||
    Direct(DirectEvent),
 | 
			
		||||
    /// m.fully_read
 | 
			
		||||
    FullyRead(FullyReadEvent),
 | 
			
		||||
    /// m.presence
 | 
			
		||||
    Presence(PresenceEvent),
 | 
			
		||||
    /// m.receipt
 | 
			
		||||
@ -60,6 +72,8 @@ pub enum Event {
 | 
			
		||||
    RoomMember(MemberEvent),
 | 
			
		||||
    /// m.room.message
 | 
			
		||||
    RoomMessage(MessageEvent),
 | 
			
		||||
    /// m.room.message.feedback
 | 
			
		||||
    RoomMessageFeedback(FeedbackEvent),
 | 
			
		||||
    /// m.room.name
 | 
			
		||||
    RoomName(NameEvent),
 | 
			
		||||
    /// m.room.pinned_events
 | 
			
		||||
@ -114,6 +128,8 @@ pub enum RoomEvent {
 | 
			
		||||
    RoomMember(MemberEvent),
 | 
			
		||||
    /// m.room.message
 | 
			
		||||
    RoomMessage(MessageEvent),
 | 
			
		||||
    /// m.room.message.feedback
 | 
			
		||||
    RoomMessageFeedback(FeedbackEvent),
 | 
			
		||||
    /// m.room.name
 | 
			
		||||
    RoomName(NameEvent),
 | 
			
		||||
    /// m.room.pinned_events
 | 
			
		||||
@ -177,6 +193,7 @@ impl Serialize for Event {
 | 
			
		||||
            Event::CallHangup(ref event) => event.serialize(serializer),
 | 
			
		||||
            Event::CallInvite(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::Receipt(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::RoomMember(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::RoomPinnedEvents(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))
 | 
			
		||||
            }
 | 
			
		||||
            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 => {
 | 
			
		||||
                let event = match from_value::<PresenceEvent>(value) {
 | 
			
		||||
                    Ok(event) => event,
 | 
			
		||||
@ -349,6 +375,14 @@ impl<'de> Deserialize<'de> for 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 => {
 | 
			
		||||
                let event = match from_value::<NameEvent>(value) {
 | 
			
		||||
                    Ok(event) => event,
 | 
			
		||||
@ -463,6 +497,7 @@ impl Serialize for RoomEvent {
 | 
			
		||||
            RoomEvent::RoomJoinRules(ref event) => event.serialize(serializer),
 | 
			
		||||
            RoomEvent::RoomMember(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::RoomPinnedEvents(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))
 | 
			
		||||
            }
 | 
			
		||||
            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 => {
 | 
			
		||||
                let event = match from_value::<NameEvent>(value) {
 | 
			
		||||
                    Ok(event) => event,
 | 
			
		||||
@ -663,6 +706,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            EventType::Direct
 | 
			
		||||
            | EventType::FullyRead
 | 
			
		||||
            | EventType::Presence
 | 
			
		||||
            | EventType::Receipt
 | 
			
		||||
            | EventType::Tag
 | 
			
		||||
@ -830,9 +874,11 @@ impl<'de> Deserialize<'de> for StateEvent {
 | 
			
		||||
            | EventType::CallHangup
 | 
			
		||||
            | EventType::CallInvite
 | 
			
		||||
            | EventType::Direct
 | 
			
		||||
            | EventType::FullyRead
 | 
			
		||||
            | EventType::Presence
 | 
			
		||||
            | EventType::Receipt
 | 
			
		||||
            | EventType::RoomMessage
 | 
			
		||||
            | EventType::RoomMessageFeedback
 | 
			
		||||
            | EventType::RoomRedaction
 | 
			
		||||
            | EventType::Tag
 | 
			
		||||
            | 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!(InviteEvent, CallInvite);
 | 
			
		||||
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!(ReceiptEvent, Receipt);
 | 
			
		||||
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!(MemberEvent, RoomMember);
 | 
			
		||||
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!(PinnedEventsEvent, RoomPinnedEvents);
 | 
			
		||||
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!(MemberEvent, RoomMember);
 | 
			
		||||
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!(PinnedEventsEvent, RoomPinnedEvents);
 | 
			
		||||
impl_from_t_for_room_event!(PowerLevelsEvent, RoomPowerLevels);
 | 
			
		||||
 | 
			
		||||
@ -10,9 +10,13 @@ use crate::{
 | 
			
		||||
        answer::AnswerEvent, candidates::CandidatesEvent, hangup::HangupEvent, invite::InviteEvent,
 | 
			
		||||
    },
 | 
			
		||||
    direct::DirectEvent,
 | 
			
		||||
    fully_read::FullyReadEvent,
 | 
			
		||||
    presence::PresenceEvent,
 | 
			
		||||
    receipt::ReceiptEvent,
 | 
			
		||||
    room::{message::MessageEvent, redaction::RedactionEvent},
 | 
			
		||||
    room::{
 | 
			
		||||
        message::{feedback::FeedbackEvent, MessageEvent},
 | 
			
		||||
        redaction::RedactionEvent,
 | 
			
		||||
    },
 | 
			
		||||
    tag::TagEvent,
 | 
			
		||||
    typing::TypingEvent,
 | 
			
		||||
    CustomEvent, CustomRoomEvent, EventType,
 | 
			
		||||
@ -23,6 +27,8 @@ use crate::{
 | 
			
		||||
pub enum Event {
 | 
			
		||||
    /// m.direct
 | 
			
		||||
    Direct(DirectEvent),
 | 
			
		||||
    /// m.fully_read
 | 
			
		||||
    FullyRead(FullyReadEvent),
 | 
			
		||||
    /// m.presence
 | 
			
		||||
    Presence(PresenceEvent),
 | 
			
		||||
    /// m.receipt
 | 
			
		||||
@ -49,6 +55,8 @@ pub enum RoomEvent {
 | 
			
		||||
    CallInvite(InviteEvent),
 | 
			
		||||
    /// m.room.message
 | 
			
		||||
    RoomMessage(MessageEvent),
 | 
			
		||||
    /// m.room.message.feedback
 | 
			
		||||
    RoomMessageFeedback(FeedbackEvent),
 | 
			
		||||
    /// m.room.redaction
 | 
			
		||||
    RoomRedaction(RedactionEvent),
 | 
			
		||||
    /// Any room event that is not part of the specification.
 | 
			
		||||
@ -62,6 +70,7 @@ impl Serialize for Event {
 | 
			
		||||
    {
 | 
			
		||||
        match *self {
 | 
			
		||||
            Event::Direct(ref event) => event.serialize(serializer),
 | 
			
		||||
            Event::FullyRead(ref event) => event.serialize(serializer),
 | 
			
		||||
            Event::Presence(ref event) => event.serialize(serializer),
 | 
			
		||||
            Event::Receipt(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))
 | 
			
		||||
            }
 | 
			
		||||
            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 => {
 | 
			
		||||
                let event = match from_value::<PresenceEvent>(value) {
 | 
			
		||||
                    Ok(event) => event,
 | 
			
		||||
@ -150,6 +167,7 @@ impl<'de> Deserialize<'de> for Event {
 | 
			
		||||
            | EventType::RoomJoinRules
 | 
			
		||||
            | EventType::RoomMember
 | 
			
		||||
            | EventType::RoomMessage
 | 
			
		||||
            | EventType::RoomMessageFeedback
 | 
			
		||||
            | EventType::RoomName
 | 
			
		||||
            | EventType::RoomPinnedEvents
 | 
			
		||||
            | EventType::RoomPowerLevels
 | 
			
		||||
@ -173,6 +191,7 @@ impl Serialize for RoomEvent {
 | 
			
		||||
            RoomEvent::CallHangup(ref event) => event.serialize(serializer),
 | 
			
		||||
            RoomEvent::CallInvite(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::CustomRoom(ref event) => event.serialize(serializer),
 | 
			
		||||
        }
 | 
			
		||||
@ -237,6 +256,14 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
			
		||||
 | 
			
		||||
                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 => {
 | 
			
		||||
                let event = match from_value::<RedactionEvent>(value) {
 | 
			
		||||
                    Ok(event) => event,
 | 
			
		||||
@ -254,6 +281,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
 | 
			
		||||
                Ok(RoomEvent::CustomRoom(event))
 | 
			
		||||
            }
 | 
			
		||||
            EventType::Direct
 | 
			
		||||
            | EventType::FullyRead
 | 
			
		||||
            | EventType::Presence
 | 
			
		||||
            | EventType::Receipt
 | 
			
		||||
            | 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!(FullyReadEvent, FullyRead);
 | 
			
		||||
impl_from_t_for_event!(PresenceEvent, Presence);
 | 
			
		||||
impl_from_t_for_event!(ReceiptEvent, Receipt);
 | 
			
		||||
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!(InviteEvent, CallInvite);
 | 
			
		||||
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!(CustomRoomEvent, CustomRoom);
 | 
			
		||||
 | 
			
		||||
@ -85,7 +85,7 @@ mod tests {
 | 
			
		||||
                assert!(direct_rooms.contains(&rooms[0]));
 | 
			
		||||
                assert!(direct_rooms.contains(&rooms[1]));
 | 
			
		||||
            }
 | 
			
		||||
            _ => assert!(false),
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        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[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 direct;
 | 
			
		||||
pub mod fully_read;
 | 
			
		||||
pub mod presence;
 | 
			
		||||
pub mod receipt;
 | 
			
		||||
pub mod room;
 | 
			
		||||
@ -142,6 +143,8 @@ pub enum EventType {
 | 
			
		||||
    CallInvite,
 | 
			
		||||
    /// m.direct
 | 
			
		||||
    Direct,
 | 
			
		||||
    /// m.fully_read
 | 
			
		||||
    FullyRead,
 | 
			
		||||
    /// m.presence
 | 
			
		||||
    Presence,
 | 
			
		||||
    /// m.receipt
 | 
			
		||||
@ -164,6 +167,8 @@ pub enum EventType {
 | 
			
		||||
    RoomMember,
 | 
			
		||||
    /// m.room.message
 | 
			
		||||
    RoomMessage,
 | 
			
		||||
    /// m.room.message.feedback
 | 
			
		||||
    RoomMessageFeedback,
 | 
			
		||||
    /// m.room.name
 | 
			
		||||
    RoomName,
 | 
			
		||||
    /// m.room.pinned_events
 | 
			
		||||
@ -253,6 +258,7 @@ impl Display for EventType {
 | 
			
		||||
            EventType::CallHangup => "m.call.hangup",
 | 
			
		||||
            EventType::CallInvite => "m.call.invite",
 | 
			
		||||
            EventType::Direct => "m.direct",
 | 
			
		||||
            EventType::FullyRead => "m.fully_read",
 | 
			
		||||
            EventType::Presence => "m.presence",
 | 
			
		||||
            EventType::Receipt => "m.receipt",
 | 
			
		||||
            EventType::RoomAliases => "m.room.aliases",
 | 
			
		||||
@ -264,6 +270,7 @@ impl Display for EventType {
 | 
			
		||||
            EventType::RoomJoinRules => "m.room.join_rules",
 | 
			
		||||
            EventType::RoomMember => "m.room.member",
 | 
			
		||||
            EventType::RoomMessage => "m.room.message",
 | 
			
		||||
            EventType::RoomMessageFeedback => "m.room.message.feedback",
 | 
			
		||||
            EventType::RoomName => "m.room.name",
 | 
			
		||||
            EventType::RoomPinnedEvents => "m.room.pinned_events",
 | 
			
		||||
            EventType::RoomPowerLevels => "m.room.power_levels",
 | 
			
		||||
@ -287,6 +294,7 @@ impl<'a> From<&'a str> for EventType {
 | 
			
		||||
            "m.call.hangup" => EventType::CallHangup,
 | 
			
		||||
            "m.call.invite" => EventType::CallInvite,
 | 
			
		||||
            "m.direct" => EventType::Direct,
 | 
			
		||||
            "m.fully_read" => EventType::FullyRead,
 | 
			
		||||
            "m.presence" => EventType::Presence,
 | 
			
		||||
            "m.receipt" => EventType::Receipt,
 | 
			
		||||
            "m.room.aliases" => EventType::RoomAliases,
 | 
			
		||||
@ -298,6 +306,7 @@ impl<'a> From<&'a str> for EventType {
 | 
			
		||||
            "m.room.join_rules" => EventType::RoomJoinRules,
 | 
			
		||||
            "m.room.member" => EventType::RoomMember,
 | 
			
		||||
            "m.room.message" => EventType::RoomMessage,
 | 
			
		||||
            "m.room.message.feedback" => EventType::RoomMessageFeedback,
 | 
			
		||||
            "m.room.name" => EventType::RoomName,
 | 
			
		||||
            "m.room.pinned_events" => EventType::RoomPinnedEvents,
 | 
			
		||||
            "m.room.power_levels" => EventType::RoomPowerLevels,
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ mod tests {
 | 
			
		||||
                avatar_url: Some("mxc://localhost:wefuiwegh8742w".to_string()),
 | 
			
		||||
                currently_active: Some(false),
 | 
			
		||||
                displayname: None,
 | 
			
		||||
                last_active_ago: Some(2478593),
 | 
			
		||||
                last_active_ago: Some(2_478_593),
 | 
			
		||||
                presence: PresenceState::Online,
 | 
			
		||||
            },
 | 
			
		||||
            event_type: EventType::Presence,
 | 
			
		||||
 | 
			
		||||
@ -9,11 +9,7 @@ event! {
 | 
			
		||||
    /// Informs the client of new receipts.
 | 
			
		||||
    pub struct ReceiptEvent(ReceiptEventContent) {
 | 
			
		||||
        /// The unique identifier for the room associated with this event.
 | 
			
		||||
        ///
 | 
			
		||||
        /// 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>
 | 
			
		||||
        pub room_id: RoomId
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,7 +25,7 @@ pub struct Receipts {
 | 
			
		||||
    /// A collection of users who have sent *m.read* receipts for this event.
 | 
			
		||||
    #[serde(rename = "m.read")]
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub m_read: UserReceipts,
 | 
			
		||||
    pub read: UserReceipts,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A mapping of user ID to receipt.
 | 
			
		||||
@ -40,6 +36,6 @@ pub type UserReceipts = HashMap<UserId, Receipt>;
 | 
			
		||||
/// An acknowledgement of an event.
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
			
		||||
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,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,6 @@ pub struct AvatarEventContent {
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    pub info: Option<ImageInfo>,
 | 
			
		||||
    /// 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.
 | 
			
		||||
    pub url: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
//! Types for the *m.room.create* event.
 | 
			
		||||
 | 
			
		||||
use ruma_identifiers::UserId;
 | 
			
		||||
use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
state_event! {
 | 
			
		||||
@ -10,11 +10,24 @@ state_event! {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The payload of a `CreateEvent`.
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
			
		||||
pub struct CreateEventContent {
 | 
			
		||||
    /// The `user_id` of the room creator. This is set by the homeserver.
 | 
			
		||||
    pub creator: UserId,
 | 
			
		||||
    /// Whether or not this room's data should be transferred to other homeservers.
 | 
			
		||||
    #[serde(rename = "m.federate")]
 | 
			
		||||
    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 serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
use crate::stripped::StrippedState;
 | 
			
		||||
 | 
			
		||||
state_event! {
 | 
			
		||||
    /// 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
 | 
			
		||||
    /// 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
 | 
			
		||||
    /// example, user A cannot force user B to join a room, and trying to force this state change
 | 
			
		||||
    /// 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.
 | 
			
		||||
    ///
 | 
			
		||||
    /// 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
 | 
			
		||||
    /// on a few select 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.
 | 
			
		||||
        #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
        pub invite_room_state: Option<Vec<StrippedState>>
 | 
			
		||||
    }
 | 
			
		||||
    /// on a subset of state events such as the room name.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The user for which a membership applies is represented by the `state_key`. Under some
 | 
			
		||||
    /// conditions, the `sender` and `state_key` may not match - this may be interpreted as the
 | 
			
		||||
    /// `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`.
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize)]
 | 
			
		||||
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")]
 | 
			
		||||
    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")]
 | 
			
		||||
    pub displayname: Option<String>,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,12 @@
 | 
			
		||||
//! Types for the *m.room.message* event.
 | 
			
		||||
 | 
			
		||||
use ruma_identifiers::EventId;
 | 
			
		||||
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
 | 
			
		||||
use serde_json::{from_value, Value};
 | 
			
		||||
 | 
			
		||||
use super::{ImageInfo, ThumbnailInfo};
 | 
			
		||||
use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
 | 
			
		||||
 | 
			
		||||
pub mod feedback;
 | 
			
		||||
 | 
			
		||||
room_event! {
 | 
			
		||||
    /// A message sent to a room.
 | 
			
		||||
@ -47,6 +50,7 @@ pub enum MessageType {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The payload of a message event.
 | 
			
		||||
#[allow(clippy::large_enum_variant)]
 | 
			
		||||
#[derive(Clone, Debug, PartialEq)]
 | 
			
		||||
pub enum MessageEventContent {
 | 
			
		||||
    /// An audio message.
 | 
			
		||||
@ -84,8 +88,13 @@ pub struct AudioMessageEventContent {
 | 
			
		||||
    pub info: Option<AudioInfo>,
 | 
			
		||||
    /// The message type. Always *m.audio*.
 | 
			
		||||
    pub msgtype: MessageType,
 | 
			
		||||
    /// The URL to the audio clip.
 | 
			
		||||
    pub url: String,
 | 
			
		||||
    /// The URL to the audio clip. Required if the file is unencrypted. The URL (typically
 | 
			
		||||
    /// [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.
 | 
			
		||||
@ -109,6 +118,13 @@ pub struct EmoteMessageEventContent {
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    /// The message type. Always *m.emote*.
 | 
			
		||||
    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.
 | 
			
		||||
@ -118,14 +134,20 @@ pub struct FileMessageEventContent {
 | 
			
		||||
    /// original upload.
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    /// 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`.
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    pub info: Option<FileInfo>,
 | 
			
		||||
    /// The message type. Always *m.file*.
 | 
			
		||||
    pub msgtype: MessageType,
 | 
			
		||||
    /// The URL to the file.
 | 
			
		||||
    pub url: String,
 | 
			
		||||
    /// The URL to the file. Required if the file is unencrypted. The URL (typically
 | 
			
		||||
    /// [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.
 | 
			
		||||
@ -138,9 +160,12 @@ pub struct FileInfo {
 | 
			
		||||
    /// Metadata about the image referred to in `thumbnail_url`.
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    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")]
 | 
			
		||||
    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.
 | 
			
		||||
@ -154,8 +179,12 @@ pub struct ImageMessageEventContent {
 | 
			
		||||
    pub info: Option<ImageInfo>,
 | 
			
		||||
    /// The message type. Always *m.image*.
 | 
			
		||||
    pub msgtype: MessageType,
 | 
			
		||||
    /// The URL to the image.
 | 
			
		||||
    pub url: String,
 | 
			
		||||
    /// The URL to the image.  Required if the file is unencrypted. The URL (typically
 | 
			
		||||
    /// [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.
 | 
			
		||||
@ -176,12 +205,17 @@ pub struct LocationMessageEventContent {
 | 
			
		||||
/// Thumbnail info associated with a location.
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 | 
			
		||||
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")]
 | 
			
		||||
    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")]
 | 
			
		||||
    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.
 | 
			
		||||
@ -191,6 +225,11 @@ pub struct NoticeMessageEventContent {
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    /// The message type. Always *m.notice*.
 | 
			
		||||
    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.
 | 
			
		||||
@ -200,6 +239,18 @@ pub struct TextMessageEventContent {
 | 
			
		||||
    pub body: String,
 | 
			
		||||
    /// The message type. Always *m.text*.
 | 
			
		||||
    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.
 | 
			
		||||
@ -213,8 +264,12 @@ pub struct VideoMessageEventContent {
 | 
			
		||||
    pub info: Option<VideoInfo>,
 | 
			
		||||
    /// The message type. Always *m.video*.
 | 
			
		||||
    pub msgtype: MessageType,
 | 
			
		||||
    /// The URL to the video clip.
 | 
			
		||||
    pub url: String,
 | 
			
		||||
    /// The URL to the video clip.  Required if the file is unencrypted. The URL (typically
 | 
			
		||||
    /// [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.
 | 
			
		||||
@ -236,15 +291,35 @@ pub struct VideoInfo {
 | 
			
		||||
    /// Metadata about an image.
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    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")]
 | 
			
		||||
    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.
 | 
			
		||||
    #[serde(rename = "w")]
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    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! {
 | 
			
		||||
    MessageType {
 | 
			
		||||
        Audio => "m.audio",
 | 
			
		||||
@ -374,7 +449,8 @@ mod tests {
 | 
			
		||||
            body: "test".to_string(),
 | 
			
		||||
            info: None,
 | 
			
		||||
            msgtype: MessageType::Audio,
 | 
			
		||||
            url: "http://example.com/audio.mp3".to_string(),
 | 
			
		||||
            url: Some("http://example.com/audio.mp3".to_string()),
 | 
			
		||||
            file: None,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
@ -389,7 +465,8 @@ mod tests {
 | 
			
		||||
            body: "test".to_string(),
 | 
			
		||||
            info: None,
 | 
			
		||||
            msgtype: MessageType::Audio,
 | 
			
		||||
            url: "http://example.com/audio.mp3".to_string(),
 | 
			
		||||
            url: Some("http://example.com/audio.mp3".to_string()),
 | 
			
		||||
            file: None,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
pub mod aliases;
 | 
			
		||||
@ -33,9 +35,12 @@ pub struct ImageInfo {
 | 
			
		||||
    /// Metadata about the image referred to in `thumbnail_url`.
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    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")]
 | 
			
		||||
    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.
 | 
			
		||||
    #[serde(rename = "w")]
 | 
			
		||||
    pub width: u64,
 | 
			
		||||
@ -55,3 +60,35 @@ pub struct ThumbnailInfo {
 | 
			
		||||
    #[serde(rename = "w")]
 | 
			
		||||
    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)]
 | 
			
		||||
pub struct NameEventContent {
 | 
			
		||||
    /// 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
 | 
			
		||||
    // 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,
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ mod tests {
 | 
			
		||||
            content: content.clone(),
 | 
			
		||||
            event_id: EventId::new("example.com").unwrap(),
 | 
			
		||||
            event_type: EventType::RoomPinnedEvents,
 | 
			
		||||
            origin_server_ts: 1432804485886,
 | 
			
		||||
            origin_server_ts: 1_432_804_485_886,
 | 
			
		||||
            prev_content: None,
 | 
			
		||||
            room_id: Some(RoomId::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.
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    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 {
 | 
			
		||||
 | 
			
		||||
@ -338,7 +338,7 @@ mod tests {
 | 
			
		||||
                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!(false);
 | 
			
		||||
                unreachable!();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -362,14 +362,14 @@ mod tests {
 | 
			
		||||
                assert_eq!(image_info.width, 128);
 | 
			
		||||
                assert_eq!(image_info.mimetype, "image/jpeg");
 | 
			
		||||
                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.event_type, EventType::RoomAvatar);
 | 
			
		||||
                assert_eq!(event.state_key, "");
 | 
			
		||||
                assert_eq!(event.sender.to_string(), "@example:localhost");
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                assert!(false);
 | 
			
		||||
                unreachable!();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -21,5 +21,5 @@ pub struct TagEventContent {
 | 
			
		||||
pub struct TagInfo {
 | 
			
		||||
    /// Value to use for lexicographically ordering rooms with this tag.
 | 
			
		||||
    #[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.
 | 
			
		||||
    pub struct TypingEvent(TypingEventContent) {
 | 
			
		||||
        /// The unique identifier for the room associated with this event.
 | 
			
		||||
        ///
 | 
			
		||||
        /// 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>
 | 
			
		||||
        pub room_id: RoomId
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user