twilight_http/request/channel/
get_pins.rs

1use crate::{
2    client::Client,
3    error::Error,
4    request::{Request, TryIntoRequest},
5    response::{Response, ResponseFuture},
6    routing::Route,
7};
8use std::future::IntoFuture;
9use twilight_model::channel::message::PinsListing;
10use twilight_model::id::{Id, marker::ChannelMarker};
11use twilight_model::util::Timestamp;
12use twilight_validate::request::{ValidationError, pin_limit as validate_pin_limit};
13
14pub struct GetPinsQueryFields {
15    before: Option<Timestamp>,
16    limit: Option<u16>,
17}
18
19/// Get the pins of a channel.
20#[must_use = "requests must be configured and executed"]
21pub struct GetPins<'a> {
22    channel_id: Id<ChannelMarker>,
23    fields: Result<GetPinsQueryFields, ValidationError>,
24    http: &'a Client,
25}
26
27impl<'a> GetPins<'a> {
28    pub(crate) const fn new(http: &'a Client, channel_id: Id<ChannelMarker>) -> Self {
29        Self {
30            channel_id,
31            fields: Ok(GetPinsQueryFields {
32                before: None,
33                limit: None,
34            }),
35            http,
36        }
37    }
38
39    /// Sets the timestamp filter to only retrieve pins before the provided timestamp.
40    ///
41    /// [docs]
42    ///
43    /// [docs]: https://discord.com/developers/docs/resources/message#get-channel-pins-query-string-params
44    pub const fn before(mut self, timestamp: Timestamp) -> Self {
45        if let Ok(fields) = self.fields.as_mut() {
46            fields.before = Some(timestamp);
47        }
48
49        self
50    }
51
52    /// Sets the limit of pins to retrieve in this request. (1-50) (default: 50)
53    ///
54    /// [docs]
55    ///
56    /// [docs]: https://discord.com/developers/docs/resources/message#get-channel-pins-query-string-params
57    pub fn limit(mut self, limit: u16) -> Self {
58        self.fields = self.fields.and_then(|mut fields| {
59            validate_pin_limit(limit)?;
60
61            fields.limit = Some(limit);
62
63            Ok(fields)
64        });
65
66        self
67    }
68}
69
70impl IntoFuture for GetPins<'_> {
71    type Output = Result<Response<PinsListing>, Error>;
72
73    type IntoFuture = ResponseFuture<PinsListing>;
74
75    fn into_future(self) -> Self::IntoFuture {
76        let http = self.http;
77
78        match self.try_into_request() {
79            Ok(request) => http.request(request),
80            Err(source) => ResponseFuture::error(source),
81        }
82    }
83}
84
85impl TryIntoRequest for GetPins<'_> {
86    fn try_into_request(self) -> Result<Request, Error> {
87        let fields = self.fields.map_err(Error::validation)?;
88
89        Ok(Request::from_route(&Route::GetPins {
90            channel_id: self.channel_id.get(),
91            limit: fields.limit,
92            before: fields.before.map(|t| t.iso_8601().to_string()),
93        }))
94    }
95}