Skip to main content

ruma_events/room/encrypted/
relation_serde.rs

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