From 9caa31d499173a427f9294500ba934594f0fc747 Mon Sep 17 00:00:00 2001 From: Kosta Date: Mon, 9 Mar 2020 23:46:49 +0100 Subject: [PATCH 1/3] (De)serializing any type from a (de)serializable type I found myself relying on this trick again today but couldn't find it documented anywhere. It kind of follows from the design of serde, but I suspect there are a lot of users that are not aware of this and might do something more complicated, e.g. implement a Visitor like described in the docs. --- ...izing_any_type_from_deserializable_type.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 _src/Deserializing_any_type_from_deserializable_type.md diff --git a/_src/Deserializing_any_type_from_deserializable_type.md b/_src/Deserializing_any_type_from_deserializable_type.md new file mode 100644 index 00000000..3cde766f --- /dev/null +++ b/_src/Deserializing_any_type_from_deserializable_type.md @@ -0,0 +1,25 @@ +# (De)serializing any type from a (de)serializable type + +Sometime it's practical to (de)serialize a field of a type that does not implement (de)serialize itself from a field that does. + +Example: + +```rust +use std::sync::atomic::AtomicU64; +use serde::Deserializer; + +fn deserialize_atomic_u64<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { + // Note: Option implements Deserialize, so we can just tell serde to deserialize an Option and use the result + let value = Option::::deserialize(deserializer)?; + AtomicU64::new(value.unwrap_or_default()) +} + +# #[allow(dead_code)] +struct Foo { + // Note: the same trick works for serialize_with as well + #[serde(deserialize_with="deserialize_atomic_u64")] + atomic: AtomicU64, +} +# +# fn main() {} +``` From 0e4747b6c9968fbbd00f9678a406b302681a5a40 Mon Sep 17 00:00:00 2001 From: Kosta Welke Date: Tue, 10 Mar 2020 00:01:58 +0100 Subject: [PATCH 2/3] fix build --- _src/Deserializing_any_type_from_deserializable_type.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_src/Deserializing_any_type_from_deserializable_type.md b/_src/Deserializing_any_type_from_deserializable_type.md index 3cde766f..81dff4ce 100644 --- a/_src/Deserializing_any_type_from_deserializable_type.md +++ b/_src/Deserializing_any_type_from_deserializable_type.md @@ -6,9 +6,9 @@ Example: ```rust use std::sync::atomic::AtomicU64; -use serde::Deserializer; +use serde::{Deserialize, Deserializer}; -fn deserialize_atomic_u64<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { +fn deserialize_atomic_u64<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { // Note: Option implements Deserialize, so we can just tell serde to deserialize an Option and use the result let value = Option::::deserialize(deserializer)?; AtomicU64::new(value.unwrap_or_default()) From 2c56b5de0185c76950b0054fc72d4156f99e4f93 Mon Sep 17 00:00:00 2001 From: Kosta Welke Date: Tue, 10 Mar 2020 00:07:16 +0100 Subject: [PATCH 3/3] fix build: correct return type --- _src/Deserializing_any_type_from_deserializable_type.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_src/Deserializing_any_type_from_deserializable_type.md b/_src/Deserializing_any_type_from_deserializable_type.md index 81dff4ce..786a35d7 100644 --- a/_src/Deserializing_any_type_from_deserializable_type.md +++ b/_src/Deserializing_any_type_from_deserializable_type.md @@ -11,7 +11,7 @@ use serde::{Deserialize, Deserializer}; fn deserialize_atomic_u64<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { // Note: Option implements Deserialize, so we can just tell serde to deserialize an Option and use the result let value = Option::::deserialize(deserializer)?; - AtomicU64::new(value.unwrap_or_default()) + Ok(AtomicU64::new(value.unwrap_or_default())) } # #[allow(dead_code)]