use crate::{DeserializeWith, SerializeWith};
use core::{marker::PhantomData, ops::Deref};
use serde::{Deserializer, Serializer};
pub struct Ptr<F>(PhantomData<F>);
impl<F> Ptr<F> {
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: ?Sized,
S: Serializer,
Self: SerializeWith<T>,
{
Self::serialize_with(value, serializer)
}
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
Self: DeserializeWith<'de, T>,
{
Self::deserialize_with(deserializer)
}
}
impl<F, T> SerializeWith<T> for Ptr<F>
where
F: SerializeWith<T::Target>,
T: Deref + ?Sized,
{
fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
F::serialize_with(value, serializer)
}
}
impl<'de, F, T> DeserializeWith<'de, T> for Ptr<F>
where
F: DeserializeWith<'de, T::Target>,
T: Deref + From<T::Target>,
T::Target: Sized,
{
fn deserialize_with<D>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
{
F::deserialize_with(deserializer).map(Into::into)
}
}
#[cfg(all(feature = "std", test))]
mod tests {
use crate::test_utils::check_serialization;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::{rc::Rc, sync::Arc};
#[derive(Debug, Deserialize, PartialEq, Serialize)]
struct WrapBox(#[serde(with = "crate::Ptr::<crate::Str>")] Box<i32>);
#[test]
fn ptr_adapter_works_for_box() {
check_serialization(WrapBox(Box::new(33)), json!("33"));
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
struct WrapArc(#[serde(with = "crate::Ptr::<crate::Str>")] Arc<i32>);
#[test]
fn ptr_adapter_works_for_arc() {
check_serialization(WrapArc(Arc::new(33)), json!("33"));
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
struct WrapRc(#[serde(with = "crate::Ptr::<crate::Str>")] Rc<i32>);
#[test]
fn ptr_adapter_works_for_rc() {
check_serialization(WrapRc(Rc::new(33)), json!("33"));
}
}