use super::*;
pub async fn fetch_roles(guild_id: &str) -> Result<Vec<Role>, Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/roles");
let resp = request(Method::GET, &url, None).await.text().await.unwrap();
let roles: Vec<Role> = DeJson::deserialize_json(&resp).unwrap();
for role in &roles {
ROLE_CACHE.lock().await.put(role.id.clone(), role.clone());
}
Ok(roles)
}
pub async fn fetch_role(guild_id: &str, role_id: &str) -> Result<Role, Box<dyn std::error::Error>> {
if let Some(role) = ROLE_CACHE.lock().await.get(role_id).cloned() {
info!("Role cache hit");
return Ok(role);
}
let url = format!("guilds/{guild_id}/roles");
let resp = request(Method::GET, &url, None).await.text().await.unwrap();
let roles: Vec<Role> = DeJson::deserialize_json(&resp).unwrap();
let mut answer = None;
for role in &roles {
ROLE_CACHE.lock().await.put(role.id.clone(), role.clone());
if role.id == role_id {
answer = Some(role.clone());
}
}
if let Some(answer) = answer {
Ok(answer)
} else {
Err("Role not found".into())
}
}
pub async fn delete_role(guild_id: &str, role_id: &str) -> Result<(), Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/roles/{role_id}");
request(Method::DELETE, &url, None).await.text().await?;
ROLE_CACHE.lock().await.pop_entry(role_id);
Ok(())
}
pub async fn edit_role_position(
guild_id: &str,
role_id: &str,
position: i32,
) -> Result<Role, Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/roles/{role_id}");
let body = object! { "position": position };
let resp = request(Method::PATCH, &url, Some(body))
.await
.text()
.await
.unwrap();
let role: Role = DeJson::deserialize_json(&resp).unwrap();
ROLE_CACHE.lock().await.put(role.id.clone(), role.clone());
Ok(role)
}
pub async fn create_role(
guild_id: &str,
name: &str,
permissions: i32,
color: crate::color::Color,
hoist: bool,
mentionable: bool,
) -> Result<Role, Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/roles");
let color: u32 = color.into();
let body = object! {
"name": name,
"permissions": permissions,
"color": color,
"hoist": hoist,
"mentionable": mentionable,
};
let resp = request(Method::POST, &url, Some(body))
.await
.text()
.await
.unwrap();
let role: Role = DeJson::deserialize_json(&resp).unwrap();
ROLE_CACHE.lock().await.put(role.id.clone(), role.clone());
Ok(role)
}
pub async fn add_role(
guild_id: &str,
user_id: &str,
role_id: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/members/{user_id}/roles/{role_id}");
let resp = request(Method::PUT, &url, None).await.error_for_status()?;
Ok(())
}
pub async fn remove_role(
guild_id: &str,
user_id: &str,
role_id: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let url = format!("guilds/{guild_id}/members/{user_id}/roles/{role_id}");
let resp = request(Method::DELETE, &url, None)
.await
.error_for_status()?;
Ok(())
}