Convert m.tag and m.typing to the new API.
This commit is contained in:
parent
1f3e33c77d
commit
4be050b19a
@ -2,32 +2,32 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ruma_events_macros::ruma_event;
|
||||
use ruma_identifiers::{RoomId, UserId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
event! {
|
||||
ruma_event! {
|
||||
/// Informs the client about the rooms that are considered direct by a user.
|
||||
pub struct DirectEvent(DirectEventContent) {}
|
||||
DirectEvent {
|
||||
kind: Event,
|
||||
event_type: Direct,
|
||||
content_type_alias: {
|
||||
/// The payload for `DirectEvent`.
|
||||
///
|
||||
/// A mapping of `UserId`s to a list of `RoomId`s which are considered *direct* for that
|
||||
/// particular user.
|
||||
HashMap<UserId, Vec<RoomId>>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// The payload of a `DirectEvent`.
|
||||
///
|
||||
/// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered
|
||||
/// *direct* for that particular user.
|
||||
pub type DirectEventContent = HashMap<UserId, Vec<RoomId>>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ruma_identifiers::{RoomId, UserId};
|
||||
use serde_json::{from_str, to_string};
|
||||
use serde_json::to_string;
|
||||
|
||||
use crate::{
|
||||
collections,
|
||||
direct::{DirectEvent, DirectEventContent},
|
||||
EventType,
|
||||
};
|
||||
use super::{DirectEvent, DirectEventContent};
|
||||
|
||||
#[test]
|
||||
fn serialization() {
|
||||
@ -39,7 +39,6 @@ mod tests {
|
||||
|
||||
let event = DirectEvent {
|
||||
content,
|
||||
event_type: EventType::Direct,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
@ -70,33 +69,10 @@ mod tests {
|
||||
rooms[1].to_string()
|
||||
);
|
||||
|
||||
let event = from_str::<DirectEvent>(&json_data).unwrap();
|
||||
assert_eq!(event.event_type, EventType::Direct);
|
||||
|
||||
let event = DirectEvent::from_str(&json_data).unwrap();
|
||||
let direct_rooms = event.content.get(&alice).unwrap();
|
||||
|
||||
assert!(direct_rooms.contains(&rooms[0]));
|
||||
assert!(direct_rooms.contains(&rooms[1]));
|
||||
|
||||
match from_str::<collections::all::Event>(&json_data).unwrap() {
|
||||
collections::all::Event::Direct(event) => {
|
||||
assert_eq!(event.event_type, EventType::Direct);
|
||||
|
||||
let direct_rooms = event.content.get(&alice).unwrap();
|
||||
assert!(direct_rooms.contains(&rooms[0]));
|
||||
assert!(direct_rooms.contains(&rooms[1]));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match from_str::<collections::only::Event>(&json_data).unwrap() {
|
||||
collections::only::Event::Direct(event) => {
|
||||
assert_eq!(event.event_type, EventType::Direct);
|
||||
|
||||
let direct_rooms = event.content.get(&alice).unwrap();
|
||||
assert!(direct_rooms.contains(&rooms[0]));
|
||||
assert!(direct_rooms.contains(&rooms[1]));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
123
src/dummy.rs
123
src/dummy.rs
@ -1,84 +1,10 @@
|
||||
//! Types for the *m.dummy* event.
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::{Formatter, Result as FmtResult},
|
||||
};
|
||||
use ruma_events_macros::ruma_event;
|
||||
|
||||
use serde::{de::{Error, MapAccess, Visitor}, ser::{SerializeMap, SerializeStruct}, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::Event;
|
||||
|
||||
/// This event type is used to indicate new Olm sessions for end-to-end encryption.
|
||||
///
|
||||
/// Typically it is encrypted as an *m.room.encrypted* event, then sent as a to-device event.
|
||||
///
|
||||
/// The event does not have any content associated with it. The sending client is expected to
|
||||
/// send a key share request shortly after this message, causing the receiving client to process
|
||||
/// this *m.dummy* event as the most recent event and using the keyshare request to set up the
|
||||
/// session. The keyshare request and *m.dummy* combination should result in the original
|
||||
/// sending client receiving keys over the newly established session.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DummyEvent {
|
||||
/// The event's content.
|
||||
pub content: DummyEventContent,
|
||||
}
|
||||
|
||||
/// The payload for `DummyEvent`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DummyEventContent;
|
||||
|
||||
impl DummyEvent {
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
pub fn from_str(json: &str) -> Result<Self, crate::InvalidEvent> {
|
||||
serde_json::from_str::<raw::DummyEvent>(json)?;
|
||||
|
||||
Ok(Self {
|
||||
content: DummyEventContent,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DummyEvent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
{
|
||||
let mut state = serializer.serialize_struct("DummyEvent", 2)?;
|
||||
|
||||
state.serialize_field("content", &self.content);
|
||||
state.serialize_field("type", &self.event_type());
|
||||
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Event for DummyEvent {
|
||||
/// The type of the event.
|
||||
const EVENT_TYPE: crate::EventType = crate::EventType::Dummy;
|
||||
|
||||
/// The type of this event's `content` field.
|
||||
type Content = DummyEventContent;
|
||||
|
||||
/// The event's content.
|
||||
fn content(&self) -> &Self::Content {
|
||||
&self.content
|
||||
}
|
||||
}
|
||||
|
||||
// This is necessary because the content is represented in JSON as an empty object.
|
||||
impl Serialize for DummyEventContent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
{
|
||||
serializer.serialize_map(Some(0))?.end()
|
||||
}
|
||||
}
|
||||
|
||||
mod raw {
|
||||
use super::*;
|
||||
use crate::Empty;
|
||||
|
||||
ruma_event! {
|
||||
/// This event type is used to indicate new Olm sessions for end-to-end encryption.
|
||||
///
|
||||
/// Typically it is encrypted as an *m.room.encrypted* event, then sent as a to-device event.
|
||||
@ -88,51 +14,24 @@ mod raw {
|
||||
/// this *m.dummy* event as the most recent event and using the keyshare request to set up the
|
||||
/// session. The keyshare request and *m.dummy* combination should result in the original
|
||||
/// sending client receiving keys over the newly established session.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct DummyEvent {
|
||||
/// The event's content.
|
||||
pub content: DummyEventContent,
|
||||
}
|
||||
|
||||
/// The payload for `DummyEvent`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DummyEventContent;
|
||||
|
||||
impl<'de> Deserialize<'de> for DummyEventContent {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>
|
||||
{
|
||||
struct EmptyMapVisitor;
|
||||
|
||||
impl <'de> Visitor<'de> for EmptyMapVisitor {
|
||||
type Value = DummyEventContent;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> FmtResult {
|
||||
write!(f, "an object/map")
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>
|
||||
{
|
||||
Ok(DummyEventContent)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_map(EmptyMapVisitor)
|
||||
DummyEvent {
|
||||
kind: Event,
|
||||
event_type: Dummy,
|
||||
content_type_alias: {
|
||||
/// The payload for `DummyEvent`.
|
||||
Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{DummyEvent, DummyEventContent};
|
||||
use super::{DummyEvent, Empty};
|
||||
|
||||
#[test]
|
||||
fn serialization() {
|
||||
let dummy_event = DummyEvent {
|
||||
content: DummyEventContent,
|
||||
content: Empty,
|
||||
};
|
||||
|
||||
let actual = serde_json::to_string(&dummy_event).unwrap();
|
||||
|
@ -3,25 +3,100 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ruma_identifiers::UserId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
event! {
|
||||
/// A list of users to ignore.
|
||||
pub struct IgnoredUserListEvent(IgnoredUserListEventContent) {}
|
||||
use crate::{Empty, Event};
|
||||
|
||||
/// A list of users to ignore.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct IgnoredUserListEvent {
|
||||
/// The event's content.
|
||||
pub content: IgnoredUserListEventContent,
|
||||
}
|
||||
|
||||
/// The payload of an `IgnoredUserListEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
/// The payload for `IgnoredUserListEvent`.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct IgnoredUserListEventContent {
|
||||
/// A list of users to ignore.
|
||||
///
|
||||
/// The values in the hash map are not meaningful. They are used to generate an empty JSON
|
||||
/// object to support the odd structure used by the Matrix specification:
|
||||
///
|
||||
/// ```text
|
||||
/// "@someone:example.org": {}
|
||||
/// ```
|
||||
pub ignored_users: HashMap<UserId, HashMap<(), ()>>,
|
||||
pub ignored_users: Vec<UserId>,
|
||||
}
|
||||
|
||||
impl IgnoredUserListEvent {
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
pub fn from_str(json: &str) -> Result<Self, crate::InvalidEvent> {
|
||||
let raw = serde_json::from_str::<raw::IgnoredUserListEvent>(json)?;
|
||||
|
||||
Ok(Self {
|
||||
content: IgnoredUserListEventContent {
|
||||
ignored_users: raw.content.ignored_users.keys().cloned().collect(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for IgnoredUserListEvent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
{
|
||||
let mut state = serializer.serialize_struct("IgnoredUserListEvent", 2)?;
|
||||
|
||||
state.serialize_field("content", &self.content);
|
||||
state.serialize_field("type", &self.event_type());
|
||||
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Event for IgnoredUserListEvent {
|
||||
/// The type of the event.
|
||||
const EVENT_TYPE: crate::EventType = crate::EventType::IgnoredUserList;
|
||||
|
||||
/// The type of this event's `content` field.
|
||||
type Content = IgnoredUserListEventContent;
|
||||
|
||||
/// The event's content.
|
||||
fn content(&self) -> &Self::Content {
|
||||
&self.content
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for IgnoredUserListEventContent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
{
|
||||
let mut map = HashMap::new();
|
||||
|
||||
for user_id in &self.ignored_users {
|
||||
map.insert(user_id.clone(), Empty);
|
||||
}
|
||||
|
||||
let raw = raw::IgnoredUserListEventContent {
|
||||
ignored_users: map,
|
||||
};
|
||||
|
||||
raw.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
mod raw {
|
||||
use crate::Empty;
|
||||
use super::*;
|
||||
|
||||
/// A list of users to ignore.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct IgnoredUserListEvent {
|
||||
/// The event's content.
|
||||
pub content: IgnoredUserListEventContent,
|
||||
}
|
||||
|
||||
/// The payload for `IgnoredUserListEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct IgnoredUserListEventContent {
|
||||
/// A list of users to ignore.
|
||||
pub ignored_users: HashMap<UserId, Empty>,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -30,40 +105,33 @@ mod tests {
|
||||
|
||||
use ruma_identifiers::UserId;
|
||||
|
||||
use super::IgnoredUserListEventContent;
|
||||
use super::{IgnoredUserListEvent, IgnoredUserListEventContent};
|
||||
|
||||
#[test]
|
||||
fn serialize_to_empty_json_object() {
|
||||
let mut ignored_user_list_event_content = IgnoredUserListEventContent {
|
||||
ignored_users: HashMap::new(),
|
||||
fn serialization() {
|
||||
let ignored_user_list_event = IgnoredUserListEvent {
|
||||
content: IgnoredUserListEventContent {
|
||||
ignored_users: vec![UserId::try_from("@carl:example.com").unwrap()],
|
||||
},
|
||||
};
|
||||
|
||||
let user_id = UserId::try_from("@carl:example.com").unwrap();
|
||||
let json = serde_json::to_string(&ignored_user_list_event).unwrap();
|
||||
|
||||
ignored_user_list_event_content
|
||||
.ignored_users
|
||||
.insert(user_id, HashMap::new());
|
||||
|
||||
let json = serde_json::to_string(&ignored_user_list_event_content).unwrap();
|
||||
|
||||
assert_eq!(json, r#"{"ignored_users":{"@carl:example.com":{}}}"#);
|
||||
assert_eq!(json, r#"{"content":{"ignored_users":{"@carl:example.com":{}}},"type":"m.ignored_user_list"}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_from_empty_json_object() {
|
||||
let json = r#"{"ignored_users":{"@carl:example.com":{}}}"#;
|
||||
fn deserialization() {
|
||||
let json = r#"{"content":{"ignored_users":{"@carl:example.com":{}}},"type":"m.ignored_user_list"}"#;
|
||||
|
||||
let ignored_user_list_event_content: IgnoredUserListEventContent =
|
||||
serde_json::from_str(&json).unwrap();
|
||||
let actual = IgnoredUserListEvent::from_str(json).unwrap();
|
||||
|
||||
let mut expected = IgnoredUserListEventContent {
|
||||
ignored_users: HashMap::new(),
|
||||
let expected = IgnoredUserListEvent {
|
||||
content: IgnoredUserListEventContent {
|
||||
ignored_users: vec![UserId::try_from("@carl:example.com").unwrap()],
|
||||
},
|
||||
};
|
||||
|
||||
let user_id = UserId::try_from("@carl:example.com").unwrap();
|
||||
|
||||
expected.ignored_users.insert(user_id, HashMap::new());
|
||||
|
||||
assert_eq!(ignored_user_list_event_content, expected);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
|
55
src/lib.rs
55
src/lib.rs
@ -107,7 +107,8 @@ use std::{
|
||||
use js_int::UInt;
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::{
|
||||
de::{Error as SerdeError, IntoDeserializer, Visitor},
|
||||
de::{Error as SerdeError, IntoDeserializer, MapAccess, Visitor},
|
||||
ser::SerializeMap,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use serde_json::Value;
|
||||
@ -121,22 +122,22 @@ mod macros;
|
||||
// pub mod all;
|
||||
// pub mod only;
|
||||
// }
|
||||
// pub mod direct;
|
||||
pub mod direct;
|
||||
pub mod dummy;
|
||||
pub mod forwarded_room_key;
|
||||
// pub mod fully_read;
|
||||
// pub mod ignored_user_list;
|
||||
pub mod ignored_user_list;
|
||||
// pub mod key;
|
||||
pub mod presence;
|
||||
// pub mod push_rules;
|
||||
// pub mod receipt;
|
||||
pub mod receipt;
|
||||
pub mod room;
|
||||
// pub mod room_key;
|
||||
pub mod room_key_request;
|
||||
pub mod sticker;
|
||||
// pub mod stripped;
|
||||
// pub mod tag;
|
||||
// pub mod typing;
|
||||
pub mod tag;
|
||||
pub mod typing;
|
||||
|
||||
/// An event that is malformed or otherwise invalid.
|
||||
///
|
||||
@ -212,6 +213,48 @@ impl Display for FromStrError {
|
||||
|
||||
impl Error for FromStrError {}
|
||||
|
||||
/// A meaningless value that serializes to an empty JSON object.
|
||||
///
|
||||
/// This type is used in a few places where the Matrix specification requires an empty JSON object,
|
||||
/// but it's wasteful to represent it as a `HashMap` in Rust code.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Empty;
|
||||
|
||||
impl Serialize for Empty {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
{
|
||||
serializer.serialize_map(Some(0))?.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Empty {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>
|
||||
{
|
||||
struct EmptyMapVisitor;
|
||||
|
||||
impl <'de> Visitor<'de> for EmptyMapVisitor {
|
||||
type Value = Empty;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> FmtResult {
|
||||
write!(f, "an object/map")
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, _map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>
|
||||
{
|
||||
Ok(Empty)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_map(EmptyMapVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of an event.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum EventType {
|
||||
|
190
src/macros.rs
190
src/macros.rs
@ -23,193 +23,3 @@ macro_rules! impl_enum {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! event {
|
||||
( $(#[$attr:meta])*
|
||||
pub struct $name:ident($content_type:ty) {
|
||||
$(
|
||||
$(#[$field_attr:meta])*
|
||||
pub $field_name:ident: $field_type:ty
|
||||
),*
|
||||
}
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct $name {
|
||||
/// The event's content.
|
||||
pub content: $content_type,
|
||||
|
||||
/// The type of the event.
|
||||
#[serde(rename = "type")]
|
||||
pub event_type: $crate::EventType,
|
||||
|
||||
$(
|
||||
$(#[$field_attr])*
|
||||
pub $field_name: $field_type
|
||||
),*
|
||||
}
|
||||
|
||||
impl_event!($name, $content_type);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_event {
|
||||
($name:ident, $content_type:ty) => {
|
||||
impl $crate::Event for $name {
|
||||
type Content = $content_type;
|
||||
|
||||
fn content(&self) -> &<$name as $crate::Event>::Content {
|
||||
&self.content
|
||||
}
|
||||
|
||||
fn event_type(&self) -> &$crate::EventType {
|
||||
&self.event_type
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! room_event {
|
||||
( $(#[$attr:meta])*
|
||||
pub struct $name:ident($content_type:ty) {
|
||||
$(
|
||||
$(#[$field_attr:meta])*
|
||||
pub $field_name:ident: $field_type:ty
|
||||
),*
|
||||
}
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct $name {
|
||||
/// The event's content.
|
||||
pub content: $content_type,
|
||||
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: ::ruma_identifiers::EventId,
|
||||
|
||||
/// The type of the event.
|
||||
#[serde(rename = "type")]
|
||||
pub event_type: $crate::EventType,
|
||||
|
||||
/// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this
|
||||
/// event was sent.
|
||||
pub origin_server_ts: UInt,
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
#[serde(skip_serializing_if="Option::is_none")]
|
||||
pub room_id: Option<::ruma_identifiers::RoomId>,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub unsigned: Option<::serde_json::Value>,
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
pub sender: ::ruma_identifiers::UserId,
|
||||
|
||||
$(
|
||||
$(#[$field_attr])*
|
||||
pub $field_name: $field_type
|
||||
),*
|
||||
}
|
||||
|
||||
impl_room_event!($name, $content_type);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_room_event {
|
||||
($name:ident, $content_type:ty) => {
|
||||
impl_event!($name, $content_type);
|
||||
|
||||
impl $crate::RoomEvent for $name {
|
||||
fn event_id(&self) -> &::ruma_identifiers::EventId {
|
||||
&self.event_id
|
||||
}
|
||||
|
||||
fn origin_server_ts(&self) -> UInt {
|
||||
self.origin_server_ts
|
||||
}
|
||||
|
||||
fn room_id(&self) -> Option<&::ruma_identifiers::RoomId> {
|
||||
self.room_id.as_ref()
|
||||
}
|
||||
|
||||
fn unsigned(&self) -> Option<&::serde_json::Value> {
|
||||
self.unsigned.as_ref()
|
||||
}
|
||||
|
||||
fn sender(&self) -> &::ruma_identifiers::UserId {
|
||||
&self.sender
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! state_event {
|
||||
( $(#[$attr:meta])*
|
||||
pub struct $name:ident($content_type:ty) {
|
||||
$(
|
||||
$(#[$field_attr:meta])*
|
||||
pub $field_name:ident: $field_type:ty
|
||||
),*
|
||||
}
|
||||
) => {
|
||||
$(#[$attr])*
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct $name {
|
||||
/// The event's content.
|
||||
pub content: $content_type,
|
||||
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: ::ruma_identifiers::EventId,
|
||||
|
||||
/// The type of the event.
|
||||
#[serde(rename = "type")]
|
||||
pub event_type: $crate::EventType,
|
||||
|
||||
/// Timestamp in milliseconds on originating homeserver when this event was sent.
|
||||
pub origin_server_ts: UInt,
|
||||
|
||||
/// The previous content for this state key, if any.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prev_content: Option<$content_type>,
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
#[serde(skip_serializing_if="Option::is_none")]
|
||||
pub room_id: Option<::ruma_identifiers::RoomId>,
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
pub state_key: String,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub unsigned: Option<::serde_json::Value>,
|
||||
|
||||
/// The unique identifier for the user associated with this event.
|
||||
pub sender: ::ruma_identifiers::UserId,
|
||||
|
||||
$(
|
||||
$(#[$field_attr])*
|
||||
pub $field_name: $field_type
|
||||
),*
|
||||
}
|
||||
|
||||
impl_state_event!($name, $content_type);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_state_event {
|
||||
($name:ident, $content_type:ty) => {
|
||||
impl_room_event!($name, $content_type);
|
||||
|
||||
impl $crate::StateEvent for $name {
|
||||
fn prev_content(&self) -> Option<&Self::Content> {
|
||||
self.prev_content.as_ref()
|
||||
}
|
||||
|
||||
fn state_key(&self) -> &str {
|
||||
&self.state_key
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -77,10 +77,9 @@ mod tests {
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_identifiers::UserId;
|
||||
use serde_json::{from_str, to_string};
|
||||
use serde_json::to_string;
|
||||
|
||||
use super::{PresenceEvent, PresenceEventContent, PresenceState};
|
||||
use crate::EventType;
|
||||
|
||||
/// Test serialization and deserialization of example m.presence event from the spec
|
||||
/// https://github.com/turt2live/matrix-doc/blob/master/event-schemas/examples/m.presence
|
||||
|
@ -3,23 +3,29 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_events_macros::ruma_event;
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
event! {
|
||||
ruma_event! {
|
||||
/// Informs the client of new receipts.
|
||||
pub struct ReceiptEvent(ReceiptEventContent) {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: RoomId
|
||||
ReceiptEvent {
|
||||
kind: Event,
|
||||
event_type: Receipt,
|
||||
fields: {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: RoomId,
|
||||
},
|
||||
content_type_alias: {
|
||||
/// The payload for `ReceiptEvent`.
|
||||
///
|
||||
/// A mapping of event ID to a collection of receipts for this event ID. The event ID is the ID of
|
||||
/// the event being acknowledged and *not* an ID for the receipt itself.
|
||||
HashMap<EventId, Receipts>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// The payload of a `ReceiptEvent`.
|
||||
///
|
||||
/// A mapping of event ID to a collection of receipts for this event ID. The event ID is the ID of
|
||||
/// the event being acknowledged and *not* an ID for the receipt itself.
|
||||
pub type ReceiptEventContent = HashMap<EventId, Receipts>;
|
||||
|
||||
/// A collection of receipts.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct Receipts {
|
||||
|
19
src/tag.rs
19
src/tag.rs
@ -2,18 +2,19 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ruma_events_macros::ruma_event;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
event! {
|
||||
ruma_event! {
|
||||
/// Informs the client of tags on a room.
|
||||
pub struct TagEvent(TagEventContent) {}
|
||||
}
|
||||
|
||||
/// The payload of a `TagEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct TagEventContent {
|
||||
/// A map of tag names to tag info.
|
||||
pub tags: HashMap<String, TagInfo>,
|
||||
TagEvent {
|
||||
kind: Event,
|
||||
event_type: Tag,
|
||||
content: {
|
||||
/// A map of tag names to tag info.
|
||||
pub tags: HashMap<String, TagInfo>,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about a tag.
|
||||
|
@ -1,19 +1,20 @@
|
||||
//! Types for the *m.typing* event.
|
||||
|
||||
use ruma_events_macros::ruma_event;
|
||||
use ruma_identifiers::{RoomId, UserId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
event! {
|
||||
ruma_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.
|
||||
pub room_id: RoomId
|
||||
TypingEvent {
|
||||
kind: Event,
|
||||
event_type: Typing,
|
||||
fields: {
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: RoomId,
|
||||
},
|
||||
content: {
|
||||
/// The list of user IDs typing in this room, if any.
|
||||
pub user_ids: Vec<UserId>,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// The payload of a `TypingEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
pub struct TypingEventContent {
|
||||
/// The list of user IDs typing in this room, if any.
|
||||
pub user_ids: Vec<UserId>,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user