twilight_http/request/channel/message/
get_channel_messages.rs

1use super::GetChannelMessagesConfigured;
2use crate::{
3    client::Client,
4    error::Error,
5    request::{Request, TryIntoRequest},
6    response::{marker::ListBody, Response, ResponseFuture},
7    routing::Route,
8};
9use std::future::IntoFuture;
10use twilight_model::{
11    channel::Message,
12    id::{
13        marker::{ChannelMarker, MessageMarker},
14        Id,
15    },
16};
17use twilight_validate::request::{
18    get_channel_messages_limit as validate_get_channel_messages_limit, ValidationError,
19};
20
21struct GetChannelMessagesFields {
22    limit: Option<u16>,
23}
24
25/// Get channel messages, by [`Id<ChannelMarker>`].
26///
27/// Only one of [`after`], [`around`], and [`before`] can be specified at a time.
28/// Once these are specified, the type returned is [`GetChannelMessagesConfigured`].
29///
30/// If [`limit`] is unspecified, the default set by Discord is 50.
31///
32/// # Examples
33///
34/// ```no_run
35/// use twilight_http::Client;
36/// use twilight_model::id::Id;
37///
38/// # #[tokio::main]
39/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
40/// let client = Client::new("my token".to_owned());
41/// let channel_id = Id::new(123);
42/// let message_id = Id::new(234);
43///
44/// let messages = client
45///     .channel_messages(channel_id)
46///     .before(message_id)
47///     .limit(6u16)
48///     .await?;
49///
50/// # Ok(()) }
51/// ```
52///
53/// [`after`]: Self::after
54/// [`around`]: Self::around
55/// [`before`]: Self::before
56/// [`GetChannelMessagesConfigured`]: super::GetChannelMessagesConfigured
57/// [`limit`]: Self::limit
58#[must_use = "requests must be configured and executed"]
59pub struct GetChannelMessages<'a> {
60    channel_id: Id<ChannelMarker>,
61    fields: Result<GetChannelMessagesFields, ValidationError>,
62    http: &'a Client,
63}
64
65impl<'a> GetChannelMessages<'a> {
66    pub(crate) const fn new(http: &'a Client, channel_id: Id<ChannelMarker>) -> Self {
67        Self {
68            channel_id,
69            fields: Ok(GetChannelMessagesFields { limit: None }),
70            http,
71        }
72    }
73
74    pub fn after(self, message_id: Id<MessageMarker>) -> GetChannelMessagesConfigured<'a> {
75        GetChannelMessagesConfigured::new(
76            self.http,
77            self.channel_id,
78            Some(message_id),
79            None,
80            None,
81            self.fields.map(|fields| fields.limit),
82        )
83    }
84
85    pub fn around(self, message_id: Id<MessageMarker>) -> GetChannelMessagesConfigured<'a> {
86        GetChannelMessagesConfigured::new(
87            self.http,
88            self.channel_id,
89            None,
90            Some(message_id),
91            None,
92            self.fields.map(|fields| fields.limit),
93        )
94    }
95
96    pub fn before(self, message_id: Id<MessageMarker>) -> GetChannelMessagesConfigured<'a> {
97        GetChannelMessagesConfigured::new(
98            self.http,
99            self.channel_id,
100            None,
101            None,
102            Some(message_id),
103            self.fields.map(|fields| fields.limit),
104        )
105    }
106
107    /// Set the maximum number of messages to retrieve.
108    ///
109    /// The minimum is 1 and the maximum is 100.
110    ///
111    /// # Errors
112    ///
113    /// Returns an error of type [`GetChannelMessages`] error type if the amount
114    /// is less than 1 or greater than 100.
115    ///
116    /// [`GetChannelMessages`]: twilight_validate::request::ValidationErrorType::GetChannelMessages
117    pub fn limit(mut self, limit: u16) -> Self {
118        self.fields = self.fields.and_then(|mut fields| {
119            validate_get_channel_messages_limit(limit)?;
120            fields.limit = Some(limit);
121
122            Ok(fields)
123        });
124
125        self
126    }
127}
128
129impl IntoFuture for GetChannelMessages<'_> {
130    type Output = Result<Response<ListBody<Message>>, Error>;
131
132    type IntoFuture = ResponseFuture<ListBody<Message>>;
133
134    fn into_future(self) -> Self::IntoFuture {
135        let http = self.http;
136
137        match self.try_into_request() {
138            Ok(request) => http.request(request),
139            Err(source) => ResponseFuture::error(source),
140        }
141    }
142}
143
144impl TryIntoRequest for GetChannelMessages<'_> {
145    fn try_into_request(self) -> Result<Request, Error> {
146        let fields = self.fields.map_err(Error::validation)?;
147
148        Ok(Request::from_route(&Route::GetMessages {
149            after: None,
150            around: None,
151            before: None,
152            channel_id: self.channel_id.get(),
153            limit: fields.limit,
154        }))
155    }
156}