use std::fmt;
use serde::de::{
self, DeserializeSeed, Deserializer, EnumAccess, IgnoredAny, MapAccess, SeqAccess, Visitor,
};
use super::Unfit;
pub trait Kinds<'de>: Sized {
type Value;
const EXPECTED: &'static str;
fn wrong<E: de::Error>() -> E {
Unfit::kind(Self::EXPECTED).raise()
}
fn binary<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error>;
fn read<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
d.deserialize_any(Shape(self))
}
fn null<E: de::Error>(self) -> Result<Self::Value, E> {
Err(Self::wrong())
}
fn bool<E: de::Error>(self, _: bool) -> Result<Self::Value, E> {
Err(Self::wrong())
}
fn int<E: de::Error>(self, _: i128) -> Result<Self::Value, E> {
Err(Self::wrong())
}
fn huge<E: de::Error>(self, v: u128) -> Result<Self::Value, E> {
#[allow(clippy::cast_precision_loss)]
self.float(v as f64)
}
fn float<E: de::Error>(self, _: f64) -> Result<Self::Value, E> {
Err(Self::wrong())
}
fn text<E: de::Error>(self, _: &str) -> Result<Self::Value, E> {
Err(Self::wrong())
}
fn seq<A: SeqAccess<'de>>(self, mut a: A) -> Result<Self::Value, A::Error> {
while a.next_element::<IgnoredAny>()?.is_some() {}
Err(Self::wrong())
}
fn map<A: MapAccess<'de>>(self, mut a: A) -> Result<Self::Value, A::Error> {
while a.next_entry::<IgnoredAny, IgnoredAny>()?.is_some() {}
Err(Self::wrong())
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Shape<K>(pub K);
impl<'de, K: Kinds<'de>> DeserializeSeed<'de> for Shape<K> {
type Value = K::Value;
fn deserialize<D: Deserializer<'de>>(self, d: D) -> Result<K::Value, D::Error> {
match d.is_human_readable() {
true => self.0.read(d),
false => self.0.binary(d),
}
}
}
impl<'de, K: Kinds<'de>> Visitor<'de> for Shape<K> {
type Value = K::Value;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(K::EXPECTED)
}
fn visit_unit<E: de::Error>(self) -> Result<K::Value, E> {
self.0.null()
}
fn visit_none<E: de::Error>(self) -> Result<K::Value, E> {
self.0.null()
}
fn visit_some<D: Deserializer<'de>>(self, d: D) -> Result<K::Value, D::Error> {
d.deserialize_any(self)
}
fn visit_newtype_struct<D: Deserializer<'de>>(self, d: D) -> Result<K::Value, D::Error> {
d.deserialize_any(self)
}
fn visit_bool<E: de::Error>(self, v: bool) -> Result<K::Value, E> {
self.0.bool(v)
}
fn visit_i64<E: de::Error>(self, v: i64) -> Result<K::Value, E> {
self.0.int(v.into())
}
fn visit_u64<E: de::Error>(self, v: u64) -> Result<K::Value, E> {
self.0.int(v.into())
}
fn visit_i128<E: de::Error>(self, v: i128) -> Result<K::Value, E> {
self.0.int(v)
}
fn visit_u128<E: de::Error>(self, v: u128) -> Result<K::Value, E> {
match i128::try_from(v) {
Ok(v) => self.0.int(v),
Err(_) => self.0.huge(v),
}
}
fn visit_f64<E: de::Error>(self, v: f64) -> Result<K::Value, E> {
self.0.float(v)
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<K::Value, E> {
self.0.text(v)
}
fn visit_bytes<E: de::Error>(self, _: &[u8]) -> Result<K::Value, E> {
Err(K::wrong())
}
fn visit_enum<A: EnumAccess<'de>>(self, _: A) -> Result<K::Value, A::Error> {
Err(K::wrong())
}
fn visit_seq<A: SeqAccess<'de>>(self, a: A) -> Result<K::Value, A::Error> {
self.0.seq(a)
}
fn visit_map<A: MapAccess<'de>>(self, a: A) -> Result<K::Value, A::Error> {
self.0.map(a)
}
}