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
|
||||
/// 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")]
|
||||
pub room: Int,
|
||||
}
|
||||
|
@ -25,7 +25,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub ban: Int,
|
||||
@ -38,7 +41,7 @@ pub struct RoomPowerLevelsEventContent {
|
||||
/// integers too.
|
||||
#[cfg_attr(
|
||||
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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
@ -48,7 +51,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub events_default: Int,
|
||||
@ -57,7 +63,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
pub invite: Int,
|
||||
|
||||
@ -65,7 +74,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub kick: Int,
|
||||
@ -74,7 +86,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub redact: Int,
|
||||
@ -83,7 +98,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub state_default: Int,
|
||||
@ -96,7 +114,7 @@ pub struct RoomPowerLevelsEventContent {
|
||||
/// integers too.
|
||||
#[cfg_attr(
|
||||
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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
@ -106,7 +124,10 @@ pub struct RoomPowerLevelsEventContent {
|
||||
///
|
||||
/// If you activate the `compat` feature, deserialization will work for stringified
|
||||
/// 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")]
|
||||
#[ruma_event(skip_redaction)]
|
||||
pub users_default: Int,
|
||||
|
@ -33,7 +33,7 @@ pub use self::{
|
||||
empty::vec_as_map_of_empty,
|
||||
raw::Raw,
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{collections::BTreeMap, convert::TryInto, fmt, marker::PhantomData};
|
||||
|
||||
use js_int::Int;
|
||||
use js_int::{Int, UInt};
|
||||
use serde::{
|
||||
de::{self, Deserializer, IntoDeserializer as _, MapAccess, Visitor},
|
||||
ser::Serializer,
|
||||
@ -52,8 +52,8 @@ where
|
||||
/// Take either an integer number or a string and deserialize to an integer number.
|
||||
///
|
||||
/// To be used like this:
|
||||
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
|
||||
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
|
||||
/// `#[serde(deserialize_with = "deserialize_v1_powerlevel")]`
|
||||
pub fn deserialize_v1_powerlevel<'de, D>(de: D) -> Result<Int, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@ -107,7 +107,12 @@ where
|
||||
}
|
||||
|
||||
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.
|
||||
///
|
||||
/// To be used like this:
|
||||
/// `#[serde(deserialize_with = "btreemap_int_or_string_to_int_values")]`
|
||||
pub fn btreemap_int_or_string_to_int_values<'de, D, T>(de: D) -> Result<BTreeMap<T, Int>, D::Error>
|
||||
/// `#[serde(deserialize_with = "btreemap_deserialize_v1_powerlevel_values")]`
|
||||
pub fn btreemap_deserialize_v1_powerlevel_values<'de, D, T>(
|
||||
de: D,
|
||||
) -> Result<BTreeMap<T, Int>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
T: Deserialize<'de> + Ord,
|
||||
@ -132,7 +139,7 @@ where
|
||||
where
|
||||
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 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]
|
||||
fn int_or_string() -> serde_json::Result<()> {
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Test {
|
||||
#[serde(deserialize_with = "int_or_string_to_int")]
|
||||
num: Int,
|
||||
}
|
||||
|
||||
assert_matches!(
|
||||
serde_json::from_value::<Test>(serde_json::json!({ "num": "0" }))?,
|
||||
Test { num } if num == int!(0)
|
||||
@ -193,4 +200,24 @@ mod tests {
|
||||
|
||||
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 {
|
||||
#[cfg_attr(
|
||||
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")]
|
||||
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")]
|
||||
users_default: Int,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user