1use std::marker::PhantomData;
2
3use serde::{de::DeserializeSeed, Deserialize};
4
5pub trait DeserializeTyped<'de, T>: Sized {
6 fn deserialize_typed<S>(type_: &T, deserializer: S) -> Result<Self, S::Error>
7 where
8 S: serde::Deserializer<'de>;
9}
10
11impl<'de, T: Deserialize<'de>, C> DeserializeTyped<'de, C> for T {
12 fn deserialize_typed<S>(_: &C, deserializer: S) -> Result<Self, S::Error>
13 where
14 S: serde::Deserializer<'de>,
15 {
16 T::deserialize(deserializer)
17 }
18}
19
20pub struct WithType<'a, T, U>(&'a T, PhantomData<U>);
21
22impl<'a, T, U> WithType<'a, T, U> {
23 pub fn new(type_: &'a T) -> Self {
24 Self(type_, PhantomData)
25 }
26}
27
28impl<'de, T, U: DeserializeTyped<'de, T>> DeserializeSeed<'de> for WithType<'_, T, U> {
29 type Value = U;
30
31 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
32 where
33 D: serde::de::Deserializer<'de>,
34 {
35 U::deserialize_typed(self.0, deserializer)
36 }
37}
38
39pub trait DeserializeTypedOwned<T>: for<'de> DeserializeTyped<'de, T> {}
40impl<T, U> DeserializeTypedOwned<T> for U where U: for<'de> DeserializeTyped<'de, T> {}