221 lines
5.8 KiB
Rust
221 lines
5.8 KiB
Rust
use std::collections::BTreeMap;
|
|
|
|
use js_int::Int;
|
|
use ruma_common::{
|
|
power_levels::{default_power_level, NotificationPowerLevels},
|
|
serde::{btreemap_deserialize_v1_powerlevel_values, deserialize_v1_powerlevel},
|
|
OwnedUserId,
|
|
};
|
|
use ruma_events::{room::power_levels::RoomPowerLevelsEventContent, TimelineEventType};
|
|
use serde::Deserialize;
|
|
use serde_json::{from_str as from_json_str, Error};
|
|
use tracing::error;
|
|
|
|
use crate::RoomVersion;
|
|
|
|
#[derive(Deserialize)]
|
|
struct IntRoomPowerLevelsEventContent {
|
|
#[serde(default = "default_power_level")]
|
|
ban: Int,
|
|
|
|
#[serde(default)]
|
|
events: BTreeMap<TimelineEventType, Int>,
|
|
|
|
#[serde(default)]
|
|
events_default: Int,
|
|
|
|
#[serde(default)]
|
|
invite: Int,
|
|
|
|
#[serde(default = "default_power_level")]
|
|
kick: Int,
|
|
|
|
#[serde(default = "default_power_level")]
|
|
redact: Int,
|
|
|
|
#[serde(default = "default_power_level")]
|
|
state_default: Int,
|
|
|
|
#[serde(default)]
|
|
users: BTreeMap<OwnedUserId, Int>,
|
|
|
|
#[serde(default)]
|
|
users_default: Int,
|
|
|
|
#[serde(default)]
|
|
notifications: IntNotificationPowerLevels,
|
|
}
|
|
|
|
impl From<IntRoomPowerLevelsEventContent> for RoomPowerLevelsEventContent {
|
|
fn from(int_pl: IntRoomPowerLevelsEventContent) -> Self {
|
|
let IntRoomPowerLevelsEventContent {
|
|
ban,
|
|
events,
|
|
events_default,
|
|
invite,
|
|
kick,
|
|
redact,
|
|
state_default,
|
|
users,
|
|
users_default,
|
|
notifications,
|
|
} = int_pl;
|
|
|
|
let mut pl = Self::new();
|
|
pl.ban = ban;
|
|
pl.events = events;
|
|
pl.events_default = events_default;
|
|
pl.invite = invite;
|
|
pl.kick = kick;
|
|
pl.redact = redact;
|
|
pl.state_default = state_default;
|
|
pl.users = users;
|
|
pl.users_default = users_default;
|
|
pl.notifications = notifications.into();
|
|
|
|
pl
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct IntNotificationPowerLevels {
|
|
#[serde(default = "default_power_level")]
|
|
room: Int,
|
|
}
|
|
|
|
impl Default for IntNotificationPowerLevels {
|
|
fn default() -> Self {
|
|
Self { room: default_power_level() }
|
|
}
|
|
}
|
|
|
|
impl From<IntNotificationPowerLevels> for NotificationPowerLevels {
|
|
fn from(int_notif: IntNotificationPowerLevels) -> Self {
|
|
let mut notif = Self::new();
|
|
notif.room = int_notif.room;
|
|
|
|
notif
|
|
}
|
|
}
|
|
|
|
pub(crate) fn deserialize_power_levels(
|
|
content: &str,
|
|
room_version: &RoomVersion,
|
|
) -> Option<RoomPowerLevelsEventContent> {
|
|
if room_version.integer_power_levels {
|
|
match from_json_str::<IntRoomPowerLevelsEventContent>(content) {
|
|
Ok(content) => Some(content.into()),
|
|
Err(_) => {
|
|
error!("m.room.power_levels event is not valid with integer values");
|
|
None
|
|
}
|
|
}
|
|
} else {
|
|
match from_json_str(content) {
|
|
Ok(content) => Some(content),
|
|
Err(_) => {
|
|
error!(
|
|
"m.room.power_levels event is not valid with integer or string integer values"
|
|
);
|
|
None
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct PowerLevelsContentFields {
|
|
#[serde(default, deserialize_with = "btreemap_deserialize_v1_powerlevel_values")]
|
|
pub(crate) users: BTreeMap<OwnedUserId, Int>,
|
|
|
|
#[serde(default, deserialize_with = "deserialize_v1_powerlevel")]
|
|
pub(crate) users_default: Int,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct IntPowerLevelsContentFields {
|
|
#[serde(default)]
|
|
users: BTreeMap<OwnedUserId, Int>,
|
|
|
|
#[serde(default)]
|
|
users_default: Int,
|
|
}
|
|
|
|
impl From<IntPowerLevelsContentFields> for PowerLevelsContentFields {
|
|
fn from(pl: IntPowerLevelsContentFields) -> Self {
|
|
let IntPowerLevelsContentFields { users, users_default } = pl;
|
|
Self { users, users_default }
|
|
}
|
|
}
|
|
|
|
pub(crate) fn deserialize_power_levels_content_fields(
|
|
content: &str,
|
|
room_version: &RoomVersion,
|
|
) -> Result<PowerLevelsContentFields, Error> {
|
|
if room_version.integer_power_levels {
|
|
from_json_str::<IntPowerLevelsContentFields>(content).map(|r| r.into())
|
|
} else {
|
|
from_json_str(content)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct PowerLevelsContentInvite {
|
|
#[serde(default, deserialize_with = "deserialize_v1_powerlevel")]
|
|
pub(crate) invite: Int,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct IntPowerLevelsContentInvite {
|
|
#[serde(default)]
|
|
invite: Int,
|
|
}
|
|
|
|
impl From<IntPowerLevelsContentInvite> for PowerLevelsContentInvite {
|
|
fn from(pl: IntPowerLevelsContentInvite) -> Self {
|
|
let IntPowerLevelsContentInvite { invite } = pl;
|
|
Self { invite }
|
|
}
|
|
}
|
|
|
|
pub(crate) fn deserialize_power_levels_content_invite(
|
|
content: &str,
|
|
room_version: &RoomVersion,
|
|
) -> Result<PowerLevelsContentInvite, Error> {
|
|
if room_version.integer_power_levels {
|
|
from_json_str::<IntPowerLevelsContentInvite>(content).map(|r| r.into())
|
|
} else {
|
|
from_json_str(content)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct PowerLevelsContentRedact {
|
|
#[serde(default = "default_power_level", deserialize_with = "deserialize_v1_powerlevel")]
|
|
pub(crate) redact: Int,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct IntPowerLevelsContentRedact {
|
|
#[serde(default = "default_power_level")]
|
|
redact: Int,
|
|
}
|
|
|
|
impl From<IntPowerLevelsContentRedact> for PowerLevelsContentRedact {
|
|
fn from(pl: IntPowerLevelsContentRedact) -> Self {
|
|
let IntPowerLevelsContentRedact { redact } = pl;
|
|
Self { redact }
|
|
}
|
|
}
|
|
|
|
pub(crate) fn deserialize_power_levels_content_redact(
|
|
content: &str,
|
|
room_version: &RoomVersion,
|
|
) -> Result<PowerLevelsContentRedact, Error> {
|
|
if room_version.integer_power_levels {
|
|
from_json_str::<IntPowerLevelsContentRedact>(content).map(|r| r.into())
|
|
} else {
|
|
from_json_str(content)
|
|
}
|
|
}
|