twilight_http/request/channel/reaction/
create_reaction.rs

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