From ac57deea11ef6c5bc4d10ee1778226317b7325cb Mon Sep 17 00:00:00 2001 From: Alvaro Muhlethaler Date: Sat, 23 Apr 2022 13:32:17 +0200 Subject: [PATCH] Deserialize Bucket retention policy from String to u64 --- google-cloud/src/deserializer/mod.rs | 39 ++++++++++++++++++++++++++ google-cloud/src/lib.rs | 2 ++ google-cloud/src/storage/api/bucket.rs | 8 ++++-- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 google-cloud/src/deserializer/mod.rs diff --git a/google-cloud/src/deserializer/mod.rs b/google-cloud/src/deserializer/mod.rs new file mode 100644 index 00000000..e5b32c79 --- /dev/null +++ b/google-cloud/src/deserializer/mod.rs @@ -0,0 +1,39 @@ +use std::fmt; +use serde::de::{self, Unexpected}; +use serde::Deserializer; + +pub fn deserialize_u64_or_string<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, +{ + deserializer.deserialize_any(DeserializeU64OrStringVisitor) +} + +struct DeserializeU64OrStringVisitor; +impl<'de> de::Visitor<'de> for DeserializeU64OrStringVisitor { + type Value = u64; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an integer or a string") + } + + fn visit_u64(self, v: u64) -> Result + where + E: de::Error, + { + Ok(v) + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + if let Ok(n) = v.parse::() { + Ok(n) + } else if v.is_empty() { + Ok(0) + } else { + Err(E::invalid_value(Unexpected::Str(v), &self)) + } + } +} diff --git a/google-cloud/src/lib.rs b/google-cloud/src/lib.rs index b40efdc2..c205be4a 100644 --- a/google-cloud/src/lib.rs +++ b/google-cloud/src/lib.rs @@ -8,6 +8,8 @@ extern crate google_cloud_derive; pub mod authorize; /// Error handling utilities. pub mod error; +/// Complements serde deserializers. +pub mod deserializer; /// Datastore bindings. #[cfg(feature = "datastore")] diff --git a/google-cloud/src/storage/api/bucket.rs b/google-cloud/src/storage/api/bucket.rs index 397e75ae..cd21b421 100644 --- a/google-cloud/src/storage/api/bucket.rs +++ b/google-cloud/src/storage/api/bucket.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::storage::api::bucket_acl::BucketAclResource; use crate::storage::api::object_acl::ObjectAclResource; +use crate::deserializer::deserialize_u64_or_string; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -49,9 +50,10 @@ pub struct BucketResource { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BucketRetentionPolicy { - pub pubretention_period: u64, - pub pubeffective_time: String, - pub pubis_locked: bool, + #[serde(deserialize_with = "deserialize_u64_or_string")] + pub retention_period: u64, + pub effective_time: String, + pub is_locked: bool, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]