From 6aeea4da70da26631533b27052133f3620cebc5a Mon Sep 17 00:00:00 2001 From: Zeyla Hellyer Date: Mon, 24 Apr 2017 22:51:22 -0700 Subject: Fix deserialization for Ids Attempt to deserialize from both a str and a u64 instead of the default derive impl. --- src/model/channel/mod.rs | 2 ++ src/model/mod.rs | 10 +++++++++- src/model/utils.rs | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/model/channel/mod.rs b/src/model/channel/mod.rs index 6600dc7..09cf70a 100644 --- a/src/model/channel/mod.rs +++ b/src/model/channel/mod.rs @@ -20,6 +20,7 @@ use serde::de::Error as DeError; use serde_json; use std::fmt::{Display, Formatter, Result as FmtResult}; use std::io::Read; +use super::utils::deserialize_u64; use ::model::*; use ::utils::builder::{CreateMessage, GetMessages}; @@ -438,6 +439,7 @@ impl ChannelType { struct PermissionOverwriteData { allow: Permissions, deny: Permissions, + #[serde(deserialize_with="deserialize_u64")] id: u64, #[serde(rename="type")] kind: String, diff --git a/src/model/mod.rs b/src/model/mod.rs index f464242..e51970d 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -39,7 +39,9 @@ pub use self::voice::*; pub use self::webhook::*; use self::utils::*; +use serde::de::Visitor; use std::collections::HashMap; +use std::fmt::{Formatter, Result as FmtResult}; use std::sync::{Arc, RwLock}; use time::Timespec; use ::internal::prelude::*; @@ -51,7 +53,7 @@ macro_rules! id { ($(#[$attr:meta] $name:ident;)*) => { $( #[$attr] - #[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialOrd, Ord, Serialize)] + #[derive(Copy, Clone, Debug, Eq, Hash, PartialOrd, Ord, Serialize)] #[allow(derive_hash_xor_eq)] pub struct $name(pub u64); @@ -81,6 +83,12 @@ macro_rules! id { self.0 == *u } } + + impl<'de> Deserialize<'de> for $name { + fn deserialize>(deserializer: D) -> StdResult { + deserializer.deserialize_u64(U64Visitor).map($name) + } + } )* } } diff --git a/src/model/utils.rs b/src/model/utils.rs index 68a6e1c..309b9de 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -115,6 +115,11 @@ pub fn deserialize_users<'de, D: Deserializer<'de>>(deserializer: D) Ok(users) } +pub fn deserialize_u64<'de, D: Deserializer<'de>>(deserializer: D) + -> StdResult { + deserializer.deserialize_u64(U64Visitor) +} + pub fn deserialize_voice_states<'de, D: Deserializer<'de>>(deserializer: D) -> StdResult, D::Error> { let vec: Vec = Deserialize::deserialize(deserializer)?; @@ -155,3 +160,37 @@ pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Re Ok(permissions.is_empty()) } + + +pub struct U64Visitor; + +impl<'de> Visitor<'de> for U64Visitor { + type Value = u64; + + fn expecting(&self, formatter: &mut Formatter) -> FmtResult { + formatter.write_str("identifier") + } + + fn visit_str(self, v: &str) -> StdResult { + match v.parse::() { + Ok(v) => Ok(v), + Err(_) => { + let mut s = String::new(); + s.push_str("Unknown "); + s.push_str(stringify!($name)); + s.push_str(" value: "); + s.push_str(v); + + Err(DeError::custom(s)) + }, + } + } + + fn visit_i64(self, v: i64) -> StdResult { + Ok(v as u64) + } + + fn visit_u64(self, v: u64) -> StdResult { + Ok(v) + } +} -- cgit v1.2.3