From 6cd1aac5589f0520ab65ba84326baa0dff84827a Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 6 Aug 2020 11:16:04 +0200 Subject: [PATCH] add serde forwarding convenience macros * forward_deserialize_to_from_str * forward_serialize_to_display Signed-off-by: Wolfgang Bumiller --- proxmox/src/lib.rs | 3 +++ proxmox/src/serde_macros.rs | 44 +++++++++++++++++++++++++++++++++++++ proxmox/src/tools/uuid.rs | 28 ++--------------------- 3 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 proxmox/src/serde_macros.rs diff --git a/proxmox/src/lib.rs b/proxmox/src/lib.rs index c71cc705..b74b3997 100644 --- a/proxmox/src/lib.rs +++ b/proxmox/src/lib.rs @@ -1,6 +1,9 @@ //! Proxmox "tools" package containing some generic tools along with the schema, API and CLI //! helpers. +#[macro_use] +pub mod serde_macros; + pub mod api; pub mod sys; pub mod tools; diff --git a/proxmox/src/serde_macros.rs b/proxmox/src/serde_macros.rs new file mode 100644 index 00000000..a730733a --- /dev/null +++ b/proxmox/src/serde_macros.rs @@ -0,0 +1,44 @@ +#[macro_export] +macro_rules! forward_deserialize_to_from_str { + ($typename:ty) => { + impl<'de> serde::Deserialize<'de> for $typename { + fn deserialize(deserializer: D) -> Result<$typename, D::Error> + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + struct ForwardToStrVisitor; + + impl<'a> serde::de::Visitor<'a> for ForwardToStrVisitor { + type Value = $typename; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str(concat!("a ", stringify!($typename))) + } + + fn visit_str(self, v: &str) -> Result<$typename, E> { + v.parse::<$typename>() + .map_err(|err| Error::custom(err.to_string())) + } + } + + deserializer.deserialize_str(ForwardToStrVisitor) + } + } + } +} + +#[macro_export] +macro_rules! forward_serialize_to_display { + ($typename:ty) => { + impl serde::Serialize for $typename { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&ToString::to_string(self)) + } + } + } +} diff --git a/proxmox/src/tools/uuid.rs b/proxmox/src/tools/uuid.rs index 49490455..8275e431 100644 --- a/proxmox/src/tools/uuid.rs +++ b/proxmox/src/tools/uuid.rs @@ -4,7 +4,7 @@ use std::borrow::{Borrow, BorrowMut}; use std::fmt; use anyhow::{bail, Error}; -use serde::{Deserialize, Serialize, Serializer, Deserializer}; +use serde::{Serialize, Serializer}; use crate::tools::parse::hex_nibble; @@ -207,31 +207,7 @@ impl Serialize for Uuid { } } -impl<'de> Deserialize<'de> for Uuid { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - use serde::de::{Error, Visitor}; - - struct UuidVisitor; - - impl<'a> Visitor<'a> for UuidVisitor { - type Value = Uuid; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a uuid") - } - - fn visit_str(self, v: &str) -> Result { - v.parse::() - .map_err(|err| Error::custom(err.to_string())) - } - } - - deserializer.deserialize_str(UuidVisitor) - } -} +forward_deserialize_to_from_str!(Uuid); #[test] fn test_uuid() {