| use crate::{ArcSwapAny, RefCnt, Strategy}; |
| use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
| |
| impl<T, S> Serialize for ArcSwapAny<T, S> |
| where |
| T: RefCnt + Serialize, |
| S: Strategy<T>, |
| { |
| fn serialize<Ser: Serializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> { |
| self.load().serialize(serializer) |
| } |
| } |
| |
| impl<'de, T, S> Deserialize<'de> for ArcSwapAny<T, S> |
| where |
| T: RefCnt + Deserialize<'de>, |
| S: Strategy<T> + Default, |
| { |
| fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { |
| Ok(Self::from(T::deserialize(deserializer)?)) |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use crate::{ArcSwap, ArcSwapAny, ArcSwapOption, RefCnt}; |
| use serde_derive::{Deserialize, Serialize}; |
| use serde_test::{assert_tokens, Token}; |
| use std::sync::Arc; |
| |
| #[derive(Debug, Serialize, Deserialize)] |
| #[serde(transparent)] |
| struct ArcSwapAnyEq<T: RefCnt>(ArcSwapAny<T>); |
| impl<T: RefCnt + PartialEq> PartialEq for ArcSwapAnyEq<T> { |
| fn eq(&self, other: &Self) -> bool { |
| self.0.load().eq(&other.0.load()) |
| } |
| } |
| impl<T: RefCnt + PartialEq> Eq for ArcSwapAnyEq<T> {} |
| |
| #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] |
| struct Foo { |
| field0: u64, |
| field1: String, |
| } |
| |
| #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] |
| struct Bar { |
| field0: ArcSwapAnyEq<Arc<u64>>, |
| field1: ArcSwapAnyEq<Option<Arc<String>>>, |
| } |
| |
| #[test] |
| fn test_serialize_deserialize() { |
| let field0 = u64::MAX; |
| let field1 = "FOO_-0123456789"; |
| |
| let data_orig = Foo { |
| field0, |
| field1: field1.to_string(), |
| }; |
| let data = ArcSwapAnyEq(ArcSwap::from_pointee(data_orig)); |
| assert_tokens( |
| &data, |
| &[ |
| Token::Struct { |
| name: "Foo", |
| len: 2, |
| }, |
| Token::Str("field0"), |
| Token::U64(u64::MAX), |
| Token::Str("field1"), |
| Token::String(field1), |
| Token::StructEnd, |
| ], |
| ); |
| |
| let data = Bar { |
| field0: ArcSwapAnyEq(ArcSwap::from_pointee(field0)), |
| field1: ArcSwapAnyEq(ArcSwapOption::from_pointee(field1.to_string())), |
| }; |
| assert_tokens( |
| &data, |
| &[ |
| Token::Struct { |
| name: "Bar", |
| len: 2, |
| }, |
| Token::Str("field0"), |
| Token::U64(u64::MAX), |
| Token::Str("field1"), |
| Token::Some, |
| Token::String(field1), |
| Token::StructEnd, |
| ], |
| ); |
| } |
| |
| #[test] |
| fn test_serialize_deserialize_option() { |
| let field0 = u64::MAX; |
| let field1 = "FOO_-0123456789"; |
| |
| let data_orig = Foo { |
| field0, |
| field1: field1.to_string(), |
| }; |
| let data = ArcSwapAnyEq(ArcSwapOption::from_pointee(data_orig)); |
| assert_tokens( |
| &data, |
| &[ |
| Token::Some, |
| Token::Struct { |
| name: "Foo", |
| len: 2, |
| }, |
| Token::Str("field0"), |
| Token::U64(u64::MAX), |
| Token::Str("field1"), |
| Token::String(field1), |
| Token::StructEnd, |
| ], |
| ); |
| } |
| |
| #[test] |
| fn test_serialize_deserialize_option_none() { |
| let data = ArcSwapAnyEq(ArcSwapOption::<Foo>::from_pointee(None)); |
| |
| assert_tokens(&data, &[Token::None]); |
| } |
| } |