twilight_http/request/guild/ban/
get_bans.rs

1use crate::{
2    client::Client,
3    error::Error,
4    request::{Request, TryIntoRequest},
5    response::{marker::ListBody, Response, ResponseFuture},
6    routing::Route,
7};
8use std::future::IntoFuture;
9use twilight_model::{
10    guild::Ban,
11    id::{
12        marker::{GuildMarker, UserMarker},
13        Id,
14    },
15};
16use twilight_validate::request::{
17    get_guild_bans_limit as validate_get_guild_bans_limit, ValidationError,
18};
19
20struct GetBansFields {
21    after: Option<Id<UserMarker>>,
22    before: Option<Id<UserMarker>>,
23    limit: Option<u16>,
24}
25
26/// Retrieve the bans for a guild.
27///
28/// # Examples
29///
30/// Retrieve the first 25 bans of a guild after a particular user ID:
31///
32/// ```no_run
33/// use std::env;
34/// use twilight_http::Client;
35/// use twilight_model::id::Id;
36///
37/// # #[tokio::main]
38/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
39/// let client = Client::new(env::var("DISCORD_TOKEN")?);
40///
41/// let guild_id = Id::new(1);
42/// let user_id = Id::new(2);
43///
44/// let response = client.bans(guild_id).after(user_id).limit(25).await?;
45/// let bans = response.models().await?;
46///
47/// for ban in bans {
48///     println!("{} was banned for: {:?}", ban.user.name, ban.reason);
49/// }
50/// # Ok(()) }
51/// ```
52#[must_use = "requests must be configured and executed"]
53pub struct GetBans<'a> {
54    fields: Result<GetBansFields, ValidationError>,
55    guild_id: Id<GuildMarker>,
56    http: &'a Client,
57}
58
59impl<'a> GetBans<'a> {
60    pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
61        Self {
62            fields: Ok(GetBansFields {
63                after: None,
64                before: None,
65                limit: None,
66            }),
67            guild_id,
68            http,
69        }
70    }
71
72    /// Set the user ID after which to retrieve bans.
73    ///
74    /// Mutually exclusive with [`before`]. If both are provided then [`before`]
75    /// is respected.
76    ///
77    /// [`before`]: Self::before
78    pub fn after(mut self, user_id: Id<UserMarker>) -> Self {
79        if let Ok(fields) = self.fields.as_mut() {
80            fields.after = Some(user_id);
81        }
82
83        self
84    }
85
86    /// Set the user ID before which to retrieve bans.
87    ///
88    /// Mutually exclusive with [`after`]. If both are provided then [`before`]
89    /// is respected.
90    ///
91    /// [`after`]: Self::after
92    /// [`before`]: Self::before
93    pub fn before(mut self, user_id: Id<UserMarker>) -> Self {
94        if let Ok(fields) = self.fields.as_mut() {
95            fields.before = Some(user_id);
96        }
97
98        self
99    }
100
101    /// Set the maximum number of bans to retrieve.
102    ///
103    /// Defaults to Discord's default.
104    ///
105    /// Refer to [Discord Docs/Get Guild Bans] for more information.
106    ///
107    /// # Errors
108    ///
109    /// Returns an error of type [`GetGuildBans`] if the limit is invalid.
110    ///
111    /// [`GetGuildBans`]: twilight_validate::request::ValidationErrorType::GetGuildBans
112    pub fn limit(mut self, limit: u16) -> Self {
113        self.fields = self.fields.and_then(|mut fields| {
114            validate_get_guild_bans_limit(limit)?;
115            fields.limit.replace(limit);
116
117            Ok(fields)
118        });
119
120        self
121    }
122}
123
124impl IntoFuture for GetBans<'_> {
125    type Output = Result<Response<ListBody<Ban>>, Error>;
126
127    type IntoFuture = ResponseFuture<ListBody<Ban>>;
128
129    fn into_future(self) -> Self::IntoFuture {
130        let http = self.http;
131
132        match self.try_into_request() {
133            Ok(request) => http.request(request),
134            Err(source) => ResponseFuture::error(source),
135        }
136    }
137}
138
139impl TryIntoRequest for GetBans<'_> {
140    fn try_into_request(self) -> Result<Request, Error> {
141        let fields = self.fields.map_err(Error::validation)?;
142
143        Ok(Request::from_route(&Route::GetBansWithParameters {
144            after: fields.after.map(Id::get),
145            before: fields.before.map(Id::get),
146            limit: fields.limit,
147            guild_id: self.guild_id.get(),
148        }))
149    }
150}