use crate::{Signature, Type};
use serde::de::{Deserialize, DeserializeSeed};
use std::marker::PhantomData;
pub trait DynamicType {
fn signature(&self) -> Signature;
}
pub trait DynamicDeserialize<'de>: DynamicType {
type Deserializer: DeserializeSeed<'de, Value = Self> + DynamicType;
fn deserializer_for_signature(signature: &Signature) -> zvariant::Result<Self::Deserializer>;
}
impl<T> DynamicType for T
where
T: Type + ?Sized,
{
fn signature(&self) -> Signature {
<T as Type>::SIGNATURE.clone()
}
}
impl<'de, T> DynamicDeserialize<'de> for T
where
T: Type + Deserialize<'de>,
{
type Deserializer = PhantomData<T>;
fn deserializer_for_signature(signature: &Signature) -> zvariant::Result<Self::Deserializer> {
let expected = <T as Type>::SIGNATURE;
if expected != signature {
match expected {
Signature::Structure(fields)
if fields.len() == 1 && fields.iter().next().unwrap() == signature =>
{
}
_ => {
return Err(zvariant::Error::SignatureMismatch(
signature.clone(),
format!("`{expected}`"),
));
}
}
}
Ok(PhantomData)
}
}