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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Types for the [`m.marked_unread`] event.
//!
//! [`m.marked_unread`]: https://spec.matrix.org/latest/client-server-api/#unread-markers

use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};

/// The content of an `m.marked_unread` event.
///
/// Whether the room has been explicitly marked as unread.
///
/// This event appears in the user's room account data for the room the marker is applicable for.
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "m.marked_unread", kind = RoomAccountData)]
pub struct MarkedUnreadEventContent {
    /// The current unread state.
    pub unread: bool,
}

impl MarkedUnreadEventContent {
    /// Creates a new `MarkedUnreadEventContent` with the given value.
    pub fn new(unread: bool) -> Self {
        Self { unread }
    }
}

/// The content of a [`com.famedly.marked_unread`] event, the unstable version of
/// [MarkedUnreadEventContent].
///
/// Whether the room has been explicitly marked as unread.
///
/// This event appears in the user's room account data for the room the marker is applicable for.
///
/// [`com.famedly.marked_unread`]: https://github.com/matrix-org/matrix-spec-proposals/pull/2867
#[cfg(feature = "unstable-msc2867")]
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[ruma_event(type = "com.famedly.marked_unread", kind = RoomAccountData)]
#[serde(transparent)]
pub struct UnstableMarkedUnreadEventContent(pub MarkedUnreadEventContent);

#[cfg(feature = "unstable-msc2867")]
impl std::ops::Deref for UnstableMarkedUnreadEventContent {
    type Target = MarkedUnreadEventContent;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[cfg(feature = "unstable-msc2867")]
impl From<MarkedUnreadEventContent> for UnstableMarkedUnreadEventContent {
    fn from(value: MarkedUnreadEventContent) -> Self {
        Self(value)
    }
}

#[cfg(feature = "unstable-msc2867")]
impl From<UnstableMarkedUnreadEventContent> for MarkedUnreadEventContent {
    fn from(value: UnstableMarkedUnreadEventContent) -> Self {
        value.0
    }
}

#[cfg(all(test, feature = "unstable-msc2867"))]
mod tests {
    use assert_matches2::assert_matches;
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::{MarkedUnreadEventContent, UnstableMarkedUnreadEventContent};
    use crate::{AnyRoomAccountDataEvent, RoomAccountDataEvent};

    #[test]
    fn deserialize() {
        let raw_unstable_marked_unread = json!({
            "type": "com.famedly.marked_unread",
            "content": {
                "unread": true,
            },
        });
        let unstable_marked_unread_account_data =
            from_json_value::<AnyRoomAccountDataEvent>(raw_unstable_marked_unread).unwrap();
        assert_matches!(
            unstable_marked_unread_account_data,
            AnyRoomAccountDataEvent::UnstableMarkedUnread(unstable_marked_unread)
        );
        assert!(unstable_marked_unread.content.unread);

        let raw_marked_unread = json!({
            "type": "m.marked_unread",
            "content": {
                "unread": true,
            },
        });
        let marked_unread_account_data =
            from_json_value::<AnyRoomAccountDataEvent>(raw_marked_unread).unwrap();
        assert_matches!(
            marked_unread_account_data,
            AnyRoomAccountDataEvent::MarkedUnread(marked_unread)
        );
        assert!(marked_unread.content.unread);
    }

    #[test]
    fn serialize() {
        let marked_unread = MarkedUnreadEventContent::new(true);
        let marked_unread_account_data = RoomAccountDataEvent { content: marked_unread.clone() };
        assert_eq!(
            to_json_value(marked_unread_account_data).unwrap(),
            json!({
                "type": "m.marked_unread",
                "content": {
                    "unread": true,
                },
            })
        );

        let unstable_marked_unread = UnstableMarkedUnreadEventContent::from(marked_unread);
        let unstable_marked_unread_account_data =
            RoomAccountDataEvent { content: unstable_marked_unread };
        assert_eq!(
            to_json_value(unstable_marked_unread_account_data).unwrap(),
            json!({
                "type": "com.famedly.marked_unread",
                "content": {
                    "unread": true,
                },
            })
        );
    }
}