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,
|
pub state_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The payload of a `NameEvent`.
|
/// The payload for `NameEvent`.
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||||
pub struct NameEventContent {
|
pub struct NameEventContent {
|
||||||
/// The name of the room. This MUST NOT exceed 255 bytes.
|
/// The name of the room. This MUST NOT exceed 255 bytes.
|
||||||
@ -91,72 +91,47 @@ impl Serialize for NameEvent {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
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("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.serialize_field("type", &self.event_type())?;
|
||||||
|
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event for NameEvent {
|
impl_state_event!(NameEvent, NameEventContent, EventType::RoomName);
|
||||||
/// 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 NameEventContent {
|
impl NameEventContent {
|
||||||
/// Create a new `NameEventContent` with the given name.
|
/// Create a new `NameEventContent` with the given name.
|
||||||
|
@ -1,20 +1,48 @@
|
|||||||
//! Types for the *m.room.power_levels* event.
|
//! 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 js_int::UInt;
|
||||||
use ruma_identifiers::UserId;
|
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
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.
|
/// Defines the power levels (privileges) of users in the room.
|
||||||
pub struct PowerLevelsEvent(PowerLevelsEventContent) {}
|
#[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`.
|
/// The payload for `PowerLevelsEvent`.
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||||
pub struct PowerLevelsEventContent {
|
pub struct PowerLevelsEventContent {
|
||||||
/// The level required to ban a user.
|
/// The level required to ban a user.
|
||||||
#[serde(default = "default_power_level")]
|
#[serde(default = "default_power_level")]
|
||||||
@ -60,6 +88,186 @@ pub struct PowerLevelsEventContent {
|
|||||||
pub notifications: NotificationPowerLevels,
|
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.
|
/// The power level requirements for specific notification types.
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct NotificationPowerLevels {
|
pub struct NotificationPowerLevels {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user