Skip to main content

twilight_http/request/guild/ban/
get_bans.rs

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