ruma_events/room/encrypted/
relation_serde.rs

1use ruma_common::{
2    serde::{from_raw_json_value, JsonObject},
3    OwnedEventId,
4};
5use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
6use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue};
7
8use super::{InReplyTo, Relation, Thread};
9
10impl<'de> Deserialize<'de> for Relation {
11    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
12    where
13        D: Deserializer<'de>,
14    {
15        let json = Box::<RawJsonValue>::deserialize(deserializer)?;
16
17        let RelationDeHelper { in_reply_to, rel_type } = from_raw_json_value(&json)?;
18
19        let rel = match (in_reply_to, rel_type.as_deref()) {
20            (_, Some("m.thread")) => Relation::Thread(from_raw_json_value(&json)?),
21            (in_reply_to, Some("io.element.thread")) => {
22                let ThreadUnstableDeHelper { event_id, is_falling_back } =
23                    from_raw_json_value(&json)?;
24                Relation::Thread(Thread { event_id, in_reply_to, is_falling_back })
25            }
26            (_, Some("m.annotation")) => Relation::Annotation(from_raw_json_value(&json)?),
27            (_, Some("m.reference")) => Relation::Reference(from_raw_json_value(&json)?),
28            (_, Some("m.replace")) => Relation::Replacement(from_raw_json_value(&json)?),
29            (Some(in_reply_to), _) => Relation::Reply { in_reply_to },
30            _ => Relation::_Custom(from_raw_json_value(&json)?),
31        };
32
33        Ok(rel)
34    }
35}
36
37#[derive(Default, Deserialize)]
38struct RelationDeHelper {
39    #[serde(rename = "m.in_reply_to")]
40    in_reply_to: Option<InReplyTo>,
41
42    rel_type: Option<String>,
43}
44
45/// A thread relation without the reply fallback, with unstable names.
46#[derive(Clone, Deserialize)]
47struct ThreadUnstableDeHelper {
48    event_id: OwnedEventId,
49
50    #[serde(rename = "io.element.show_reply", default)]
51    is_falling_back: bool,
52}
53
54impl Relation {
55    pub(super) fn serialize_data(&self) -> JsonObject {
56        match serde_json::to_value(self).expect("relation serialization to succeed") {
57            JsonValue::Object(mut obj) => {
58                obj.remove("rel_type");
59                obj
60            }
61            _ => panic!("all relations must serialize to objects"),
62        }
63    }
64}
65
66impl Serialize for Relation {
67    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68    where
69        S: serde::Serializer,
70    {
71        match self {
72            Relation::Reply { in_reply_to } => {
73                let mut st = serializer.serialize_struct("Relation", 1)?;
74                st.serialize_field("m.in_reply_to", in_reply_to)?;
75                st.end()
76            }
77            Relation::Replacement(data) => data.serialize(serializer),
78            Relation::Reference(data) => data.serialize(serializer),
79            Relation::Annotation(data) => data.serialize(serializer),
80            Relation::Thread(data) => data.serialize(serializer),
81            Relation::_Custom(c) => c.serialize(serializer),
82        }
83    }
84}