#![allow(clippy::needless_doctest_main)]
#![feature(specialization)]
#[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::*;
#[allow(unused_imports)]
#[macro_use]
extern crate lazy_static;
#[doc(hidden)]
pub use lazy_static::*;
#[macro_use]
extern crate failure;
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
#[macro_use(quickcheck)]
extern crate quickcheck_macros;
mod deserializer;
mod seed;
mod version_groups;
mod version_map;
mod visitor;
#[macro_use]
mod utils;
pub mod exports;
#[cfg(feature = "toml-support")]
pub mod toml;
pub use deserializer::VersionedDeserializer;
use serde::de::{EnumAccess, MapAccess, SeqAccess};
use std::fmt::Display;
pub use version_groups::{
DefaultVersionGroupResolver, VersionGroupResolver, VersionGroupURI, VersionGroupURIs,
};
pub use version_map::{
AggregateVersionMap, AggregateVersionMapError, DefaultVersionMap, TypeInMultipleVersionGroups,
UnknownVersionURI, VersionMap,
};
#[derive(Debug, Hash, PartialEq, Eq, Fail)]
#[fail(display = "Unknown version {} for type {}", version, type_id)]
pub struct InvalidVersionError {
pub version: usize,
pub type_id: String,
}
#[derive(Debug, Hash, PartialEq, Eq)]
pub enum Error<E> {
DeserializeError(E),
InvalidVersionError(InvalidVersionError),
Message(String),
}
impl<E> Error<E>
where
E: serde::de::Error,
{
pub fn into_error(self) -> E {
match self {
Error::Message(err) => serde::de::Error::custom(err),
Error::DeserializeError(err) => err,
Error::InvalidVersionError(err) => serde::de::Error::custom(format!("{}", err)),
}
}
}
impl<E> Error<Error<E>>
where
E: serde::de::Error,
{
pub fn reduce(self) -> Error<E> {
match self {
Error::Message(err) | Error::DeserializeError(Error::Message(err)) => {
Error::Message(err)
}
Error::InvalidVersionError(err)
| Error::DeserializeError(Error::InvalidVersionError(err)) => {
Error::InvalidVersionError(err)
}
Error::DeserializeError(Error::DeserializeError(err)) => Error::DeserializeError(err),
}
}
}
impl<E> std::fmt::Display for Error<E>
where
E: std::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match self {
Error::DeserializeError(ref e) => write!(f, "{}", e),
Error::InvalidVersionError(ref e) => {
write!(f, "Unknown version {} for type {}", e.version, e.type_id)
}
Error::Message(ref e) => write!(f, "{}", e),
}
}
}
impl<E> std::error::Error for Error<E> where E: std::error::Error {}
impl<E> serde::de::Error for Error<E>
where
E: serde::de::Error,
{
fn custom<T>(msg: T) -> Self
where
T: Display,
{
Self::Message(format!("{}", msg))
}
}
pub trait DeserializeVersioned<'de, VM: VersionMap>: serde::Deserialize<'de> {
fn deserialize_versioned<D>(deserializer: D, _version_map: VM) -> Result<Self, Error<D::Error>>
where
D: serde::de::Deserializer<'de>;
fn next_element<S>(
seq_access: &mut S,
version_map: VM,
) -> Result<Option<Self>, Error<S::Error>>
where
S: SeqAccess<'de>;
fn next_value<M>(map_access: &mut M, _version_map: VM) -> Result<Self, Error<M::Error>>
where
M: MapAccess<'de>;
fn next_key<M>(map_access: &mut M, _version_map: VM) -> Result<Option<Self>, Error<M::Error>>
where
M: MapAccess<'de>;
fn variant<E>(enum_access: E, _version_map: VM) -> Result<(Self, E::Variant), Error<E::Error>>
where
E: EnumAccess<'de>;
}
impl<'de, T: serde::Deserialize<'de>, VM: VersionMap> DeserializeVersioned<'de, VM> for T {
default fn deserialize_versioned<D>(
deserializer: D,
version_map: VM,
) -> Result<Self, Error<D::Error>>
where
D: serde::de::Deserializer<'de>,
{
let version_deserializer = VersionedDeserializer::new(deserializer, version_map);
T::deserialize(version_deserializer)
}
#[inline]
default fn next_element<S>(
seq_access: &mut S,
_version_map: VM,
) -> Result<Option<Self>, Error<S::Error>>
where
S: SeqAccess<'de>,
{
seq_access
.next_element_seed(std::marker::PhantomData)
.map_err(Error::DeserializeError)
}
#[inline]
default fn next_value<M>(map_access: &mut M, _version_map: VM) -> Result<Self, Error<M::Error>>
where
M: MapAccess<'de>,
{
map_access
.next_value_seed(std::marker::PhantomData)
.map_err(Error::DeserializeError)
}
#[inline]
default fn next_key<M>(
map_access: &mut M,
_version_map: VM,
) -> Result<Option<Self>, Error<M::Error>>
where
M: MapAccess<'de>,
{
map_access
.next_key_seed(std::marker::PhantomData)
.map_err(Error::DeserializeError)
}
#[inline]
default fn variant<E>(
enum_access: E,
_version_map: VM,
) -> Result<(Self, E::Variant), Error<E::Error>>
where
E: EnumAccess<'de>,
{
enum_access
.variant_seed(std::marker::PhantomData)
.map_err(Error::DeserializeError)
}
}