events: Implement Deserialize for encrypted::Relation
This commit is contained in:
parent
4d9781e05f
commit
c8e61a2ee7
@ -23,11 +23,7 @@ pub struct EncryptedEventContent {
|
||||
pub encrypted: EncryptedContentBlock,
|
||||
|
||||
/// Information about related events.
|
||||
#[serde(
|
||||
flatten,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
deserialize_with = "super::room::encrypted::relation_serde::deserialize_relation"
|
||||
)]
|
||||
#[serde(rename = "m.relates_to", skip_serializing_if = "Option::is_none")]
|
||||
pub relates_to: Option<Relation>,
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,7 @@ pub struct RoomEncryptedEventContent {
|
||||
pub scheme: EncryptedEventScheme,
|
||||
|
||||
/// Information about related events.
|
||||
#[serde(
|
||||
flatten,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
deserialize_with = "relation_serde::deserialize_relation"
|
||||
)]
|
||||
#[serde(rename = "m.relates_to", skip_serializing_if = "Option::is_none")]
|
||||
pub relates_to: Option<Relation>,
|
||||
}
|
||||
|
||||
|
@ -1,41 +1,45 @@
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use super::{Annotation, InReplyTo, Reference, Relation, Replacement, Thread};
|
||||
use crate::OwnedEventId;
|
||||
|
||||
pub(crate) fn deserialize_relation<'de, D>(deserializer: D) -> Result<Option<Relation>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let ev = EventWithRelatesToJsonRepr::deserialize(deserializer)?;
|
||||
|
||||
if let Some(
|
||||
RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id, is_falling_back })
|
||||
| RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }),
|
||||
) = ev.relates_to.relation
|
||||
impl<'de> Deserialize<'de> for Relation {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let in_reply_to = ev.relates_to.in_reply_to;
|
||||
return Ok(Some(Relation::Thread(Thread { event_id, in_reply_to, is_falling_back })));
|
||||
}
|
||||
let rel = if let Some(in_reply_to) = ev.relates_to.in_reply_to {
|
||||
Some(Relation::Reply { in_reply_to })
|
||||
} else {
|
||||
ev.relates_to.relation.map(|relation| match relation {
|
||||
RelationJsonRepr::Annotation(a) => Relation::Annotation(a),
|
||||
RelationJsonRepr::Reference(r) => Relation::Reference(r),
|
||||
RelationJsonRepr::Replacement(Replacement { event_id }) => {
|
||||
Relation::Replacement(Replacement { event_id })
|
||||
}
|
||||
RelationJsonRepr::ThreadStable(_) | RelationJsonRepr::ThreadUnstable(_) => {
|
||||
unreachable!()
|
||||
}
|
||||
// FIXME: Maybe we should log this, though at this point we don't even have
|
||||
// access to the rel_type of the unknown relation.
|
||||
RelationJsonRepr::Unknown => Relation::_Custom,
|
||||
})
|
||||
};
|
||||
let relates_to = RelatesToJsonRepr::deserialize(deserializer)?;
|
||||
|
||||
Ok(rel)
|
||||
if let Some(
|
||||
RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id, is_falling_back })
|
||||
| RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }),
|
||||
) = relates_to.relation
|
||||
{
|
||||
let in_reply_to = relates_to.in_reply_to;
|
||||
return Ok(Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }));
|
||||
}
|
||||
let rel = if let Some(in_reply_to) = relates_to.in_reply_to {
|
||||
Relation::Reply { in_reply_to }
|
||||
} else if let Some(relation) = relates_to.relation {
|
||||
match relation {
|
||||
RelationJsonRepr::Annotation(a) => Relation::Annotation(a),
|
||||
RelationJsonRepr::Reference(r) => Relation::Reference(r),
|
||||
RelationJsonRepr::Replacement(Replacement { event_id }) => {
|
||||
Relation::Replacement(Replacement { event_id })
|
||||
}
|
||||
RelationJsonRepr::ThreadStable(_) | RelationJsonRepr::ThreadUnstable(_) => {
|
||||
unreachable!()
|
||||
}
|
||||
// FIXME: Maybe we should log this, though at this point we don't even have
|
||||
// access to the rel_type of the unknown relation.
|
||||
RelationJsonRepr::Unknown => Relation::_Custom,
|
||||
}
|
||||
} else {
|
||||
return Err(de::Error::missing_field("m.in_reply_to or rel_type"));
|
||||
};
|
||||
|
||||
Ok(rel)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Relation {
|
||||
@ -71,16 +75,10 @@ impl Serialize for Relation {
|
||||
Relation::_Custom => RelatesToJsonRepr::default(),
|
||||
};
|
||||
|
||||
EventWithRelatesToJsonRepr { relates_to }.serialize(serializer)
|
||||
relates_to.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct EventWithRelatesToJsonRepr {
|
||||
#[serde(rename = "m.relates_to", default, skip_serializing_if = "RelatesToJsonRepr::is_empty")]
|
||||
relates_to: RelatesToJsonRepr,
|
||||
}
|
||||
|
||||
/// Struct modeling the different ways relationships can be expressed in a `m.relates_to` field of
|
||||
/// an event.
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
@ -92,12 +90,6 @@ struct RelatesToJsonRepr {
|
||||
relation: Option<RelationJsonRepr>,
|
||||
}
|
||||
|
||||
impl RelatesToJsonRepr {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.in_reply_to.is_none() && self.relation.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
/// A thread relation without the reply fallback, with stable names.
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
struct ThreadStableJsonRepr {
|
||||
|
Loading…
x
Reference in New Issue
Block a user