diff options
| author | Adelyn Breedlove <[email protected]> | 2019-12-09 15:59:51 -0700 |
|---|---|---|
| committer | Adelyn Breedlove <[email protected]> | 2019-12-09 15:59:51 -0700 |
| commit | 45f1fb15bbd312920e3490c8ad26f3bce280efda (patch) | |
| tree | dded5a5bd093acacb2939a8280543b3a35963f7b /src | |
| parent | Add new auditlog type enums (diff) | |
| download | serenity-45f1fb15bbd312920e3490c8ad26f3bce280efda.tar.xz serenity-45f1fb15bbd312920e3490c8ad26f3bce280efda.zip | |
Patch auditlog deserialize to allow unknown fields
Diffstat (limited to 'src')
| -rw-r--r-- | src/model/guild/audit_log.rs | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/model/guild/audit_log.rs b/src/model/guild/audit_log.rs index 11fd283..0d25574 100644 --- a/src/model/guild/audit_log.rs +++ b/src/model/guild/audit_log.rs @@ -11,7 +11,8 @@ use super::super::prelude::*; use std::{ collections::HashMap, mem::transmute, - fmt + fmt, + error::Error, }; /// Determines to what entity an action was used on. @@ -434,6 +435,7 @@ impl<'de> Deserialize<'de> for AuditLogs { #[serde(rename = "audit_log_entries")] Entries, #[serde(rename = "webhooks")] Webhooks, #[serde(rename = "users")] Users, + // TODO(field added by Discord, undocumented) #[serde(rename = "integrations")] Integrations, } struct EntriesVisitor; @@ -450,29 +452,40 @@ impl<'de> Deserialize<'de> for AuditLogs { let mut users = None; let mut webhooks = None; - while let Some(field) = map.next_key()? { - match field { - Field::Entries => { + loop { + match map.next_key() { + Ok(Some(Field::Entries)) => { if audit_log_entries.is_some() { return Err(de::Error::duplicate_field("entries")); } audit_log_entries = Some(map.next_value::<Vec<AuditLogEntry>>()?); }, - Field::Webhooks => { + Ok(Some(Field::Webhooks)) => { if webhooks.is_some() { return Err(de::Error::duplicate_field("webhooks")); } webhooks = Some(map.next_value::<Vec<Webhook>>()?); }, - Field::Users => { + Ok(Some(Field::Users)) => { if users.is_some() { return Err(de::Error::duplicate_field("users")); } users = Some(map.next_value::<Vec<User>>()?); }, + Ok(None) => break, // No more keys + Err(e) => if e.description().contains("unknown field") { + // e is of type <V as MapAccess>::Error, which is a macro-defined trait, ultimately + // implemented by serde::de::value::Error. Seeing as every error is a simple string and not + // using a proper Error num, the best we can do here is to check if the string contains + // this error. This was added because Discord randomly started sending new fields. + // But no JSON deserializer should ever error over this. + map.next_value::<serde_json::Value>()?; // Actually read the value to avoid syntax errors + } else { + return Err(e) + } } } |