Improve Synapse compatibility w.r.t. power levels
This commit is contained in:
parent
bdf4a86770
commit
8348b97091
@ -13,7 +13,10 @@ pub struct NotificationPowerLevels {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level")]
|
#[serde(default = "default_power_level")]
|
||||||
pub room: Int,
|
pub room: Int,
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub ban: Int,
|
pub ban: Int,
|
||||||
@ -38,7 +41,7 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "compat",
|
feature = "compat",
|
||||||
serde(deserialize_with = "ruma_serde::btreemap_int_or_string_to_int_values")
|
serde(deserialize_with = "ruma_serde::btreemap_deserialize_v1_powerlevel_values")
|
||||||
)]
|
)]
|
||||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
@ -48,7 +51,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub events_default: Int,
|
pub events_default: Int,
|
||||||
@ -57,7 +63,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
||||||
pub invite: Int,
|
pub invite: Int,
|
||||||
|
|
||||||
@ -65,7 +74,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub kick: Int,
|
pub kick: Int,
|
||||||
@ -74,7 +86,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub redact: Int,
|
pub redact: Int,
|
||||||
@ -83,7 +98,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
#[serde(default = "default_power_level", skip_serializing_if = "is_default_power_level")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub state_default: Int,
|
pub state_default: Int,
|
||||||
@ -96,7 +114,7 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "compat",
|
feature = "compat",
|
||||||
serde(deserialize_with = "ruma_serde::btreemap_int_or_string_to_int_values")
|
serde(deserialize_with = "ruma_serde::btreemap_deserialize_v1_powerlevel_values")
|
||||||
)]
|
)]
|
||||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
@ -106,7 +124,10 @@ pub struct RoomPowerLevelsEventContent {
|
|||||||
///
|
///
|
||||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||||
/// integers too.
|
/// integers too.
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
||||||
#[ruma_event(skip_redaction)]
|
#[ruma_event(skip_redaction)]
|
||||||
pub users_default: Int,
|
pub users_default: Int,
|
||||||
|
@ -33,7 +33,7 @@ pub use self::{
|
|||||||
empty::vec_as_map_of_empty,
|
empty::vec_as_map_of_empty,
|
||||||
raw::Raw,
|
raw::Raw,
|
||||||
strings::{
|
strings::{
|
||||||
btreemap_int_or_string_to_int_values, empty_string_as_none, int_or_string_to_int,
|
btreemap_deserialize_v1_powerlevel_values, deserialize_v1_powerlevel, empty_string_as_none,
|
||||||
none_as_empty_string,
|
none_as_empty_string,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{collections::BTreeMap, convert::TryInto, fmt, marker::PhantomData};
|
use std::{collections::BTreeMap, convert::TryInto, fmt, marker::PhantomData};
|
||||||
|
|
||||||
use js_int::Int;
|
use js_int::{Int, UInt};
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{self, Deserializer, IntoDeserializer as _, MapAccess, Visitor},
|
de::{self, Deserializer, IntoDeserializer as _, MapAccess, Visitor},
|
||||||
ser::Serializer,
|
ser::Serializer,
|
||||||
@ -52,8 +52,8 @@ where
|
|||||||
/// Take either an integer number or a string and deserialize to an integer number.
|
/// Take either an integer number or a string and deserialize to an integer number.
|
||||||
///
|
///
|
||||||
/// To be used like this:
|
/// To be used like this:
|
||||||
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
|
/// `#[serde(deserialize_with = "deserialize_v1_powerlevel")]`
|
||||||
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
|
pub fn deserialize_v1_powerlevel<'de, D>(de: D) -> Result<Int, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@ -107,7 +107,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||||
v.parse().map_err(E::custom)
|
let trimmed = v.trim();
|
||||||
|
|
||||||
|
match trimmed.strip_prefix('+') {
|
||||||
|
Some(without) => without.parse::<UInt>().map(|u| u.into()).map_err(E::custom),
|
||||||
|
None => trimmed.parse().map_err(E::custom),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +123,10 @@ where
|
|||||||
/// those to integer numbers.
|
/// those to integer numbers.
|
||||||
///
|
///
|
||||||
/// To be used like this:
|
/// To be used like this:
|
||||||
/// `#[serde(deserialize_with = "btreemap_int_or_string_to_int_values")]`
|
/// `#[serde(deserialize_with = "btreemap_deserialize_v1_powerlevel_values")]`
|
||||||
pub fn btreemap_int_or_string_to_int_values<'de, D, T>(de: D) -> Result<BTreeMap<T, Int>, D::Error>
|
pub fn btreemap_deserialize_v1_powerlevel_values<'de, D, T>(
|
||||||
|
de: D,
|
||||||
|
) -> Result<BTreeMap<T, Int>, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
T: Deserialize<'de> + Ord,
|
T: Deserialize<'de> + Ord,
|
||||||
@ -132,7 +139,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
int_or_string_to_int(deserializer).map(IntWrap)
|
deserialize_v1_powerlevel(deserializer).map(IntWrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,16 +183,16 @@ mod tests {
|
|||||||
use matches::assert_matches;
|
use matches::assert_matches;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::int_or_string_to_int;
|
use super::deserialize_v1_powerlevel;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Test {
|
||||||
|
#[serde(deserialize_with = "deserialize_v1_powerlevel")]
|
||||||
|
num: Int,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn int_or_string() -> serde_json::Result<()> {
|
fn int_or_string() -> serde_json::Result<()> {
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct Test {
|
|
||||||
#[serde(deserialize_with = "int_or_string_to_int")]
|
|
||||||
num: Int,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
serde_json::from_value::<Test>(serde_json::json!({ "num": "0" }))?,
|
serde_json::from_value::<Test>(serde_json::json!({ "num": "0" }))?,
|
||||||
Test { num } if num == int!(0)
|
Test { num } if num == int!(0)
|
||||||
@ -193,4 +200,24 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn weird_plus_string() -> serde_json::Result<()> {
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<Test>(serde_json::json!({ "num": " +0000000001000 " }))?,
|
||||||
|
Test { num } if num == int!(1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn weird_minus_string() -> serde_json::Result<()> {
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<Test>(serde_json::json!({ "num": " \n\n-0000000000000001000 " }))?,
|
||||||
|
Test { num } if num == int!(-1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,12 +339,15 @@ where
|
|||||||
struct PowerLevelsContentFields {
|
struct PowerLevelsContentFields {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "compat",
|
feature = "compat",
|
||||||
serde(deserialize_with = "ruma_serde::btreemap_int_or_string_to_int_values")
|
serde(deserialize_with = "ruma_serde::btreemap_deserialize_v1_powerlevel_values")
|
||||||
)]
|
)]
|
||||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
users: BTreeMap<Box<UserId>, Int>,
|
users: BTreeMap<Box<UserId>, Int>,
|
||||||
|
|
||||||
#[cfg_attr(feature = "compat", serde(deserialize_with = "ruma_serde::int_or_string_to_int"))]
|
#[cfg_attr(
|
||||||
|
feature = "compat",
|
||||||
|
serde(deserialize_with = "ruma_serde::deserialize_v1_powerlevel")
|
||||||
|
)]
|
||||||
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
#[serde(default, skip_serializing_if = "ruma_serde::is_default")]
|
||||||
users_default: Int,
|
users_default: Int,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user