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