1use std::{
6 collections::{BTreeMap, btree_map},
7 ops::{Deref, DerefMut},
8};
9
10use ruma_common::OwnedRoomId;
11pub use ruma_common::{DirectUserIdentifier, OwnedDirectUserIdentifier};
12use ruma_macros::EventContent;
13use serde::{Deserialize, Serialize};
14
15#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
22#[allow(clippy::exhaustive_structs)]
23#[ruma_event(type = "m.direct", kind = GlobalAccountData)]
24pub struct DirectEventContent(pub BTreeMap<OwnedDirectUserIdentifier, Vec<OwnedRoomId>>);
25
26impl Deref for DirectEventContent {
27 type Target = BTreeMap<OwnedDirectUserIdentifier, Vec<OwnedRoomId>>;
28
29 fn deref(&self) -> &Self::Target {
30 &self.0
31 }
32}
33
34impl DerefMut for DirectEventContent {
35 fn deref_mut(&mut self) -> &mut Self::Target {
36 &mut self.0
37 }
38}
39
40impl IntoIterator for DirectEventContent {
41 type Item = (OwnedDirectUserIdentifier, Vec<OwnedRoomId>);
42 type IntoIter = btree_map::IntoIter<OwnedDirectUserIdentifier, Vec<OwnedRoomId>>;
43
44 fn into_iter(self) -> Self::IntoIter {
45 self.0.into_iter()
46 }
47}
48
49impl FromIterator<(OwnedDirectUserIdentifier, Vec<OwnedRoomId>)> for DirectEventContent {
50 fn from_iter<T>(iter: T) -> Self
51 where
52 T: IntoIterator<Item = (OwnedDirectUserIdentifier, Vec<OwnedRoomId>)>,
53 {
54 Self(BTreeMap::from_iter(iter))
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use std::collections::BTreeMap;
61
62 use ruma_common::{
63 DirectUserIdentifier, canonical_json::assert_to_canonical_json_eq, owned_room_id, user_id,
64 };
65 use serde_json::{from_value as from_json_value, json};
66
67 use super::{DirectEvent, DirectEventContent};
68
69 #[test]
70 fn serialization() {
71 let mut content = DirectEventContent(BTreeMap::new());
72 let alice = user_id!("@alice:ruma.io");
73 let alice_mail = "alice@ruma.io";
74 let rooms = vec![owned_room_id!("!1:ruma.io")];
75 let mail_rooms = vec![owned_room_id!("!3:ruma.io")];
76
77 content.insert(alice.into(), rooms.clone());
78 content.insert(alice_mail.into(), mail_rooms.clone());
79
80 let json_data = json!({
81 alice: rooms,
82 alice_mail: mail_rooms,
83 });
84
85 assert_to_canonical_json_eq!(content, json_data);
86 }
87
88 #[test]
89 fn deserialization() {
90 let alice = user_id!("@alice:ruma.io");
91 let alice_mail = "alice@ruma.io";
92 let rooms = vec![owned_room_id!("!1:ruma.io"), owned_room_id!("!2:ruma.io")];
93 let mail_rooms = vec![owned_room_id!("!3:ruma.io")];
94
95 let json_data = json!({
96 "content": {
97 alice: rooms,
98 alice_mail: mail_rooms,
99 },
100 "type": "m.direct"
101 });
102
103 let event: DirectEvent = from_json_value(json_data).unwrap();
104
105 let direct_rooms = event.content.get(<&DirectUserIdentifier>::from(alice)).unwrap();
106 assert!(direct_rooms.contains(&rooms[0]));
107 assert!(direct_rooms.contains(&rooms[1]));
108
109 let email_direct_rooms =
110 event.content.get(<&DirectUserIdentifier>::from(alice_mail)).unwrap();
111 assert!(email_direct_rooms.contains(&mail_rooms[0]));
112 }
113}