use super::{BotApi, resource};
use crate::error::Result;
use crate::models::emoji::EmojiType;
use crate::{MessageReactionPager, ReactionEmoji, ReactionUsers};
use std::collections::HashMap;
use tracing::debug;
fn reaction_users_query_params(
cookie: Option<&str>,
limit: Option<u32>,
) -> HashMap<&'static str, String> {
let mut params = HashMap::new();
params.insert("limit", limit.unwrap_or(20).to_string());
if let Some(cookie) = cookie.filter(|cookie| !cookie.is_empty()) {
params.insert("cookie", cookie.to_string());
}
params
}
impl BotApi {
pub async fn put_reaction(
&self,
channel_id: &str,
message_id: &str,
emoji_type: i32,
emoji_id: &str,
) -> Result<()> {
debug!(
"Adding reaction to message {} in channel {}",
message_id, channel_id
);
let path = resource::message_reaction(channel_id, message_id, emoji_type, emoji_id);
self.http
.put(self.token(), &path, None::<&()>, None::<&()>)
.await?;
Ok(())
}
pub async fn create_message_reaction(
&self,
channel_id: &str,
message_id: &str,
emoji: &ReactionEmoji,
) -> Result<()> {
self.put_reaction(channel_id, message_id, emoji.emoji_type, &emoji.id)
.await
}
pub async fn delete_reaction(
&self,
channel_id: &str,
message_id: &str,
emoji_type: i32,
emoji_id: &str,
) -> Result<()> {
debug!(
"Removing reaction from message {} in channel {}",
message_id, channel_id
);
let path = resource::message_reaction(channel_id, message_id, emoji_type, emoji_id);
self.http.delete(self.token(), &path, None::<&()>).await?;
Ok(())
}
pub async fn delete_own_message_reaction(
&self,
channel_id: &str,
message_id: &str,
emoji: &ReactionEmoji,
) -> Result<()> {
self.delete_reaction(channel_id, message_id, emoji.emoji_type, &emoji.id)
.await
}
pub async fn get_reaction_users(
&self,
channel_id: &str,
message_id: &str,
emoji_type: EmojiType,
emoji_id: &str,
cookie: Option<&str>,
limit: Option<u32>,
) -> Result<ReactionUsers> {
debug!(
"Getting reaction users for message {} with emoji {}",
message_id, emoji_id
);
let params = reaction_users_query_params(cookie, limit);
let path =
resource::message_reaction(channel_id, message_id, u8::from(emoji_type), emoji_id);
let response = self.http.get(self.token(), &path, Some(¶ms)).await?;
Self::decode_json(response)
}
pub async fn get_message_reaction_users(
&self,
channel_id: &str,
message_id: &str,
emoji: &ReactionEmoji,
pager: &MessageReactionPager,
) -> Result<ReactionUsers> {
debug!(
"Getting reaction users for message {} with emoji {:?}",
message_id, emoji.id
);
let params = pager.query_params();
let path = resource::message_reaction(channel_id, message_id, emoji.emoji_type, &emoji.id);
let response = self
.http
.get(
self.token(),
&path,
if params.is_empty() {
None
} else {
Some(¶ms)
},
)
.await?;
Self::decode_json(response)
}
}
#[cfg(test)]
mod tests {
use super::reaction_users_query_params;
#[test]
fn reaction_users_query_omits_empty_cookie() {
let params = reaction_users_query_params(Some(""), None);
assert_eq!(params.get("limit").map(String::as_str), Some("20"));
assert!(!params.contains_key("cookie"));
}
#[test]
fn reaction_users_query_keeps_non_empty_cookie() {
let params = reaction_users_query_params(Some("cursor-1"), Some(50));
assert_eq!(params.get("limit").map(String::as_str), Some("50"));
assert_eq!(params.get("cookie").map(String::as_str), Some("cursor-1"));
}
}