field_helpers.rs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //! Modules that help with serializing and deserializing struct fields via the
  2. //! `#[serde(with ="path")]` attribute.
  3. use serde::{Deserialize, Deserializer, Serialize, Serializer};
  4. /// A helper for serializing and deserializing fields which are "smart pointers", types like
  5. /// [std::sync::Arc], [std::rc::Rc], and [Box].
  6. pub mod smart_ptr {
  7. use super::*;
  8. use std::{ops::Deref, rc::Rc, sync::Arc};
  9. /// Trait for general smart pointers.
  10. pub trait SmartPtr: Deref {
  11. /// Creates a new pointer which points to the given target.
  12. fn new(inner: Self::Target) -> Self;
  13. }
  14. macro_rules! impl_smart_ptr {
  15. ($ptr:ident) => {
  16. impl<T> SmartPtr for $ptr<T> {
  17. fn new(inner: Self::Target) -> Self {
  18. $ptr::new(inner)
  19. }
  20. }
  21. };
  22. }
  23. impl_smart_ptr!(Arc);
  24. impl_smart_ptr!(Box);
  25. impl_smart_ptr!(Rc);
  26. pub fn serialize<P, T, S>(field: &P, ser: S) -> Result<S::Ok, S::Error>
  27. where
  28. P: SmartPtr<Target = T>,
  29. T: ?Sized + Serialize,
  30. S: Serializer,
  31. {
  32. field.deref().serialize(ser)
  33. }
  34. pub fn deserialize<'de, P, T, D>(de: D) -> Result<P, D::Error>
  35. where
  36. P: SmartPtr<Target = T>,
  37. T: ?Sized + Deserialize<'de>,
  38. D: Deserializer<'de>,
  39. {
  40. Ok(P::new(T::deserialize(de)?))
  41. }
  42. }
  43. #[cfg(test)]
  44. mod smart_ptr_tests {
  45. use crate::{from_vec, to_vec};
  46. use paste::paste;
  47. use serde::{Deserialize, Serialize};
  48. use std::{rc::Rc, sync::Arc};
  49. use super::smart_ptr::{self, SmartPtr};
  50. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
  51. struct Test<P: SmartPtr<Target = String>> {
  52. #[serde(with = "smart_ptr")]
  53. field: P,
  54. }
  55. impl<P: SmartPtr<Target = String>> Test<P> {
  56. fn new(expected: &str) -> Self {
  57. Test {
  58. field: P::new(expected.to_string()),
  59. }
  60. }
  61. }
  62. macro_rules! check_ptr {
  63. ($ptr:ty) => {
  64. paste! {
  65. #[test]
  66. fn [<"check_" $ptr:lower>]() {
  67. let expected = Test::new("expected");
  68. let actual: Test<$ptr<String>> = from_vec(&to_vec(&expected).unwrap()).unwrap();
  69. assert_eq!(expected, actual);
  70. }
  71. }
  72. };
  73. }
  74. check_ptr!(Arc);
  75. check_ptr!(Box);
  76. check_ptr!(Rc);
  77. }