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::{canonical_json::assert_to_canonical_json_eq, owned_room_id, user_id};
63 use serde_json::{from_value as from_json_value, json};
64
65 use super::{DirectEvent, DirectEventContent};
66
67 #[test]
68 fn serialization() {
69 let mut content = DirectEventContent(BTreeMap::new());
70 let alice = user_id!("@alice:ruma.io");
71 let alice_mail = "alice@ruma.io";
72 let rooms = vec![owned_room_id!("!1:ruma.io")];
73 let mail_rooms = vec![owned_room_id!("!3:ruma.io")];
74
75 content.insert(alice.into(), rooms.clone());
76 content.insert(alice_mail.into(), mail_rooms.clone());
77
78 let json_data = json!({
79 alice: rooms,
80 alice_mail: mail_rooms,
81 });
82
83 assert_to_canonical_json_eq!(content, json_data);
84 }
85
86 #[test]
87 fn deserialization() {
88 let alice = user_id!("@alice:ruma.io");
89 let alice_mail = "alice@ruma.io";
90 let rooms = vec![owned_room_id!("!1:ruma.io"), owned_room_id!("!2:ruma.io")];
91 let mail_rooms = vec![owned_room_id!("!3:ruma.io")];
92
93 let json_data = json!({
94 "content": {
95 alice: rooms,
96 alice_mail: mail_rooms,
97 },
98 "type": "m.direct"
99 });
100
101 let event: DirectEvent = from_json_value(json_data).unwrap();
102
103 let direct_rooms = event.content.get(alice.as_str()).unwrap();
104 assert!(direct_rooms.contains(&rooms[0]));
105 assert!(direct_rooms.contains(&rooms[1]));
106
107 let email_direct_rooms = event.content.get(alice_mail).unwrap();
108 assert!(email_direct_rooms.contains(&mail_rooms[0]));
109 }
110}