use std::ops::Deref;
use chrono::{DateTime, Utc};
use super::prelude::*;
#[cfg(feature = "model")]
use crate::builder::CreateInvite;
#[cfg(feature = "model")]
use crate::internal::prelude::*;
#[cfg(all(feature = "cache", feature = "model"))]
use super::{Permissions, utils as model_utils};
#[cfg(feature = "model")]
use crate::utils;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::Cache;
#[cfg(feature = "model")]
use crate::http::{Http, CacheHttp};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Invite {
pub approximate_member_count: Option<u64>,
pub approximate_presence_count: Option<u64>,
pub code: String,
pub channel: InviteChannel,
pub guild: Option<InviteGuild>,
pub inviter: Option<InviteUser>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "model")]
impl Invite {
#[inline]
pub async fn create<F>(
cache_http: impl CacheHttp,
channel_id: impl Into<ChannelId>,
f: F
) -> Result<RichInvite>
where F: FnOnce(CreateInvite) -> CreateInvite
{
let channel_id = channel_id.into();
#[cfg(feature = "cache")]
{
if let Some(cache) = cache_http.cache() {
let req = Permissions::CREATE_INVITE;
if !model_utils::user_has_perms(cache, channel_id, None, req).await? {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
}
let map = utils::hashmap_to_json_map(f(CreateInvite::default()).0);
cache_http.http().create_invite(channel_id.0, &map).await
}
pub async fn delete(&self, cache_http: impl CacheHttp) -> Result<Invite> {
#[cfg(feature = "cache")]
{
if let Some(cache) = cache_http.cache() {
let req = Permissions::MANAGE_GUILD;
let guild_id = self.guild.as_ref().map(|g| g.id);
if !model_utils::user_has_perms(cache, self.channel.id, guild_id, req).await? {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
}
cache_http.http().as_ref().delete_invite(&self.code).await
}
pub async fn get(http: impl AsRef<Http>, code: &str, stats: bool) -> Result<Invite> {
let mut invite = code;
#[cfg(feature = "utils")]
{
invite = crate::utils::parse_invite(invite);
}
http.as_ref().get_invite(invite, stats).await
}
pub fn url(&self) -> String { format!("https://discord.gg/{}", self.code) }
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InviteUser {
pub id: UserId,
#[serde(rename = "username")] pub name: String,
#[serde(deserialize_with = "deserialize_u16")] pub discriminator: u16,
pub avatar: Option<String>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
impl Deref for InviteUser {
type Target = UserId;
fn deref(&self) -> &Self::Target {
&self.id
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InviteChannel {
pub id: ChannelId,
pub name: String,
#[serde(rename = "type")] pub kind: ChannelType,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InviteGuild {
pub id: GuildId,
pub icon: Option<String>,
pub name: String,
pub splash_hash: Option<String>,
pub text_channel_count: Option<u64>,
pub voice_channel_count: Option<u64>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "model")]
impl InviteGuild {
#[cfg(all(feature = "cache", feature = "utils"))]
#[inline]
pub async fn shard_id(&self, cache: impl AsRef<Cache>) -> u64 {
self.id.shard_id(&cache).await
}
#[cfg(all(feature = "utils", not(feature = "cache")))]
#[inline]
pub async fn shard_id(&self, shard_count: u64) -> u64 {
self.id.shard_id(shard_count).await
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct RichInvite {
pub channel: InviteChannel,
pub code: String,
pub created_at: DateTime<Utc>,
pub guild: Option<InviteGuild>,
pub inviter: User,
pub max_age: u64,
pub max_uses: u64,
pub temporary: bool,
pub uses: u64,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "model")]
impl RichInvite {
pub async fn delete(&self, cache_http: impl CacheHttp) -> Result<Invite> {
#[cfg(feature = "cache")]
{
if let Some(cache) = cache_http.cache() {
let req = Permissions::MANAGE_GUILD;
let guild_id = self.guild.as_ref().map(|g| g.id);
if !model_utils::user_has_perms(cache, self.channel.id, guild_id, req).await? {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
}
cache_http.http().as_ref().delete_invite(&self.code).await
}
pub fn url(&self) -> String { format!("https://discord.gg/{}", self.code) }
}