Skip to main content

twilight_http/request/channel/reaction/
create_reaction.rs

1use super::RequestReactionType;
2#[cfg(not(target_os = "wasi"))]
3use crate::response::{Response, ResponseFuture, marker::EmptyBody};
4use crate::{
5    client::Client,
6    error::Error,
7    request::{Request, TryIntoRequest},
8    routing::Route,
9};
10use std::future::IntoFuture;
11use twilight_model::id::{
12    Id,
13    marker::{ChannelMarker, MessageMarker},
14};
15
16/// Create a reaction in a [`Id<ChannelMarker>`] on a [`Id<MessageMarker>`].
17///
18/// The reaction must be a variant of [`RequestReactionType`].
19///
20/// # Examples
21/// ```no_run
22/// use twilight_http::{Client, request::channel::reaction::RequestReactionType};
23/// use twilight_model::id::Id;
24///
25/// # #[tokio::main]
26/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
27/// let client = Client::new("my token".to_owned());
28///
29/// let channel_id = Id::new(123);
30/// let message_id = Id::new(456);
31/// let emoji = RequestReactionType::Unicode { name: "🌃" };
32///
33/// let reaction = client
34///     .create_reaction(channel_id, message_id, &emoji)
35///     .await?;
36/// # Ok(()) }
37/// ```
38#[must_use = "requests must be configured and executed"]
39pub struct CreateReaction<'a> {
40    channel_id: Id<ChannelMarker>,
41    emoji: &'a RequestReactionType<'a>,
42    http: &'a Client,
43    message_id: Id<MessageMarker>,
44}
45
46impl<'a> CreateReaction<'a> {
47    pub(crate) const fn new(
48        http: &'a Client,
49        channel_id: Id<ChannelMarker>,
50        message_id: Id<MessageMarker>,
51        emoji: &'a RequestReactionType<'a>,
52    ) -> Self {
53        Self {
54            channel_id,
55            emoji,
56            http,
57            message_id,
58        }
59    }
60}
61
62#[cfg(not(target_os = "wasi"))]
63impl IntoFuture for CreateReaction<'_> {
64    type Output = Result<Response<EmptyBody>, Error>;
65
66    type IntoFuture = ResponseFuture<EmptyBody>;
67
68    fn into_future(self) -> Self::IntoFuture {
69        let http = self.http;
70
71        match self.try_into_request() {
72            Ok(request) => http.request(request),
73            Err(source) => ResponseFuture::error(source),
74        }
75    }
76}
77
78impl TryIntoRequest for CreateReaction<'_> {
79    fn try_into_request(self) -> Result<Request, Error> {
80        Ok(Request::from_route(&Route::CreateReaction {
81            channel_id: self.channel_id.get(),
82            emoji: self.emoji,
83            message_id: self.message_id.get(),
84        }))
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    #![allow(clippy::non_ascii_literal)]
91
92    use super::CreateReaction;
93    use crate::{
94        Client,
95        request::{Request, TryIntoRequest, channel::reaction::RequestReactionType},
96        routing::Route,
97    };
98    use std::error::Error;
99    use twilight_model::id::Id;
100
101    #[test]
102    fn request() -> Result<(), Box<dyn Error>> {
103        let client = Client::new("foo".to_owned());
104
105        let emoji = RequestReactionType::Unicode { name: "🌃" };
106
107        let builder = CreateReaction::new(&client, Id::new(123), Id::new(456), &emoji);
108        let actual = builder.try_into_request()?;
109
110        let expected = Request::from_route(&Route::CreateReaction {
111            channel_id: 123,
112            emoji: &RequestReactionType::Unicode { name: "🌃" },
113            message_id: 456,
114        });
115
116        assert_eq!(actual.path, expected.path);
117
118        Ok(())
119    }
120}