Complete EventResult API for stripped
This commit is contained in:
parent
c20d79db7d
commit
9b26c60fe8
11
src/lib.rs
11
src/lib.rs
@ -254,6 +254,7 @@ pub trait EventResultCompatible: Sized {
|
|||||||
fn try_from_raw(_: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)>;
|
fn try_from_raw(_: Self::Raw) -> Result<Self, (Self::Err, Self::Raw)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Replace with ! once that is stable
|
||||||
/// An empty type
|
/// An empty type
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Void {}
|
pub enum Void {}
|
||||||
@ -335,14 +336,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EventResultCompatible> Serialize for EventResult<T> {
|
// For now, we don't support serialization of EventResult.
|
||||||
|
// This is going to be added in a future version.
|
||||||
|
/*impl<T: EventResultCompatible> Serialize for EventResult<T> {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/// An error when attempting to create a value from a string via the `FromStr` trait.
|
/// An error when attempting to create a value from a string via the `FromStr` trait.
|
||||||
///
|
///
|
||||||
@ -889,12 +891,13 @@ mod vec_as_map_of_empty {
|
|||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::{collections::HashMap, hash::Hash};
|
use std::{collections::HashMap, hash::Hash};
|
||||||
|
|
||||||
|
#[allow(clippy::ptr_arg)]
|
||||||
pub fn serialize<S, T>(vec: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
|
pub fn serialize<S, T>(vec: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
T: Serialize + Hash + Eq,
|
T: Serialize + Hash + Eq,
|
||||||
{
|
{
|
||||||
vec.into_iter()
|
vec.iter()
|
||||||
.map(|v| (v, Empty))
|
.map(|v| (v, Empty))
|
||||||
.collect::<HashMap<_, _>>()
|
.collect::<HashMap<_, _>>()
|
||||||
.serialize(serializer)
|
.serialize(serializer)
|
||||||
|
132
src/stripped.rs
132
src/stripped.rs
@ -6,7 +6,8 @@
|
|||||||
//! the other fields are otherwise inapplicable.
|
//! the other fields are otherwise inapplicable.
|
||||||
|
|
||||||
use ruma_identifiers::UserId;
|
use ruma_identifiers::UserId;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
room::{
|
room::{
|
||||||
@ -67,6 +68,7 @@ pub struct StrippedStateContent<C> {
|
|||||||
/// Data specific to the event type.
|
/// Data specific to the event type.
|
||||||
pub content: C,
|
pub content: C,
|
||||||
|
|
||||||
|
// FIXME(jplatte): It's unclear to me why this is stored
|
||||||
/// The type of the event.
|
/// The type of the event.
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub event_type: EventType,
|
pub event_type: EventType,
|
||||||
@ -119,7 +121,34 @@ impl EventResultCompatible for StrippedState {
|
|||||||
type Err = String;
|
type Err = String;
|
||||||
|
|
||||||
fn try_from_raw(raw: raw::StrippedState) -> Result<Self, (Self::Err, Self::Raw)> {
|
fn try_from_raw(raw: raw::StrippedState) -> Result<Self, (Self::Err, Self::Raw)> {
|
||||||
unimplemented!()
|
use raw::StrippedState::*;
|
||||||
|
|
||||||
|
fn convert<T: EventResultCompatible>(
|
||||||
|
raw_variant: fn(T::Raw) -> raw::StrippedState,
|
||||||
|
variant: fn(T) -> StrippedState,
|
||||||
|
raw: T::Raw,
|
||||||
|
) -> Result<StrippedState, (String, raw::StrippedState)> {
|
||||||
|
T::try_from_raw(raw)
|
||||||
|
.map(variant)
|
||||||
|
.map_err(|(msg, raw)| (msg.into(), raw_variant(raw)))
|
||||||
|
}
|
||||||
|
|
||||||
|
match raw {
|
||||||
|
RoomAliases(c) => convert(RoomAliases, Self::RoomAliases, c),
|
||||||
|
RoomAvatar(c) => convert(RoomAvatar, Self::RoomAvatar, c),
|
||||||
|
RoomCanonicalAlias(c) => convert(RoomCanonicalAlias, Self::RoomCanonicalAlias, c),
|
||||||
|
RoomCreate(c) => convert(RoomCreate, Self::RoomCreate, c),
|
||||||
|
RoomGuestAccess(c) => convert(RoomGuestAccess, Self::RoomGuestAccess, c),
|
||||||
|
RoomHistoryVisibility(c) => {
|
||||||
|
convert(RoomHistoryVisibility, Self::RoomHistoryVisibility, c)
|
||||||
|
}
|
||||||
|
RoomJoinRules(c) => convert(RoomJoinRules, Self::RoomJoinRules, c),
|
||||||
|
RoomMember(c) => convert(RoomMember, Self::RoomMember, c),
|
||||||
|
RoomName(c) => convert(RoomName, Self::RoomName, c),
|
||||||
|
RoomPowerLevels(c) => convert(RoomPowerLevels, Self::RoomPowerLevels, c),
|
||||||
|
RoomThirdPartyInvite(c) => convert(RoomThirdPartyInvite, Self::RoomThirdPartyInvite, c),
|
||||||
|
RoomTopic(c) => convert(RoomTopic, Self::RoomTopic, c),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,9 +159,16 @@ where
|
|||||||
type Raw = StrippedStateContent<C::Raw>;
|
type Raw = StrippedStateContent<C::Raw>;
|
||||||
type Err = C::Err;
|
type Err = C::Err;
|
||||||
|
|
||||||
fn try_from_raw(raw: StrippedStateContent<C::Raw>) -> Result<Self, (Self::Err, Self::Raw)> {
|
fn try_from_raw(mut raw: StrippedStateContent<C::Raw>) -> Result<Self, (Self::Err, Self::Raw)> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
content: C::try_from_raw(raw.content).map_err(|(msg, raw)| (msg, unimplemented!()))?,
|
content: match C::try_from_raw(raw.content) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err((msg, raw_content)) => {
|
||||||
|
// we moved raw.content, so we need to put it back before returning raw
|
||||||
|
raw.content = raw_content;
|
||||||
|
return Err((msg, raw));
|
||||||
|
}
|
||||||
|
},
|
||||||
event_type: raw.event_type,
|
event_type: raw.event_type,
|
||||||
state_key: raw.state_key,
|
state_key: raw.state_key,
|
||||||
sender: raw.sender,
|
sender: raw.sender,
|
||||||
@ -164,13 +200,58 @@ impl Serialize for StrippedState {
|
|||||||
|
|
||||||
impl<'de, C> Deserialize<'de> for StrippedStateContent<C>
|
impl<'de, C> Deserialize<'de> for StrippedStateContent<C>
|
||||||
where
|
where
|
||||||
C: Deserialize<'de>,
|
C: DeserializeOwned,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
use serde::de::Error as _;
|
||||||
|
use serde_json::from_value;
|
||||||
|
|
||||||
|
let conv_err = |error: serde_json::Error| D::Error::custom(error.to_string());
|
||||||
|
|
||||||
|
// TODO: Optimize
|
||||||
|
let value = Value::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let event_type = from_value(
|
||||||
|
value
|
||||||
|
.get("type")
|
||||||
|
.map(Clone::clone)
|
||||||
|
.ok_or_else(|| D::Error::missing_field("type"))?,
|
||||||
|
)
|
||||||
|
.map_err(conv_err)?;
|
||||||
|
|
||||||
|
let content = from_value(
|
||||||
|
value
|
||||||
|
.get("content")
|
||||||
|
.map(Clone::clone)
|
||||||
|
.ok_or_else(|| D::Error::missing_field("content"))?,
|
||||||
|
)
|
||||||
|
.map_err(conv_err)?;
|
||||||
|
|
||||||
|
let sender = from_value(
|
||||||
|
value
|
||||||
|
.get("sender")
|
||||||
|
.map(Clone::clone)
|
||||||
|
.ok_or_else(|| D::Error::missing_field("sender"))?,
|
||||||
|
)
|
||||||
|
.map_err(conv_err)?;
|
||||||
|
|
||||||
|
let state_key = from_value(
|
||||||
|
value
|
||||||
|
.get("state_key")
|
||||||
|
.map(Clone::clone)
|
||||||
|
.ok_or_else(|| D::Error::missing_field("state_key"))?,
|
||||||
|
)
|
||||||
|
.map_err(conv_err)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
content,
|
||||||
|
event_type,
|
||||||
|
state_key,
|
||||||
|
sender,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +351,44 @@ mod raw {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
use crate::EventType::*;
|
||||||
|
use serde::de::Error as _;
|
||||||
|
use serde_json::{from_value, Value};
|
||||||
|
|
||||||
|
let conv_err = |error: serde_json::Error| D::Error::custom(error.to_string());
|
||||||
|
|
||||||
|
// TODO: Optimize
|
||||||
|
let value = Value::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let event_type = from_value(
|
||||||
|
value
|
||||||
|
.get("type")
|
||||||
|
.map(Clone::clone)
|
||||||
|
.ok_or_else(|| D::Error::missing_field("type"))?,
|
||||||
|
)
|
||||||
|
.map_err(conv_err)?;
|
||||||
|
|
||||||
|
Ok(match event_type {
|
||||||
|
RoomAliases => StrippedState::RoomAliases(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomAvatar => Self::RoomAvatar(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomCanonicalAlias => {
|
||||||
|
Self::RoomCanonicalAlias(from_value(value).map_err(conv_err)?)
|
||||||
|
}
|
||||||
|
RoomCreate => Self::RoomCreate(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomGuestAccess => Self::RoomGuestAccess(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomHistoryVisibility => {
|
||||||
|
Self::RoomHistoryVisibility(from_value(value).map_err(conv_err)?)
|
||||||
|
}
|
||||||
|
RoomJoinRules => Self::RoomJoinRules(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomMember => Self::RoomMember(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomName => Self::RoomName(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomPowerLevels => Self::RoomPowerLevels(from_value(value).map_err(conv_err)?),
|
||||||
|
RoomThirdPartyInvite => {
|
||||||
|
Self::RoomThirdPartyInvite(from_value(value).map_err(conv_err)?)
|
||||||
|
}
|
||||||
|
RoomTopic => Self::RoomTopic(from_value(value).map_err(conv_err)?),
|
||||||
|
_ => return Err(D::Error::custom("not a state event")),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user