Add new macros for implementing event traits. Fix Serialize impl for
NameEventContent. Convert m.room.power_levels to the new API.
This commit is contained in:
parent
03099b9a8b
commit
090a91f78b
@ -23,3 +23,77 @@ macro_rules! impl_enum {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_event {
|
||||
($name:ident, $content_name:ident, $event_type:path) => {
|
||||
impl Event for $name {
|
||||
/// The type of this event's `content` field.
|
||||
type Content = $content_name;
|
||||
|
||||
/// The event's content.
|
||||
fn content(&self) -> &Self::Content {
|
||||
&self.content
|
||||
}
|
||||
|
||||
/// The type of the event.
|
||||
fn event_type(&self) -> EventType {
|
||||
$event_type
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_room_event {
|
||||
($name:ident, $content_name:ident, $event_type:path) => {
|
||||
impl_event!($name, $content_name, $event_type);
|
||||
|
||||
impl RoomEvent for $name {
|
||||
/// The unique identifier for the event.
|
||||
fn event_id(&self) -> &EventId {
|
||||
&self.event_id
|
||||
}
|
||||
|
||||
/// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this event was
|
||||
/// sent.
|
||||
fn origin_server_ts(&self) -> UInt {
|
||||
self.origin_server_ts
|
||||
}
|
||||
|
||||
/// 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.
|
||||
fn room_id(&self) -> Option<&RoomId> {
|
||||
self.room_id.as_ref()
|
||||
}
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
fn sender(&self) -> &UserId {
|
||||
&self.sender
|
||||
}
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
fn unsigned(&self) -> Option<&Value> {
|
||||
self.unsigned.as_ref()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_state_event {
|
||||
($name:ident, $content_name:ident, $event_type:path) => {
|
||||
impl_room_event!($name, $content_name, $event_type);
|
||||
|
||||
impl StateEvent for $name {
|
||||
/// The previous content for this state key, if any.
|
||||
fn prev_content(&self) -> Option<&Self::Content> {
|
||||
self.prev_content.as_ref()
|
||||
}
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
fn state_key(&self) -> &str {
|
||||
&self.state_key
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub struct NameEvent {
|
||||
pub state_key: String,
|
||||
}
|
||||
|
||||
/// The payload of a `NameEvent`.
|
||||
/// The payload for `NameEvent`.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
pub struct NameEventContent {
|
||||
/// The name of the room. This MUST NOT exceed 255 bytes.
|
||||
@ -91,72 +91,47 @@ impl Serialize for NameEvent {
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_struct("NameEvent", 2)?;
|
||||
let mut len = 6;
|
||||
|
||||
if self.prev_content.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
if self.room_id.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
if self.unsigned.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
let mut state = serializer.serialize_struct("NameEvent", len)?;
|
||||
|
||||
state.serialize_field("content", &self.content)?;
|
||||
state.serialize_field("event_id", &self.event_id)?;
|
||||
state.serialize_field("origin_server_ts", &self.origin_server_ts)?;
|
||||
|
||||
if self.prev_content.is_some() {
|
||||
state.serialize_field("prev_content", &self.prev_content)?;
|
||||
}
|
||||
|
||||
if self.room_id.is_some() {
|
||||
state.serialize_field("room_id", &self.room_id)?;
|
||||
}
|
||||
|
||||
if self.unsigned.is_some() {
|
||||
state.serialize_field("unsigned", &self.unsigned)?;
|
||||
}
|
||||
|
||||
state.serialize_field("sender", &self.sender)?;
|
||||
state.serialize_field("state_key", &self.state_key)?;
|
||||
state.serialize_field("type", &self.event_type())?;
|
||||
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl Event for NameEvent {
|
||||
/// The type of this event's `content` field.
|
||||
type Content = NameEventContent;
|
||||
|
||||
/// The event's content.
|
||||
fn content(&self) -> &Self::Content {
|
||||
&self.content
|
||||
}
|
||||
|
||||
/// The type of the event.
|
||||
fn event_type(&self) -> EventType {
|
||||
EventType::RoomName
|
||||
}
|
||||
}
|
||||
|
||||
impl RoomEvent for NameEvent {
|
||||
/// The unique identifier for the event.
|
||||
fn event_id(&self) -> &EventId {
|
||||
&self.event_id
|
||||
}
|
||||
|
||||
/// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this event was
|
||||
/// sent.
|
||||
fn origin_server_ts(&self) -> UInt {
|
||||
self.origin_server_ts
|
||||
}
|
||||
|
||||
/// 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.
|
||||
fn room_id(&self) -> Option<&RoomId> {
|
||||
self.room_id.as_ref()
|
||||
}
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
fn sender(&self) -> &UserId {
|
||||
&self.sender
|
||||
}
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
fn unsigned(&self) -> Option<&Value> {
|
||||
self.unsigned.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl StateEvent for NameEvent {
|
||||
/// The previous content for this state key, if any.
|
||||
fn prev_content(&self) -> Option<&Self::Content> {
|
||||
self.prev_content.as_ref()
|
||||
}
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
fn state_key(&self) -> &str {
|
||||
&self.state_key
|
||||
}
|
||||
}
|
||||
impl_state_event!(NameEvent, NameEventContent, EventType::RoomName);
|
||||
|
||||
impl NameEventContent {
|
||||
/// Create a new `NameEventContent` with the given name.
|
||||
|
@ -1,20 +1,48 @@
|
||||
//! Types for the *m.room.power_levels* event.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, convert::TryFrom, str::FromStr};
|
||||
|
||||
use js_int::{Int, UInt};
|
||||
use ruma_identifiers::UserId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use js_int::UInt;
|
||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::EventType;
|
||||
use crate::{
|
||||
Event, EventType, InvalidEvent, InvalidInput, RoomEvent, StateEvent,
|
||||
};
|
||||
|
||||
state_event! {
|
||||
/// Defines the power levels (privileges) of users in the room.
|
||||
pub struct PowerLevelsEvent(PowerLevelsEventContent) {}
|
||||
|
||||
/// Defines the power levels (privileges) of users in the room.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PowerLevelsEvent {
|
||||
/// The event's content.
|
||||
pub content: PowerLevelsEventContent,
|
||||
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
||||
/// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this
|
||||
/// event was sent.
|
||||
pub origin_server_ts: UInt,
|
||||
|
||||
/// The previous content for this state key, if any.
|
||||
pub prev_content: Option<NameEventContent>,
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: Option<RoomId>,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
pub unsigned: Option<Value>,
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
pub sender: UserId,
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
pub state_key: String,
|
||||
}
|
||||
|
||||
/// The payload of a `PowerLevelsEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
/// The payload for `PowerLevelsEvent`.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
pub struct PowerLevelsEventContent {
|
||||
/// The level required to ban a user.
|
||||
#[serde(default = "default_power_level")]
|
||||
@ -60,6 +88,186 @@ pub struct PowerLevelsEventContent {
|
||||
pub notifications: NotificationPowerLevels,
|
||||
}
|
||||
|
||||
impl FromStr for PowerLevelsEvent {
|
||||
type Err = crate::InvalidEvent;
|
||||
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
fn from_str(json: &str) -> Result<Self, Self::Err> {
|
||||
let raw = serde_json::from_str::<raw::PowerLevelsEvent>(json)?;
|
||||
|
||||
Ok(Self {
|
||||
content: PowerLevelsEventContent {
|
||||
ban: raw.content.ban,
|
||||
events: raw.content.events,
|
||||
events_default: raw.content.events_default,
|
||||
invite: raw.content.invite,
|
||||
kick: raw.content.kick,
|
||||
redact: raw.content.redact,
|
||||
state_default: raw.content.state_default,
|
||||
users: raw.content.users,
|
||||
users_default: raw.content.users_default,
|
||||
notifications: raw.content.notifications,
|
||||
},
|
||||
event_id: raw.event_id,
|
||||
origin_server_ts: raw.origin_server_ts,
|
||||
prev_content: raw
|
||||
.prev_content
|
||||
.map(|prev| PowerLevelsEventContent {
|
||||
ban: prev.ban,
|
||||
events: prev.events,
|
||||
events_default: prev.events_default,
|
||||
invite: prev.invite,
|
||||
kick: prev.kick,
|
||||
redact: prev.redact,
|
||||
state_default: prev.state_default,
|
||||
users: prev.users,
|
||||
users_default: prev.users_default,
|
||||
notifications: prev.notifications,
|
||||
}),
|
||||
room_id: raw.room_id,
|
||||
unsigned: raw.unsigned,
|
||||
sender: raw.sender,
|
||||
state_key: raw.state_key,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for PowerLevelsEvent {
|
||||
type Error = InvalidEvent;
|
||||
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
fn try_from(json: &'a str) -> Result<Self, Self::Error> {
|
||||
FromStr::from_str(json)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for NameEvent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut len = 6;
|
||||
|
||||
if self.prev_content.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
if self.room_id.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
if self.unsigned.is_some() {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
let mut state = serializer.serialize_struct("PowerLevelsEvent", len)?;
|
||||
|
||||
state.serialize_field("content", &self.content)?;
|
||||
state.serialize_field("event_id", &self.event_id)?;
|
||||
state.serialize_field("origin_server_ts", &self.origin_server_ts)?;
|
||||
|
||||
if self.prev_content.is_some() {
|
||||
state.serialize_field("prev_content", &self.prev_content)?;
|
||||
}
|
||||
|
||||
if self.room_id.is_some() {
|
||||
state.serialize_field("room_id", &self.room_id)?;
|
||||
}
|
||||
|
||||
if self.unsigned.is_some() {
|
||||
state.serialize_field("unsigned", &self.unsigned)?;
|
||||
}
|
||||
|
||||
state.serialize_field("sender", &self.sender)?;
|
||||
state.serialize_field("state_key", &self.state_key)?;
|
||||
state.serialize_field("type", &self.event_type())?;
|
||||
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl_state_event!(PowerLevelsEvent, PowerLevelsEventContent, EventType::RoomPowerLevels);
|
||||
|
||||
mod raw {
|
||||
use super::*;
|
||||
|
||||
/// Defines the power levels (privileges) of users in the room.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
pub struct PowerLevelsEvent {
|
||||
/// The event's content.
|
||||
pub content: PowerLevelsEventContent,
|
||||
|
||||
/// The unique identifier for the event.
|
||||
pub event_id: EventId,
|
||||
|
||||
/// Timestamp (milliseconds since the UNIX epoch) on originating homeserver when this
|
||||
/// event was sent.
|
||||
pub origin_server_ts: UInt,
|
||||
|
||||
/// The previous content for this state key, if any.
|
||||
pub prev_content: Option<NameEventContent>,
|
||||
|
||||
/// The unique identifier for the room associated with this event.
|
||||
pub room_id: Option<RoomId>,
|
||||
|
||||
/// Additional key-value pairs not signed by the homeserver.
|
||||
pub unsigned: Option<Value>,
|
||||
|
||||
/// The unique identifier for the user who sent this event.
|
||||
pub sender: UserId,
|
||||
|
||||
/// A key that determines which piece of room state the event represents.
|
||||
pub state_key: String,
|
||||
}
|
||||
|
||||
/// The payload for `PowerLevelsEvent`.
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||
pub struct PowerLevelsEventContent {
|
||||
/// The level required to ban a user.
|
||||
#[serde(default = "default_power_level")]
|
||||
pub ban: Int,
|
||||
|
||||
/// The level required to send specific event types.
|
||||
///
|
||||
/// This is a mapping from event type to power level required.
|
||||
pub events: HashMap<EventType, Int>,
|
||||
|
||||
/// The default level required to send message events.
|
||||
#[serde(default)]
|
||||
pub events_default: Int,
|
||||
|
||||
/// The level required to invite a user.
|
||||
#[serde(default = "default_power_level")]
|
||||
pub invite: Int,
|
||||
|
||||
/// The level required to kick a user.
|
||||
#[serde(default = "default_power_level")]
|
||||
pub kick: Int,
|
||||
|
||||
/// The level required to redact an event.
|
||||
#[serde(default = "default_power_level")]
|
||||
pub redact: Int,
|
||||
|
||||
/// The default level required to send state events.
|
||||
#[serde(default = "default_power_level")]
|
||||
pub state_default: Int,
|
||||
|
||||
/// The power levels for specific users.
|
||||
///
|
||||
/// This is a mapping from `user_id` to power level for that user.
|
||||
pub users: HashMap<UserId, Int>,
|
||||
|
||||
/// The default power level for every user in the room.
|
||||
#[serde(default)]
|
||||
pub users_default: Int,
|
||||
|
||||
/// 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, PartialEq, Serialize)]
|
||||
pub struct NotificationPowerLevels {
|
||||
|
Loading…
x
Reference in New Issue
Block a user