From de709e72a8e708a12eac5dbd2a92619d4fcef4a8 Mon Sep 17 00:00:00 2001 From: James Brown Date: Thu, 11 Jul 2019 17:51:19 -0700 Subject: [PATCH] implement deserialization for atomic integer types --- serde/src/de/impls.rs | 53 +++++++++++++++++++++++++ test_suite/tests/test_de.rs | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 1d4c3187..300abe34 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -2543,3 +2543,56 @@ where Deserialize::deserialize(deserializer).map(Wrapping) } } + +#[cfg(feature = "std")] +use std::sync::atomic; + + +#[cfg(feature = "std")] +macro_rules! atomic_impl { + ($ty:path, $primitive:ident) => { + impl<'de> Deserialize<'de> for $ty + { + #[inline] + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + let val = $primitive::deserialize(deserializer)?; + Ok(Self::new(val)) + } + } + } +} + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicBool, bool); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicI8, i8); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicI16, i16); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicI32, i32); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicI64, i64); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicIsize, isize); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicU8, u8); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicU16, u16); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicU32, u32); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicU64, u64); + +#[cfg(feature = "std")] +atomic_impl!(atomic::AtomicUsize, usize); diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 90e0f395..b96f1739 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -9,6 +9,7 @@ use std::num::Wrapping; use std::ops::Bound; use std::path::{Path, PathBuf}; use std::rc::{Rc, Weak as RcWeak}; +use std::sync::atomic; use std::sync::{Arc, Weak as ArcWeak}; use std::time::{Duration, UNIX_EPOCH}; @@ -1140,6 +1141,82 @@ fn test_never_type() { ); } + +macro_rules! assert_de_tokens_atomic { + ($ty:ty, $val:expr, $tokens:expr) => { + let mut de = serde_test::Deserializer::new($tokens); + match <$ty>::deserialize(&mut de) { + Ok(v) => { + let loaded = v.load(atomic::Ordering::SeqCst); + assert_eq!($val, loaded); + }, + Err(e) => panic!("tokens failed to deserialize: {}", e) + }; + if de.remaining() > 0 { + panic!("{} remaining tokens", de.remaining()); + } + } +} + +#[test] +fn test_atomics() { + assert_de_tokens_atomic!( + atomic::AtomicBool, + true, + &[Token::Bool(true)] + ); + assert_de_tokens_atomic!( + atomic::AtomicI8, + -127, + &[Token::I8(-127i8)] + ); + assert_de_tokens_atomic!( + atomic::AtomicI16, + -510, + &[Token::I16(-510i16)] + ); + assert_de_tokens_atomic!( + atomic::AtomicI32, + -131072, + &[Token::I32(-131072i32)] + ); + assert_de_tokens_atomic!( + atomic::AtomicI64, + -8589934592, + &[Token::I64(-8589934592)] + ); + assert_de_tokens_atomic!( + atomic::AtomicIsize, + -131072isize, + &[Token::I32(-131072)] + ); + assert_de_tokens_atomic!( + atomic::AtomicU8, + 127, + &[Token::U8(127u8)] + ); + assert_de_tokens_atomic!( + atomic::AtomicU16, + 510u16, + &[Token::U16(510u16)] + ); + assert_de_tokens_atomic!( + atomic::AtomicU32, + 131072u32, + &[Token::U32(131072u32)] + ); + assert_de_tokens_atomic!( + atomic::AtomicU64, + 8589934592u64, + &[Token::U64(8589934592)] + ); + assert_de_tokens_atomic!( + atomic::AtomicUsize, + 131072usize, + &[Token::U32(131072)] + ); +} + declare_error_tests! { test_unknown_field { &[