use crate::de::delegating_visitor::{DelegatingVisitor, Visitor2};
use crate::de::Behavior;
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use serde::de::{self, Visitor};
use serde_json::de::{IoRead, Read, SliceRead, StrRead};
use serde_json::Error;
use std::fmt;
use std::io;
pub fn client_from_reader<R, T>(reader: R) -> Result<T, Error>
where
R: io::Read,
T: de::DeserializeOwned,
{
let mut de = ClientDeserializer::from_reader(reader);
let value = T::deserialize(&mut de)?;
de.end()?;
Ok(value)
}
pub fn client_from_str<'a, T>(s: &'a str) -> Result<T, Error>
where
T: de::Deserialize<'a>,
{
let mut de = ClientDeserializer::from_str(s);
let value = T::deserialize(&mut de)?;
de.end()?;
Ok(value)
}
pub fn client_from_slice<'a, T>(s: &'a [u8]) -> Result<T, Error>
where
T: de::Deserialize<'a>,
{
let mut de = ClientDeserializer::from_slice(s);
let value = T::deserialize(&mut de)?;
de.end()?;
Ok(value)
}
pub struct ClientDeserializer<R>(serde_json::Deserializer<R>);
impl<R> ClientDeserializer<IoRead<R>>
where
R: io::Read,
{
pub fn from_reader(reader: R) -> ClientDeserializer<IoRead<R>> {
ClientDeserializer(serde_json::Deserializer::from_reader(reader))
}
}
impl<'a> ClientDeserializer<SliceRead<'a>> {
pub fn from_slice(bytes: &'a [u8]) -> ClientDeserializer<SliceRead<'a>> {
ClientDeserializer(serde_json::Deserializer::from_slice(bytes))
}
}
impl<'a> ClientDeserializer<StrRead<'a>> {
#[allow(clippy::should_implement_trait)] pub fn from_str(s: &'a str) -> ClientDeserializer<StrRead<'a>> {
ClientDeserializer(serde_json::Deserializer::from_str(s))
}
}
impl<'de, R> ClientDeserializer<R>
where
R: Read<'de>,
{
pub fn end(&mut self) -> Result<(), Error> {
self.0.end()
}
}
impl<'a, 'de, R> de::Deserializer<'de> for &'a mut ClientDeserializer<R>
where
R: Read<'de>,
{
impl_deserialize_body!(&'a mut serde_json::Deserializer<R>, ValueBehavior);
fn is_human_readable(&self) -> bool {
true
}
}
pub enum ValueBehavior {}
impl Behavior for ValueBehavior {
type KeyBehavior = KeyBehavior;
fn deserialize_f32<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_any(DelegatingVisitor::new(F32Visitor, visitor))
}
fn deserialize_f64<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_any(DelegatingVisitor::new(F64Visitor, visitor))
}
fn deserialize_bytes<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(ByteBufVisitor(visitor))
}
fn deserialize_byte_buf<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(ByteBufVisitor(visitor))
}
}
pub enum KeyBehavior {}
impl Behavior for KeyBehavior {
type KeyBehavior = Self;
fn deserialize_bool<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: Visitor<'de>,
{
de.deserialize_str(BoolKeyVisitor(visitor))
}
fn deserialize_f32<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(F32KeyVisitor(visitor))
}
fn deserialize_f64<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(F64KeyVisitor(visitor))
}
fn deserialize_bytes<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(ByteBufVisitor(visitor))
}
fn deserialize_byte_buf<'de, D, V>(de: D, visitor: V) -> Result<V::Value, D::Error>
where
D: serde::Deserializer<'de>,
V: de::Visitor<'de>,
{
de.deserialize_str(ByteBufVisitor(visitor))
}
}
macro_rules! float_visitor {
($name:ident, $method:ident, $module:ident) => {
struct $name;
impl<'de, V> Visitor2<'de, V> for $name
where
V: Visitor<'de>,
{
fn visit_str<E>(self, visitor: V, v: &str) -> Result<V::Value, E>
where
E: de::Error,
{
match v {
"NaN" => visitor.$method($module::NAN),
"Infinity" => visitor.$method($module::INFINITY),
"-Infinity" => visitor.$method($module::NEG_INFINITY),
_ => visitor.visit_str(v),
}
}
fn visit_borrowed_str<E>(self, visitor: V, v: &'de str) -> Result<V::Value, E>
where
E: de::Error,
{
self.visit_str(visitor, v)
}
fn visit_string<E>(self, visitor: V, v: String) -> Result<V::Value, E>
where
E: de::Error,
{
self.visit_str(visitor, &v)
}
}
};
}
float_visitor!(F32Visitor, visit_f32, f32);
float_visitor!(F64Visitor, visit_f64, f64);
macro_rules! float_key_visitor {
($name:ident, $method:ident, $module:ident) => {
struct $name<T>(T);
impl<'de, T> de::Visitor<'de> for $name<T>
where
T: de::Visitor<'de>,
{
type Value = T::Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a number")
}
fn visit_str<E>(self, v: &str) -> Result<T::Value, E>
where
E: de::Error,
{
match v {
"NaN" => (self.0).$method($module::NAN),
"Infinity" => (self.0).$method($module::INFINITY),
"-Infinity" => (self.0).$method($module::NEG_INFINITY),
v => match v.parse() {
Ok(v) => (self.0).$method(v),
Err(_) => Err(de::Error::invalid_value(de::Unexpected::Str(v), &self)),
},
}
}
}
};
}
float_key_visitor!(F32KeyVisitor, visit_f32, f32);
float_key_visitor!(F64KeyVisitor, visit_f64, f64);
struct ByteBufVisitor<T>(T);
impl<'de, T> de::Visitor<'de> for ByteBufVisitor<T>
where
T: de::Visitor<'de>,
{
type Value = T::Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a base64 string")
}
fn visit_str<E>(self, v: &str) -> Result<T::Value, E>
where
E: de::Error,
{
match STANDARD.decode(v) {
Ok(v) => self.0.visit_byte_buf(v),
Err(_) => Err(E::invalid_value(de::Unexpected::Str(v), &self)),
}
}
}
struct BoolKeyVisitor<T>(T);
impl<'de, T> Visitor<'de> for BoolKeyVisitor<T>
where
T: Visitor<'de>,
{
type Value = T::Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a boolean")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
match v.parse() {
Ok(v) => self.0.visit_bool(v),
Err(_) => Err(E::invalid_value(de::Unexpected::Str(v), &self)),
}
}
}