use crate::{DeserializeWith, Id};
use core::{fmt::Display, marker::PhantomData};
use serde::Deserializer;
pub struct TryFrom<T, F = Id> {
_convert: PhantomData<fn(T)>,
_f: PhantomData<F>,
}
impl<T, F> TryFrom<T, F> {
pub fn deserialize<'de, U, D>(deserializer: D) -> Result<U, D::Error>
where
D: Deserializer<'de>,
Self: DeserializeWith<'de, U>,
{
Self::deserialize_with(deserializer)
}
}
impl<'de, T, U, F> DeserializeWith<'de, U> for TryFrom<T, F>
where
U: core::convert::TryFrom<T>,
U::Error: Display,
F: DeserializeWith<'de, T>,
{
fn deserialize_with<D>(deserializer: D) -> Result<U, D::Error>
where
D: serde::Deserializer<'de>,
{
F::deserialize_with(deserializer)?
.try_into()
.map_err(serde::de::Error::custom)
}
}
#[cfg(test)]
mod tests {
use serde::Deserialize;
use serde_json::json;
#[derive(Debug, Deserialize)]
struct Foo(
#[allow(unused)]
#[serde(with = "crate::TryFrom::<u32>")]
char,
);
#[test]
fn try_from_adapter_fails_to_deserialize_if_conversion_fails() {
serde_json::from_value::<Foo>(json!(0xd800)).unwrap_err();
}
}