12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- //! Modules that help with serializing and deserializing struct fields via the
- //! `#[serde(with ="path")]` attribute.
- use serde::{Deserialize, Deserializer, Serialize, Serializer};
- /// A helper for serializing and deserializing fields which are "smart pointers", types like
- /// [std::sync::Arc], [std::rc::Rc], and [Box].
- pub mod smart_ptr {
- use super::*;
- use std::{ops::Deref, rc::Rc, sync::Arc};
- /// Trait for general smart pointers.
- pub trait SmartPtr: Deref {
- /// Creates a new pointer which points to the given target.
- fn new(inner: Self::Target) -> Self;
- }
- macro_rules! impl_smart_ptr {
- ($ptr:ident) => {
- impl<T> SmartPtr for $ptr<T> {
- fn new(inner: Self::Target) -> Self {
- $ptr::new(inner)
- }
- }
- };
- }
- impl_smart_ptr!(Arc);
- impl_smart_ptr!(Box);
- impl_smart_ptr!(Rc);
- pub fn serialize<P, T, S>(field: &P, ser: S) -> Result<S::Ok, S::Error>
- where
- P: SmartPtr<Target = T>,
- T: ?Sized + Serialize,
- S: Serializer,
- {
- field.deref().serialize(ser)
- }
- pub fn deserialize<'de, P, T, D>(de: D) -> Result<P, D::Error>
- where
- P: SmartPtr<Target = T>,
- T: ?Sized + Deserialize<'de>,
- D: Deserializer<'de>,
- {
- Ok(P::new(T::deserialize(de)?))
- }
- }
- #[cfg(test)]
- mod smart_ptr_tests {
- use crate::{from_vec, to_vec};
- use paste::paste;
- use serde::{Deserialize, Serialize};
- use std::{rc::Rc, sync::Arc};
- use super::smart_ptr::{self, SmartPtr};
- #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
- struct Test<P: SmartPtr<Target = String>> {
- #[serde(with = "smart_ptr")]
- field: P,
- }
- impl<P: SmartPtr<Target = String>> Test<P> {
- fn new(expected: &str) -> Self {
- Test {
- field: P::new(expected.to_string()),
- }
- }
- }
- macro_rules! check_ptr {
- ($ptr:ty) => {
- paste! {
- #[test]
- fn [<"check_" $ptr:lower>]() {
- let expected = Test::new("expected");
- let actual: Test<$ptr<String>> = from_vec(&to_vec(&expected).unwrap()).unwrap();
- assert_eq!(expected, actual);
- }
- }
- };
- }
- check_ptr!(Arc);
- check_ptr!(Box);
- check_ptr!(Rc);
- }
|