use crate::consts::permissions::*;
use crate::prelude::{Channel, Guild, Member};
use chrono::{DateTime, Utc};
enum MemberOrId {
Id(u32),
MemberObj(Member),
}
pub async fn fetch_permissions(member: &Member, guild: &Guild, channel: Option<&Channel>) -> u64 {
let id = member.clone().user.unwrap_or_default().id;
if id.is_empty() {
return 0;
}
if guild.owner_id == id {
return ADMINISTRATOR;
}
let mut base_permissions = guild
.default_role()
.await
.unwrap()
.permissions
.parse::<u64>()
.unwrap();
for role_id in &member.roles {
if let Some(role) = guild.fetch_role(role_id).await.ok() {
base_permissions |= role.permissions.parse::<u64>().unwrap();
}
}
if base_permissions & ADMINISTRATOR == ADMINISTRATOR {
return ADMINISTRATOR;
}
if let Some(channel) = channel {
if let Some(overwrites) = &channel.permission_overwrites {
for overwrite in overwrites {
let allow = overwrite.allow.parse::<u64>().unwrap();
let deny = overwrite.deny.parse::<u64>().unwrap();
if overwrite.overwrite_type == 1 && overwrite.id == id {
base_permissions &= !deny;
base_permissions |= allow;
} else if overwrite.overwrite_type == 0 && member.roles.contains(&overwrite.id) {
base_permissions &= !deny;
base_permissions |= allow;
}
}
}
}
if let Some(timeout_str) = &member.timeout_until {
if let Ok(timeout_time) = DateTime::parse_from_rfc3339(timeout_str) {
if timeout_time > Utc::now() {
base_permissions &= VIEW_CHANNEL | READ_MESSAGE_HISTORY;
}
}
}
base_permissions
}