Skip to main content

neptunium_http/endpoints/channel/messages/
reactions.rs

1use std::fmt::Display;
2
3use bon::Builder;
4use neptunium_model::{
5    id::{
6        Id,
7        marker::{ChannelMarker, EmojiMarker, MessageMarker, UserMarker},
8    },
9    user::PartialUser,
10};
11use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
12use reqwest::Method;
13
14use crate::{endpoints::Endpoint, request::Request};
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
17pub enum RequestReactionType<'a> {
18    Custom {
19        id: Id<EmojiMarker>,
20        /// Name of the custom emoji.
21        name: Option<&'a str>,
22    },
23    /// A unicode emoji, such as "🪑".
24    Unicode(&'a str),
25}
26
27impl Display for RequestReactionType<'_> {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Self::Custom { id, name } => {
31                if let Some(name) = name {
32                    f.write_str(name)?;
33                } else {
34                    f.write_str("e")?;
35                }
36
37                f.write_str(":")?;
38
39                id.fmt(f)
40            }
41            Self::Unicode(name) => utf8_percent_encode(name, NON_ALPHANUMERIC).fmt(f),
42        }
43    }
44}
45
46#[derive(Builder, Copy, Clone, Debug)]
47pub struct ListReactions<'a> {
48    pub channel_id: Id<ChannelMarker>,
49    pub message_id: Id<MessageMarker>,
50    pub emoji: &'a RequestReactionType<'a>,
51}
52
53impl Endpoint for ListReactions<'_> {
54    type Response = Vec<PartialUser>;
55    fn into_request(self) -> crate::request::Request {
56        Request::builder()
57            .method(Method::GET)
58            .path(format!(
59                "/channels/{}/messages/{}/reactions/{}",
60                self.channel_id, self.message_id, self.emoji
61            ))
62            .build()
63    }
64}
65
66#[derive(Builder, Copy, Clone, Debug)]
67pub struct AddReaction<'a> {
68    pub channel_id: Id<ChannelMarker>,
69    pub message_id: Id<MessageMarker>,
70    pub reaction: &'a RequestReactionType<'a>,
71}
72
73impl Endpoint for AddReaction<'_> {
74    type Response = ();
75    fn into_request(self) -> Request {
76        Request::builder()
77            .method(Method::PUT)
78            .path(format!(
79                "/channels/{}/messages/{}/reactions/{}/@me",
80                self.channel_id, self.message_id, self.reaction
81            ))
82            .build()
83    }
84}
85
86/// Delete the bot's own specified reaction from a message.
87#[derive(Builder, Copy, Clone, Debug)]
88pub struct DeleteOwnReaction<'a> {
89    pub channel_id: Id<ChannelMarker>,
90    pub message_id: Id<MessageMarker>,
91    pub reaction: &'a RequestReactionType<'a>,
92}
93
94impl Endpoint for DeleteOwnReaction<'_> {
95    type Response = ();
96
97    fn into_request(self) -> Request {
98        Request::builder()
99            .method(Method::DELETE)
100            .path(format!(
101                "/channels/{}/messages/{}/reactions/{}/@me",
102                self.channel_id, self.message_id, self.reaction
103            ))
104            .build()
105    }
106}
107
108/// Delete one specified reaction from a user on a message.
109#[derive(Builder, Copy, Clone, Debug)]
110pub struct DeleteReaction<'a> {
111    pub channel_id: Id<ChannelMarker>,
112    pub message_id: Id<MessageMarker>,
113    pub reaction: &'a RequestReactionType<'a>,
114    pub target: Id<UserMarker>,
115}
116
117impl Endpoint for DeleteReaction<'_> {
118    type Response = ();
119
120    fn into_request(self) -> Request {
121        Request::builder()
122            .method(Method::DELETE)
123            .path(format!(
124                "/channels/{}/messages/{}/reactions/{}/@{}",
125                self.channel_id, self.message_id, self.reaction, self.target
126            ))
127            .build()
128    }
129}
130
131/// Delete all reactions of a specified emoji from a message.
132#[derive(Builder, Copy, Clone, Debug)]
133pub struct DeleteAllReactionsOfEmoji<'a> {
134    pub channel_id: Id<ChannelMarker>,
135    pub message_id: Id<MessageMarker>,
136    pub reaction: &'a RequestReactionType<'a>,
137}
138
139impl Endpoint for DeleteAllReactionsOfEmoji<'_> {
140    type Response = ();
141
142    fn into_request(self) -> Request {
143        Request::builder()
144            .method(Method::DELETE)
145            .path(format!(
146                "/channels/{}/messages/{}/reactions/{}",
147                self.channel_id, self.message_id, self.reaction
148            ))
149            .build()
150    }
151}
152
153/// Delete all reactions from a message.
154#[derive(Builder, Copy, Clone, Debug)]
155pub struct DeleteAllReactions {
156    pub channel_id: Id<ChannelMarker>,
157    pub message_id: Id<MessageMarker>,
158}
159
160impl Endpoint for DeleteAllReactions {
161    type Response = ();
162
163    fn into_request(self) -> Request {
164        Request::builder()
165            .method(Method::DELETE)
166            .path(format!(
167                "/channels/{}/messages/{}/reactions",
168                self.channel_id, self.message_id
169            ))
170            .build()
171    }
172}