use std::cell::Cell;
use std::error;
use std::fmt;
use serde::de::{self, DeserializeSeed, Deserializer};
use serde::ser::{self, Serialize, SerializeMap, SerializeSeq, Serializer};
const TRANSLATION_FAILED: &str = "translation failed";
pub(crate) fn transcode<'de, S, D>(ser: S, de: D) -> Result<S::Ok, Error<S::Error, D::Error>>
where
S: Serializer,
D: Deserializer<'de>,
{
let mut visitor = Visitor::new(ser);
match de.deserialize_any(&mut visitor) {
Ok(value) => Ok(value),
Err(de_err) => match visitor.0.error_source() {
ErrorSource::Ser => Err(Error::Ser(visitor.0.into_error().unwrap(), de_err)),
ErrorSource::De => Err(Error::De(de_err)),
},
}
}
#[derive(Debug)]
pub(crate) enum Error<S, D>
where
S: ser::Error,
D: de::Error,
{
Ser(S, D),
De(D),
}
impl<S, D> fmt::Display for Error<S, D>
where
S: ser::Error,
D: de::Error,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Ser(ser_err, de_err) => write!(f, "{de_err}: {ser_err}"),
Error::De(de_err) => fmt::Display::fmt(de_err, f),
}
}
}
impl<S, D> error::Error for Error<S, D>
where
S: ser::Error + 'static,
D: de::Error + 'static,
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Error::Ser(ser_err, _) => Some(ser_err),
Error::De(de_err) => Some(de_err),
}
}
}
#[derive(Clone, Copy)]
enum ErrorSource {
De,
Ser,
}
struct State<P, E> {
parent: Cell<Option<P>>,
error: Cell<Option<E>>,
source: Cell<ErrorSource>,
}
impl<P, E> State<P, E> {
fn new(parent: P) -> State<P, E> {
State {
parent: Cell::new(Some(parent)),
error: Cell::new(None),
source: Cell::new(ErrorSource::De),
}
}
fn take_parent(&self) -> P {
self.parent
.replace(None)
.expect("parent already taken from this state")
}
fn capture_error(&self, source: ErrorSource, error: E) {
self.source.set(source);
self.error.set(Some(error));
}
fn capture_child_error<C>(&self, child: State<C, E>) {
self.source.set(child.error_source());
self.error.set(child.into_error());
}
fn error_source(&self) -> ErrorSource {
self.source.get()
}
fn into_error(self) -> Option<E> {
self.error.into_inner()
}
}
struct Visitor<S: Serializer>(State<S, S::Error>);
impl<S: Serializer> Visitor<S> {
fn new(ser: S) -> Visitor<S> {
Visitor(State::new(ser))
}
fn forward_scalar<F, E>(&mut self, use_serializer: F) -> Result<S::Ok, E>
where
F: FnOnce(S) -> Result<S::Ok, S::Error>,
E: de::Error,
{
let ser = self.0.take_parent();
match use_serializer(ser) {
Ok(value) => Ok(value),
Err(ser_err) => {
self.0.capture_error(ErrorSource::Ser, ser_err);
Err(de::Error::custom(TRANSLATION_FAILED))
}
}
}
}
macro_rules! xt_transcode_impl_scalar_visitors {
($($name:ident($($arg:ident: $ty:ty)?) => $op:expr;)*) => {
$(fn $name<E: ::serde::de::Error>(self, $($arg: $ty)?) -> ::std::result::Result<Self::Value, E> {
self.forward_scalar($op)
})*
};
}
impl<'de, S: Serializer> de::Visitor<'de> for &mut Visitor<S> {
type Value = S::Ok;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("any supported value")
}
xt_transcode_impl_scalar_visitors! {
visit_unit() => |ser| ser.serialize_unit();
visit_bool(v: bool) => |ser| ser.serialize_bool(v);
visit_i8(v: i8) => |ser| ser.serialize_i8(v);
visit_i16(v: i16) => |ser| ser.serialize_i16(v);
visit_i32(v: i32) => |ser| ser.serialize_i32(v);
visit_i64(v: i64) => |ser| ser.serialize_i64(v);
visit_i128(v: i128) => |ser| ser.serialize_i128(v);
visit_u8(v: u8) => |ser| ser.serialize_u8(v);
visit_u16(v: u16) => |ser| ser.serialize_u16(v);
visit_u32(v: u32) => |ser| ser.serialize_u32(v);
visit_u64(v: u64) => |ser| ser.serialize_u64(v);
visit_u128(v: u128) => |ser| ser.serialize_u128(v);
visit_f32(v: f32) => |ser| ser.serialize_f32(v);
visit_f64(v: f64) => |ser| ser.serialize_f64(v);
visit_char(v: char) => |ser| ser.serialize_char(v);
visit_str(v: &str) => |ser| ser.serialize_str(v);
visit_bytes(v: &[u8]) => |ser| ser.serialize_bytes(v);
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut de: A) -> Result<Self::Value, A::Error> {
let mut seq = match self.0.take_parent().serialize_seq(de.size_hint()) {
Ok(seq) => seq,
Err(ser_err) => {
self.0.capture_error(ErrorSource::Ser, ser_err);
return Err(de::Error::custom(TRANSLATION_FAILED));
}
};
loop {
let mut seed = SeqSeed::new(&mut seq);
match de.next_element_seed(&mut seed) {
Ok(None) => break,
Ok(Some(())) => {}
Err(de_err) => {
self.0.capture_child_error(seed.0);
return Err(de_err);
}
}
}
match seq.end() {
Ok(value) => Ok(value),
Err(ser_err) => {
self.0.capture_error(ErrorSource::Ser, ser_err);
Err(de::Error::custom(TRANSLATION_FAILED))
}
}
}
fn visit_map<A: de::MapAccess<'de>>(self, mut de: A) -> Result<Self::Value, A::Error> {
let mut map = match self.0.take_parent().serialize_map(de.size_hint()) {
Ok(map) => map,
Err(ser_err) => {
self.0.capture_error(ErrorSource::Ser, ser_err);
return Err(de::Error::custom(TRANSLATION_FAILED));
}
};
loop {
let mut key_seed = KeySeed::new(&mut map);
match de.next_key_seed(&mut key_seed) {
Ok(None) => break,
Ok(Some(())) => {}
Err(de_err) => {
self.0.capture_child_error(key_seed.0);
return Err(de_err);
}
}
let mut value_seed = ValueSeed::new(&mut map);
if let Err(de_err) = de.next_value_seed(&mut value_seed) {
self.0.capture_child_error(value_seed.0);
return Err(de_err);
}
}
match map.end() {
Ok(value) => Ok(value),
Err(ser_err) => {
self.0.capture_error(ErrorSource::Ser, ser_err);
Err(de::Error::custom(TRANSLATION_FAILED))
}
}
}
}
struct Forwarder<'de, D: Deserializer<'de>>(State<D, D::Error>);
impl<'de, D: Deserializer<'de>> Forwarder<'de, D> {
fn new(de: D) -> Forwarder<'de, D> {
Forwarder(State::new(de))
}
fn serialize_with_seed<S, SErr, F>(
self,
seed_state: &mut State<S, SErr>,
use_serializer: F,
) -> Result<(), D::Error>
where
F: FnOnce(S, &Self) -> Result<(), SErr>,
{
let ser = seed_state.take_parent();
match use_serializer(ser, &self) {
Ok(()) => Ok(()),
Err(ser_err) => {
seed_state.capture_error(self.0.error_source(), ser_err);
match self.0.into_error() {
Some(de_err) => Err(de_err),
None => Err(de::Error::custom(TRANSLATION_FAILED)),
}
}
}
}
}
impl<'de, D: Deserializer<'de>> Serialize for Forwarder<'de, D> {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
let mut visitor = Visitor::new(ser);
let de = self.0.take_parent();
match de.deserialize_any(&mut visitor) {
Ok(value) => Ok(value),
Err(de_err) => {
self.0.capture_error(visitor.0.error_source(), de_err);
match visitor.0.into_error() {
Some(ser_err) => Err(ser_err),
None => Err(ser::Error::custom(TRANSLATION_FAILED)),
}
}
}
}
}
struct SeqSeed<'ser, S: SerializeSeq>(State<&'ser mut S, S::Error>);
impl<'ser, S: SerializeSeq> SeqSeed<'ser, S> {
fn new(ser: &'ser mut S) -> SeqSeed<'ser, S> {
SeqSeed(State::new(ser))
}
}
impl<'de, S: SerializeSeq> DeserializeSeed<'de> for &mut SeqSeed<'_, S> {
type Value = ();
fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<(), D::Error> {
Forwarder::new(de)
.serialize_with_seed(&mut self.0, |ser, element| ser.serialize_element(element))
}
}
struct KeySeed<'ser, S: SerializeMap>(State<&'ser mut S, S::Error>);
impl<'ser, S: SerializeMap> KeySeed<'ser, S> {
fn new(ser: &'ser mut S) -> KeySeed<'ser, S> {
KeySeed(State::new(ser))
}
}
impl<'de, S: SerializeMap> DeserializeSeed<'de> for &mut KeySeed<'_, S> {
type Value = ();
fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<(), D::Error> {
Forwarder::new(de).serialize_with_seed(&mut self.0, |ser, key| ser.serialize_key(key))
}
}
struct ValueSeed<'ser, S: SerializeMap>(State<&'ser mut S, S::Error>);
impl<'ser, S: SerializeMap> ValueSeed<'ser, S> {
fn new(ser: &'ser mut S) -> ValueSeed<'ser, S> {
ValueSeed(State::new(ser))
}
}
impl<'de, S: SerializeMap> DeserializeSeed<'de> for &mut ValueSeed<'_, S> {
type Value = ();
fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<(), D::Error> {
Forwarder::new(de).serialize_with_seed(&mut self.0, |ser, value| ser.serialize_value(value))
}
}