Skip to main content

twilight_http/request/guild/
get_audit_log.rs

1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture};
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::audit_log::{AuditLog, AuditLogEventType},
12    id::{
13        Id,
14        marker::{GuildMarker, UserMarker},
15    },
16};
17use twilight_validate::request::{
18    ValidationError, get_guild_audit_log_limit as validate_get_guild_audit_log_limit,
19};
20
21struct GetAuditLogFields {
22    action_type: Option<AuditLogEventType>,
23    after: Option<u64>,
24    before: Option<u64>,
25    limit: Option<u16>,
26    user_id: Option<Id<UserMarker>>,
27}
28
29/// Get the audit log for a guild.
30///
31/// # Examples
32///
33/// ```no_run
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("token".to_owned());
40///
41/// let guild_id = Id::new(101);
42/// let audit_log = client.audit_log(guild_id).await?.model().await?;
43///
44/// for entry in audit_log.entries {
45///     println!("ID: {}", entry.id);
46///     println!("  Action Type: {}", u16::from(entry.action_type));
47///     println!("  Changes:");
48///
49///     for change in entry.changes {
50///         println!("{change:?}");
51///     }
52/// }
53/// # Ok(()) }
54/// ```
55#[must_use = "requests must be configured and executed"]
56pub struct GetAuditLog<'a> {
57    fields: Result<GetAuditLogFields, ValidationError>,
58    guild_id: Id<GuildMarker>,
59    http: &'a Client,
60}
61
62impl<'a> GetAuditLog<'a> {
63    pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
64        Self {
65            fields: Ok(GetAuditLogFields {
66                action_type: None,
67                after: None,
68                before: None,
69                limit: None,
70                user_id: None,
71            }),
72            guild_id,
73            http,
74        }
75    }
76
77    /// Filter by an action type.
78    pub const fn action_type(mut self, action_type: AuditLogEventType) -> Self {
79        if let Ok(fields) = self.fields.as_mut() {
80            fields.action_type = Some(action_type);
81        }
82
83        self
84    }
85
86    /// Get audit log entries after the entry specified.
87    pub const fn after(mut self, after: u64) -> Self {
88        if let Ok(fields) = self.fields.as_mut() {
89            fields.after = Some(after);
90        }
91
92        self
93    }
94
95    /// Get audit log entries before the entry specified.
96    pub const fn before(mut self, before: u64) -> Self {
97        if let Ok(fields) = self.fields.as_mut() {
98            fields.before = Some(before);
99        }
100
101        self
102    }
103
104    /// Set the maximum number of audit logs to retrieve.
105    ///
106    /// The minimum is 1 and the maximum is 100.
107    ///
108    /// # Errors
109    ///
110    /// Returns an error of type [`GetGuildAuditLog`] if the `limit` is 0 or
111    /// greater than 100.
112    ///
113    /// [`GetGuildAuditLog`]: twilight_validate::request::ValidationErrorType::GetGuildAuditLog
114    pub fn limit(mut self, limit: u16) -> Self {
115        self.fields = self.fields.and_then(|mut fields| {
116            validate_get_guild_audit_log_limit(limit)?;
117            fields.limit = Some(limit);
118
119            Ok(fields)
120        });
121
122        self
123    }
124
125    /// Filter audit log for entries from a user.
126    ///
127    /// This is the user who did the auditable action, not the target of the auditable action.
128    pub const fn user_id(mut self, user_id: Id<UserMarker>) -> Self {
129        if let Ok(fields) = self.fields.as_mut() {
130            fields.user_id = Some(user_id);
131        }
132
133        self
134    }
135}
136
137#[cfg(not(target_os = "wasi"))]
138impl IntoFuture for GetAuditLog<'_> {
139    type Output = Result<Response<AuditLog>, Error>;
140
141    type IntoFuture = ResponseFuture<AuditLog>;
142
143    fn into_future(self) -> Self::IntoFuture {
144        let http = self.http;
145
146        match self.try_into_request() {
147            Ok(request) => http.request(request),
148            Err(source) => ResponseFuture::error(source),
149        }
150    }
151}
152
153impl TryIntoRequest for GetAuditLog<'_> {
154    fn try_into_request(self) -> Result<Request, Error> {
155        let fields = self.fields.map_err(Error::validation)?;
156
157        Ok(Request::from_route(&Route::GetAuditLogs {
158            action_type: fields.action_type.map(|x| u64::from(u16::from(x))),
159            after: fields.after,
160            before: fields.before,
161            guild_id: self.guild_id.get(),
162            limit: fields.limit,
163            user_id: fields.user_id.map(Id::get),
164        }))
165    }
166}