use serde::{Deserialize, Serialize};
use crate::{
builders::EditMember,
models::{Attachment, Id},
Context, Result,
};
#[derive(Debug, Clone, PartialEq, Deserialize, Hash, Eq)]
pub struct MemberId {
#[serde(rename = "server")]
pub server_id: Id,
#[serde(rename = "user")]
pub user_id: Id,
}
impl From<(&Id, &Id)> for MemberId {
fn from((server_id, user_id): (&Id, &Id)) -> Self {
Self {
server_id: server_id.clone(),
user_id: user_id.clone(),
}
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct Member {
#[serde(rename = "_id")]
pub id: MemberId,
pub nickname: Option<String>,
pub avatar: Option<Attachment>,
#[serde(default)]
pub roles: Vec<Id>,
}
impl Member {
pub async fn fetch(cx: &Context, server_id: &Id, user_id: &Id) -> Result<Self> {
#[cfg(feature = "cache")]
if let Some(member) = cx.cache.member(&(server_id, user_id).into()).await {
return Ok(member);
}
cx.http_client
.get(format!("servers/{}/members/{}", server_id, user_id))
.await
}
pub async fn edit(&self, cx: &Context, builder: EditMember) -> Result {
cx.http_client
.patch(
format!("servers/{}/members/{}", self.id.server_id, self.id.user_id),
builder,
)
.await
}
pub async fn kick(&self, cx: &Context) -> Result {
cx.http_client
.delete(format!(
"servers/{}/members/{}",
self.id.server_id, self.id.user_id
))
.await
}
pub async fn ban(&self, cx: &Context, reason: Option<impl Into<String>>) -> Result {
cx.http_client
.put(
format!("servers/{}/bans/{}", self.id.server_id, self.id.user_id),
CreateBan::new(reason),
)
.await
}
}
#[derive(Debug, Serialize)]
struct CreateBan {
#[serde(skip_serializing_if = "Option::is_none")]
reason: Option<String>,
}
impl CreateBan {
fn new(reason: Option<impl Into<String>>) -> Self {
match reason {
Some(reason) => CreateBan {
reason: Some(reason.into()),
},
None => CreateBan { reason: None },
}
}
}