use super::UnknownVariant;
use crate::tags::{self, PrimaryTag};
use crate::{
Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, SerializedValue,
Serializer,
};
#[derive(Debug, Clone, PartialEq, Eq)]
enum Old {
Var1,
Fallback(UnknownVariant),
}
impl PrimaryTag for Old {
type Tag = tags::Value;
}
impl Serialize<tags::Value> for Old {
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
serializer.serialize::<tags::Value>(&self)
}
}
impl Serialize<tags::Value> for &Old {
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
match self {
Old::Var1 => serializer.serialize_unit_enum(1u32),
Old::Fallback(fallback) => serializer.serialize_unknown_variant(fallback),
}
}
}
impl Deserialize<tags::Value> for Old {
fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
let deserializer = deserializer.deserialize_enum()?;
match deserializer.id() {
1 => deserializer.deserialize_unit().map(|()| Self::Var1),
_ => deserializer.into_unknown_variant().map(Self::Fallback),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum New {
Var1,
Var2(u8),
Fallback(UnknownVariant),
}
impl PrimaryTag for New {
type Tag = tags::Value;
}
impl Serialize<tags::Value> for New {
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
serializer.serialize::<tags::Value>(&self)
}
}
impl Serialize<tags::Value> for &New {
fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
match self {
New::Var1 => serializer.serialize_unit_enum(1u32),
New::Var2(value) => serializer.serialize_enum::<tags::U8>(2u32, value),
New::Fallback(fallback) => serializer.serialize_unknown_variant(fallback),
}
}
}
impl Deserialize<tags::Value> for New {
fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
let deserializer = deserializer.deserialize_enum()?;
match deserializer.id() {
1 => deserializer.deserialize_unit().map(|()| Self::Var1),
2 => deserializer.deserialize::<tags::U8, _>().map(Self::Var2),
_ => deserializer.into_unknown_variant().map(Self::Fallback),
}
}
}
#[test]
fn old_new_old_roundtrip() {
let old = Old::Var1;
let serialized = SerializedValue::serialize(&old).unwrap();
let new = serialized.deserialize::<New>().unwrap();
assert_eq!(new, New::Var1);
let serialized = SerializedValue::serialize(&new).unwrap();
let old2 = serialized.deserialize::<Old>().unwrap();
assert_eq!(old2, old);
}
#[test]
fn new_old_new_roundtrip1() {
let new = New::Var1;
let serialized = SerializedValue::serialize(&new).unwrap();
let old = serialized.deserialize::<Old>().unwrap();
assert_eq!(old, Old::Var1);
let serialized = SerializedValue::serialize(&old).unwrap();
let new2 = serialized.deserialize::<New>().unwrap();
assert_eq!(new2, new);
}
#[test]
fn new_old_new_roundtrip2() {
let new = New::Var2(1);
let serialized = SerializedValue::serialize(&new).unwrap();
let old = serialized.deserialize::<Old>().unwrap();
let Old::Fallback(ref fallback) = old else {
panic!();
};
assert_eq!(fallback.id(), 2);
assert_eq!(fallback.deserialize::<u8>().unwrap(), 1u8);
let serialized = SerializedValue::serialize(&old).unwrap();
let new2 = serialized.deserialize::<New>().unwrap();
assert_eq!(new2, new);
}