logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! `Serialize` and `Deserialize` implementations for extensible events (MSC1767).

use std::convert::TryFrom;

use serde::{ser::SerializeStruct, Deserialize, Serialize};

use super::{MessageContent, Text, TryFromExtensibleError};

#[derive(Debug, Default, Deserialize)]
pub(crate) struct MessageContentSerDeHelper {
    /// Plain text short form, stable name.
    #[serde(rename = "m.text")]
    text_stable: Option<String>,

    /// Plain text short form, unstable name.
    #[serde(rename = "org.matrix.msc1767.text")]
    text_unstable: Option<String>,

    /// Long form, stable name.
    #[serde(rename = "m.message")]
    message_stable: Option<Vec<Text>>,

    /// Long form, unstable name.
    #[serde(rename = "org.matrix.msc1767.message")]
    message_unstable: Option<Vec<Text>>,
}

impl TryFrom<MessageContentSerDeHelper> for MessageContent {
    type Error = TryFromExtensibleError;

    fn try_from(helper: MessageContentSerDeHelper) -> Result<Self, Self::Error> {
        let MessageContentSerDeHelper {
            text_stable,
            text_unstable,
            message_stable,
            message_unstable,
        } = helper;

        if let Some(message) = message_stable.or(message_unstable) {
            Ok(Self(message))
        } else if let Some(text) = text_stable.or(text_unstable) {
            Ok(Self::plain(text))
        } else {
            Err(TryFromExtensibleError::MissingField("m.message or m.text".to_owned()))
        }
    }
}

impl Serialize for MessageContent {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut st = serializer.serialize_struct("MessageContent", 1)?;
        if self.len() == 1 && self[0].mimetype == "text/plain" {
            st.serialize_field("org.matrix.msc1767.text", &self[0].body)?;
        } else {
            st.serialize_field("org.matrix.msc1767.message", &self.0)?;
        }
        st.end()
    }
}

pub(crate) mod as_vec {
    use serde::{de, ser::SerializeSeq, Deserialize, Deserializer, Serializer};

    use crate::events::message::{MessageContent, Text};

    /// Serializes a `Option<MessageContent>` as a `Vec<Text>`.
    pub fn serialize<S>(content: &Option<MessageContent>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if let Some(content) = content {
            let mut seq = serializer.serialize_seq(Some(content.len()))?;
            for e in content.iter() {
                seq.serialize_element(e)?;
            }
            seq.end()
        } else {
            serializer.serialize_seq(Some(0))?.end()
        }
    }

    /// Deserializes a `Vec<Text>` to an `Option<MessageContent>`.
    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<MessageContent>, D::Error>
    where
        D: Deserializer<'de>,
    {
        Option::<Vec<Text>>::deserialize(deserializer).and_then(|content| {
            content.map(MessageContent::new).ok_or_else(|| {
                de::Error::invalid_value(de::Unexpected::Other("empty array"), &"a non-empty array")
            })
        })
    }
}