use std::collections::BTreeMap;
use ruma_common::{OwnedRoomId, OwnedServerName, OwnedUserId};
use ruma_macros::{EventContent, StringEnum};
use serde::{Deserialize, Serialize};
use crate::PrivOwnedStr;
#[derive(Clone, StringEnum)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_enum(rename_all = "snake_case")]
pub enum UserPresenceSharingState {
Allow,
Deny,
#[doc(hidden)]
_Custom(PrivOwnedStr),
}
#[derive(Clone, StringEnum)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_enum(rename_all = "snake_case")]
pub enum RoomPresenceSharingState {
Allow,
#[doc(hidden)]
_Custom(PrivOwnedStr),
}
#[derive(Clone, StringEnum)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_enum(rename_all = "snake_case")]
pub enum ServerPresenceSharingState {
Deny,
#[doc(hidden)]
_Custom(PrivOwnedStr),
}
#[derive(Clone, Default, Debug, Deserialize, Serialize, EventContent)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
#[ruma_event(type = "org.continuwuity.presence_v2.msc4495.presence.sharing", kind = GlobalAccountData)]
pub struct PresenceSharingEventContent {
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub share_locally: bool,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub users: BTreeMap<OwnedUserId, UserPresenceSharingState>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub rooms: BTreeMap<OwnedRoomId, RoomPresenceSharingState>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub servers: BTreeMap<OwnedServerName, ServerPresenceSharingState>,
}
impl PresenceSharingEventContent {
pub fn new(
share_locally: bool,
users: BTreeMap<OwnedUserId, UserPresenceSharingState>,
rooms: BTreeMap<OwnedRoomId, RoomPresenceSharingState>,
servers: BTreeMap<OwnedServerName, ServerPresenceSharingState>,
) -> Self {
Self { share_locally, users, rooms, servers }
}
}
#[cfg(test)]
mod tests {
use ruma_common::{
canonical_json::assert_to_canonical_json_eq, owned_room_id, owned_server_name,
owned_user_id, room_id, server_name, user_id,
};
use serde_json::{from_value as from_json_value, json};
use crate::presence::sharing::{
PresenceSharingEventContent, RoomPresenceSharingState, ServerPresenceSharingState,
UserPresenceSharingState,
};
#[test]
fn serialization() {
let content = PresenceSharingEventContent {
share_locally: true,
users: [
(owned_user_id!("@alice:example.com"), UserPresenceSharingState::Allow),
(owned_user_id!("@mallory:example.com"), UserPresenceSharingState::Deny),
]
.into(),
rooms: [(owned_room_id!("!family-group-chat"), RoomPresenceSharingState::Allow)].into(),
servers: [(owned_server_name!("matrix.org"), ServerPresenceSharingState::Deny)].into(),
};
assert_to_canonical_json_eq!(
content,
json!({
"share_locally": true,
"users": {
"@alice:example.com": "allow",
"@mallory:example.com": "deny",
},
"rooms": {
"!family-group-chat": "allow",
},
"servers": {
"matrix.org": "deny",
},
}),
);
}
#[test]
fn deserialization() {
let json_data = json!({
"share_locally": true,
"users": {
"@alice:example.com": "allow",
"@mallory:example.com": "deny",
},
"rooms": {
"!family-group-chat": "allow",
},
"servers": {
"matrix.org": "deny",
}
});
let content = from_json_value::<PresenceSharingEventContent>(json_data).unwrap();
assert!(content.share_locally);
assert_eq!(content.users.len(), 2);
assert_eq!(
content.users.get(user_id!("@alice:example.com")).unwrap(),
&UserPresenceSharingState::Allow
);
assert_eq!(
content.users.get(user_id!("@mallory:example.com")).unwrap(),
&UserPresenceSharingState::Deny
);
assert_eq!(content.rooms.len(), 1);
assert_eq!(
content.rooms.get(room_id!("!family-group-chat")).unwrap(),
&RoomPresenceSharingState::Allow
);
assert_eq!(content.servers.len(), 1);
assert_eq!(
content.servers.get(server_name!("matrix.org")).unwrap(),
&ServerPresenceSharingState::Deny
);
}
}