#![feature(specialization)]
pub use deserializer::{VersionMap, VersionedDeserializer};
use serde::de::{EnumAccess, MapAccess, SeqAccess};
#[cfg(feature = "serde_version_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_version_derive;
#[cfg(feature = "serde_version_derive")]
#[doc(hidden)]
pub use serde_version_derive::*;
pub trait DeserializeVersioned<'de>: serde::Deserialize<'de> {
fn deserialize_versioned<D>(
deserializer: D,
_version_map: &'de VersionMap,
) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Self::deserialize(deserializer)
}
#[inline]
fn next_element<S>(
seq_access: &mut S,
_version_map: &'de VersionMap,
) -> Result<Option<Self>, S::Error>
where
S: SeqAccess<'de>,
{
seq_access.next_element_seed(std::marker::PhantomData)
}
#[inline]
fn next_value<M>(map_access: &mut M, _version_map: &'de VersionMap) -> Result<Self, M::Error>
where
M: MapAccess<'de>,
{
map_access.next_value_seed(std::marker::PhantomData)
}
#[inline]
fn next_key<M>(
map_access: &mut M,
_version_map: &'de VersionMap,
) -> Result<Option<Self>, M::Error>
where
M: MapAccess<'de>,
{
map_access.next_key_seed(std::marker::PhantomData)
}
#[inline]
fn variant<E>(
enum_access: E,
_version_map: &'de VersionMap,
) -> Result<(Self, E::Variant), E::Error>
where
E: EnumAccess<'de>,
{
enum_access.variant_seed(std::marker::PhantomData)
}
}
impl<'de, T: serde::Deserialize<'de>> DeserializeVersioned<'de> for T {
default fn deserialize_versioned<D>(
deserializer: D,
version_map: &'de VersionMap,
) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let version_deserializer = VersionedDeserializer::new(deserializer, version_map);
T::deserialize(version_deserializer)
}
}
mod deserializer {
use super::visitor::VersionedVisitor;
use serde::Deserializer;
use std::collections::HashMap;
pub type VersionMap = HashMap<String, usize>;
pub struct VersionedDeserializer<'de, D>
where
D: Deserializer<'de>,
{
deserializer: D,
version_map: &'de VersionMap,
marker: std::marker::PhantomData<&'de usize>,
}
impl<'de, D> VersionedDeserializer<'de, D>
where
D: Deserializer<'de>,
{
pub fn new(deserializer: D, version_map: &'de VersionMap) -> Self {
Self {
deserializer,
version_map,
marker: std::marker::PhantomData,
}
}
}
macro_rules! forward_deserialize {
($name:ident) => {forward_deserialize!($name, );};
($name:ident, $($arg:tt => $ty:ty),*) => {
fn $name<V>(self, $($arg: $ty,)* visitor: V) -> Result<V::Value, D::Error>
where V: serde::de::Visitor<'de>
{
let visitor = VersionedVisitor::new(
visitor,
self.version_map,
);
self.deserializer.$name($($arg,)* visitor)
}
}
}
impl<'de, D: Deserializer<'de>> Deserializer<'de> for VersionedDeserializer<'de, D> {
type Error = D::Error;
forward_deserialize!(deserialize_any);
forward_deserialize!(deserialize_bool);
forward_deserialize!(deserialize_u8);
forward_deserialize!(deserialize_u16);
forward_deserialize!(deserialize_u32);
forward_deserialize!(deserialize_u64);
forward_deserialize!(deserialize_i8);
forward_deserialize!(deserialize_i16);
forward_deserialize!(deserialize_i32);
forward_deserialize!(deserialize_i64);
forward_deserialize!(deserialize_f32);
forward_deserialize!(deserialize_f64);
forward_deserialize!(deserialize_char);
forward_deserialize!(deserialize_str);
forward_deserialize!(deserialize_string);
forward_deserialize!(deserialize_unit);
forward_deserialize!(deserialize_option);
forward_deserialize!(deserialize_seq);
forward_deserialize!(deserialize_bytes);
forward_deserialize!(deserialize_byte_buf);
forward_deserialize!(deserialize_map);
forward_deserialize!(deserialize_unit_struct, name => &'static str);
forward_deserialize!(deserialize_newtype_struct, name => &'static str);
forward_deserialize!(deserialize_tuple_struct, name => &'static str, len => usize);
forward_deserialize!(deserialize_struct,
name => &'static str,
fields => &'static [&'static str]);
forward_deserialize!(deserialize_identifier);
forward_deserialize!(deserialize_tuple, len => usize);
forward_deserialize!(deserialize_enum,
name => &'static str,
variants => &'static [&'static str]);
forward_deserialize!(deserialize_ignored_any);
}
}
mod visitor {
use super::{VersionMap, VersionedDeserializer};
use crate::seed::VersionedSeed;
use crate::DeserializeVersioned;
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::{Deserialize, Deserializer};
pub struct VersionedVisitor<'v, V> {
visitor: V,
version_map: &'v VersionMap,
}
impl<'v, V> VersionedVisitor<'v, V> {
pub fn new(visitor: V, version_map: &'v VersionMap) -> Self {
Self {
visitor,
version_map,
}
}
}
macro_rules! forward_visit {
($name:ident, $ty:ty) => {
#[inline]
fn $name<E>(self, v: $ty) -> Result<V::Value, E>
where E: serde::de::Error
{
self.visitor.$name(v)
}
}
}
impl<'de, V> Visitor<'de> for VersionedVisitor<'de, V>
where
V: Visitor<'de>,
{
type Value = V::Value;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.visitor.expecting(formatter)
}
forward_visit!(visit_bool, bool);
forward_visit!(visit_i8, i8);
forward_visit!(visit_i16, i16);
forward_visit!(visit_i32, i32);
forward_visit!(visit_i64, i64);
forward_visit!(visit_u8, u8);
forward_visit!(visit_u16, u16);
forward_visit!(visit_u32, u32);
forward_visit!(visit_u64, u64);
forward_visit!(visit_f32, f32);
forward_visit!(visit_f64, f64);
forward_visit!(visit_char, char);
forward_visit!(visit_bytes, &[u8]);
forward_visit!(visit_byte_buf, Vec<u8>);
forward_visit!(visit_str, &str);
forward_visit!(visit_string, String);
forward_visit!(visit_borrowed_str, &'de str);
#[inline]
fn visit_unit<E>(self) -> Result<V::Value, E>
where
E: serde::de::Error,
{
self.visitor.visit_unit()
}
#[inline]
fn visit_none<E>(self) -> Result<V::Value, E>
where
E: serde::de::Error,
{
self.visitor.visit_none()
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<V::Value, D::Error>
where
D: Deserializer<'de>,
{
let deserializer = VersionedDeserializer::new(deserializer, self.version_map);
self.visitor.visit_some(deserializer)
}
#[inline]
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<V::Value, D::Error>
where
D: Deserializer<'de>,
{
let deserializer = VersionedDeserializer::new(deserializer, self.version_map);
self.visitor.visit_newtype_struct(deserializer)
}
#[inline]
fn visit_seq<V2>(self, visitor: V2) -> Result<V::Value, V2::Error>
where
V2: SeqAccess<'de>,
{
let visitor = VersionedVisitor {
visitor,
version_map: self.version_map,
};
self.visitor.visit_seq(visitor)
}
#[inline]
fn visit_map<V2>(self, visitor: V2) -> Result<V::Value, V2::Error>
where
V2: MapAccess<'de>,
{
let visitor = VersionedVisitor {
visitor,
version_map: self.version_map,
};
self.visitor.visit_map(visitor)
}
#[inline]
fn visit_enum<V2>(self, visitor: V2) -> Result<V::Value, V2::Error>
where
V2: EnumAccess<'de>,
{
let visitor = VersionedVisitor {
visitor,
version_map: self.version_map,
};
self.visitor.visit_enum(visitor)
}
}
impl<'de, V> SeqAccess<'de> for VersionedVisitor<'de, V>
where
V: SeqAccess<'de>,
{
type Error = V::Error;
#[inline]
fn next_element_seed<T>(
&mut self,
seed: T,
) -> Result<Option<<T as DeserializeSeed<'de>>::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
let seed = VersionedSeed::new(seed, self.version_map);
self.visitor.next_element_seed(seed)
}
#[inline]
fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
where
T: Deserialize<'de>,
{
<T as DeserializeVersioned<'de>>::next_element(self, self.version_map)
}
}
impl<'de, V> MapAccess<'de> for VersionedVisitor<'de, V>
where
V: MapAccess<'de>,
{
type Error = V::Error;
#[inline]
fn next_key_seed<K>(
&mut self,
seed: K,
) -> Result<Option<<K as DeserializeSeed<'de>>::Value>, Self::Error>
where
K: DeserializeSeed<'de>,
{
let seed = VersionedSeed::new(seed, self.version_map);
self.visitor.next_key_seed(seed)
}
#[inline]
fn next_value_seed<S>(
&mut self,
seed: S,
) -> Result<<S as DeserializeSeed<'de>>::Value, Self::Error>
where
S: DeserializeSeed<'de>,
{
let seed = VersionedSeed::new(seed, self.version_map);
self.visitor.next_value_seed(seed)
}
#[inline]
#[allow(clippy::type_complexity)]
fn next_entry_seed<K, V2>(
&mut self,
kseed: K,
vseed: V2,
) -> Result<Option<(K::Value, V2::Value)>, V::Error>
where
K: DeserializeSeed<'de>,
V2: DeserializeSeed<'de>,
{
let kseed = VersionedSeed::new(kseed, self.version_map);
let vseed = VersionedSeed::new(vseed, self.version_map);
self.visitor.next_entry_seed(kseed, vseed)
}
#[inline]
fn next_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where
K: Deserialize<'de>,
{
<K as DeserializeVersioned<'de>>::next_key(self, self.version_map)
}
#[inline]
fn next_value<V2>(&mut self) -> Result<V2, Self::Error>
where
V2: Deserialize<'de>,
{
<V2 as DeserializeVersioned<'de>>::next_value(self, self.version_map)
}
fn size_hint(&self) -> Option<usize> {
self.visitor.size_hint()
}
}
impl<'de, V> EnumAccess<'de> for VersionedVisitor<'de, V>
where
V: EnumAccess<'de>,
{
type Error = V::Error;
type Variant = VersionedVisitor<'de, V::Variant>;
#[inline]
#[allow(clippy::type_complexity)]
fn variant_seed<S>(
self,
seed: S,
) -> Result<(S::Value, VersionedVisitor<'de, V::Variant>), V::Error>
where
S: DeserializeSeed<'de>,
{
let seed = VersionedSeed::new(seed, self.version_map);
match self.visitor.variant_seed(seed) {
Ok((value, variant)) => {
let variant = VersionedVisitor {
visitor: variant,
version_map: self.version_map,
};
Ok((value, variant))
}
Err(e) => Err(e),
}
}
#[inline]
fn variant<V2>(self) -> Result<(V2, Self::Variant), Self::Error>
where
V2: Deserialize<'de>,
{
let version_map = self.version_map;
<V2 as DeserializeVersioned<'de>>::variant(self, version_map)
}
}
impl<'de, V> VariantAccess<'de> for VersionedVisitor<'de, V>
where
V: VariantAccess<'de>,
{
type Error = V::Error;
#[inline]
fn unit_variant(self) -> Result<(), V::Error> {
self.visitor.unit_variant()
}
#[inline]
fn newtype_variant_seed<S>(self, seed: S) -> Result<S::Value, V::Error>
where
S: DeserializeSeed<'de>,
{
let seed = VersionedSeed::new(seed, self.version_map);
self.visitor.newtype_variant_seed(seed)
}
#[inline]
fn tuple_variant<V2>(self, len: usize, visitor: V2) -> Result<V2::Value, V::Error>
where
V2: Visitor<'de>,
{
let visitor = VersionedVisitor {
visitor,
version_map: self.version_map,
};
self.visitor.tuple_variant(len, visitor)
}
#[inline]
fn struct_variant<V2>(
self,
fields: &'static [&'static str],
visitor: V2,
) -> Result<V2::Value, V::Error>
where
V2: Visitor<'de>,
{
let visitor = VersionedVisitor {
visitor,
version_map: self.version_map,
};
self.visitor.struct_variant(fields, visitor)
}
}
}
mod seed {
use super::VersionMap;
use crate::VersionedDeserializer;
use serde::de::DeserializeSeed;
use serde::Deserializer;
pub struct VersionedSeed<'v, S> {
seed: S,
version_map: &'v VersionMap,
}
impl<'v, S> VersionedSeed<'v, S> {
pub fn new(seed: S, version_map: &'v VersionMap) -> Self {
Self { seed, version_map }
}
}
impl<'de, 'v, S> DeserializeSeed<'de> for VersionedSeed<'de, S>
where
S: DeserializeSeed<'de>,
{
type Value = S::Value;
fn deserialize<D>(
self,
deserializer: D,
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
self.seed
.deserialize(VersionedDeserializer::new(deserializer, self.version_map))
}
}
}