use super::SerializedValue;
use crate::tags::{PrimaryTag, Tag};
use crate::{Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, Serializer};
#[test]
fn concrete_vs_vague() {
#[derive(Debug, PartialEq, Eq)]
struct Type<T1, T2> {
field1: T1,
field2: T2,
}
impl<T1: Tag, T2: Tag> Tag for Type<T1, T2> {}
impl<T1: PrimaryTag, T2: PrimaryTag> PrimaryTag for Type<T1, T2> {
type Tag = Type<T1::Tag, T2::Tag>;
}
impl<T1, U1, T2, U2> Serialize<Type<T1, T2>> for Type<U1, U2>
where
T1: Tag,
U1: Serialize<T1>,
T2: Tag,
U2: Serialize<T2>,
{
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
let mut serializer = serializer.serialize_struct2()?;
serializer.serialize(1u32, self.field1)?;
serializer.serialize(2u32, self.field2)?;
serializer.finish()
}
}
impl<'a, T1, U1, T2, U2> Serialize<Type<T1, T2>> for &'a Type<U1, U2>
where
T1: Tag,
&'a U1: Serialize<T1>,
T2: Tag,
&'a U2: Serialize<T2>,
{
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
let mut serializer = serializer.serialize_struct2()?;
serializer.serialize(1u32, &self.field1)?;
serializer.serialize(2u32, &self.field2)?;
serializer.finish()
}
}
impl<T1, U1, T2, U2> Deserialize<Type<T1, T2>> for Type<U1, U2>
where
T1: Tag,
U1: Deserialize<T1>,
T2: Tag,
U2: Deserialize<T2>,
{
fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
let mut deserializer = deserializer.deserialize_struct()?;
let mut field1 = None;
let mut field2 = None;
while let Some(deserializer) = deserializer.deserialize()? {
match deserializer.id() {
1 => field1 = deserializer.deserialize().map(Some)?,
2 => field2 = deserializer.deserialize().map(Some)?,
_ => deserializer.skip()?,
}
}
deserializer.finish_with(|_| {
Ok(Self {
field1: field1.ok_or(DeserializeError::InvalidSerialization)?,
field2: field2.ok_or(DeserializeError::InvalidSerialization)?,
})
})
}
}
type Concrete = Type<i32, String>;
type Vague = Type<SerializedValue, SerializedValue>;
let concrete = Concrete {
field1: 0x1234,
field2: "0x1234".to_string(),
};
let vague = Vague {
field1: SerializedValue::serialize(0x1234).unwrap(),
field2: SerializedValue::serialize("0x1234").unwrap(),
};
assert_eq!(
concrete,
SerializedValue::serialize(&vague)
.unwrap()
.deserialize()
.unwrap()
);
assert_eq!(
vague,
SerializedValue::serialize(&concrete)
.unwrap()
.deserialize()
.unwrap()
);
}