421 lines
15 KiB
Rust
421 lines
15 KiB
Rust
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
|
|
use crate::value::value::{Float, Double};
|
|
use num::traits::cast::ToPrimitive;
|
|
use serde::Deserialize;
|
|
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
|
|
use std::convert::TryFrom;
|
|
use std::iter::Iterator;
|
|
|
|
pub mod error {
|
|
use num::bigint::BigInt;
|
|
use crate::value::IOValue;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
Message(String),
|
|
InvalidUnicodeScalar(u32),
|
|
NumberTooLarge(BigInt),
|
|
CannotDeserializeAny,
|
|
Expected(ExpectedKind, IOValue),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum ExpectedKind {
|
|
Boolean,
|
|
Float,
|
|
Double,
|
|
|
|
SignedInteger,
|
|
String,
|
|
ByteString,
|
|
Symbol,
|
|
|
|
Record(Option<usize>),
|
|
SimpleRecord(&'static str, Option<usize>),
|
|
Option,
|
|
Sequence,
|
|
Dictionary,
|
|
}
|
|
|
|
impl serde::de::Error for Error {
|
|
fn custom<T: std::fmt::Display>(msg: T) -> Self {
|
|
Self::Message(msg.to_string())
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
impl std::fmt::Display for Error {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{:?}", self)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub use error::Error;
|
|
use error::ExpectedKind;
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
pub struct Deserializer<'de> {
|
|
input: &'de IOValue,
|
|
}
|
|
|
|
pub fn from_value<'a, T>(v: &'a IOValue) -> Result<T> where T: Deserialize<'a>
|
|
{
|
|
let mut de = Deserializer::from_value(v);
|
|
let t = T::deserialize(&mut de)?;
|
|
Ok(t)
|
|
}
|
|
|
|
impl<'de> Deserializer<'de> {
|
|
pub fn from_value(v: &'de IOValue) -> Self {
|
|
Deserializer { input: v }
|
|
}
|
|
|
|
fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T>
|
|
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T>
|
|
{
|
|
f(self.input.value()).ok_or_else(|| Error::Expected(k, self.input.clone()))
|
|
}
|
|
}
|
|
|
|
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
|
|
{
|
|
type Error = Error;
|
|
|
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let v = self.input.value();
|
|
match v {
|
|
Value::Boolean(b) => visitor.visit_bool(*b),
|
|
Value::Float(Float(f)) => visitor.visit_f32(*f),
|
|
Value::Double(Double(d)) => visitor.visit_f64(*d),
|
|
Value::SignedInteger(ref i) =>
|
|
match i.to_i64() {
|
|
None => match i.to_u64() {
|
|
None => Err(Error::NumberTooLarge(i.clone())),
|
|
Some(n) => visitor.visit_u64(n),
|
|
}
|
|
Some(n) => visitor.visit_i64(n),
|
|
}
|
|
Value::String(ref s) => visitor.visit_str(&s),
|
|
Value::ByteString(_) => self.deserialize_bytes(visitor),
|
|
Value::Record(_) =>
|
|
if v.is_simple_record("tuple", Some(0)) {
|
|
self.deserialize_unit(visitor)
|
|
} else if v.is_simple_record("UnicodeScalar", Some(1)) {
|
|
self.deserialize_char(visitor)
|
|
} else if v.is_simple_record("None", Some(0)) || v.is_simple_record("Some", Some(1)) {
|
|
self.deserialize_option(visitor)
|
|
} else if v.is_simple_record("tuple", None) {
|
|
visitor.visit_seq(VecSeq::new(self, v.as_simple_record("tuple", None).unwrap()))
|
|
} else {
|
|
Err(Error::CannotDeserializeAny)
|
|
}
|
|
Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v)),
|
|
Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)),
|
|
_ => Err(Error::CannotDeserializeAny),
|
|
}
|
|
}
|
|
|
|
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_bool(self.check(|v| v.as_boolean(), ExpectedKind::Boolean)?)
|
|
}
|
|
|
|
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_i8(i.to_i8().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_i16(i.to_i16().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_i32(i.to_i32().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_i64(i.to_i64().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_u8(i.to_u8().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_u16(i.to_u16().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_u32(i.to_u32().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let i = self.check(|v| v.as_signedinteger(), ExpectedKind::SignedInteger)?;
|
|
visitor.visit_u64(i.to_u64().ok_or_else(|| Error::NumberTooLarge(i.clone()))?)
|
|
}
|
|
|
|
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_f32(self.check(|v| v.as_float(), ExpectedKind::Float)?)
|
|
}
|
|
|
|
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_f64(self.check(|v| v.as_double(), ExpectedKind::Double)?)
|
|
}
|
|
|
|
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let fs = self.check(|v| v.as_simple_record("UnicodeScalar", Some(1)),
|
|
ExpectedKind::SimpleRecord("UnicodeScalar", Some(1)))?;
|
|
let c = fs[0].value().as_u32()
|
|
.ok_or_else(|| Error::Expected(ExpectedKind::SignedInteger, self.input.copy_via_id()))?;
|
|
visitor.visit_char(char::try_from(c).or(Err(Error::InvalidUnicodeScalar(c)))?)
|
|
}
|
|
|
|
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_borrowed_str(&self.check(|v| v.as_string(), ExpectedKind::String)?)
|
|
}
|
|
|
|
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
self.deserialize_str(visitor)
|
|
}
|
|
|
|
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_borrowed_bytes(&self.check(|v| v.as_bytestring(), ExpectedKind::ByteString)?)
|
|
}
|
|
|
|
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_byte_buf(self.check(|v| v.as_bytestring(), ExpectedKind::ByteString)?.clone())
|
|
}
|
|
|
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
match self.input.value().as_simple_record("None", Some(0)) {
|
|
Some(_fs) => visitor.visit_none(),
|
|
None => match self.input.value().as_simple_record("Some", Some(1)) {
|
|
Some(fs) => {
|
|
self.input = &fs[0];
|
|
visitor.visit_some(self)
|
|
}
|
|
None => Err(Error::Expected(ExpectedKind::Option, self.input.copy_via_id()))
|
|
}
|
|
}
|
|
}
|
|
|
|
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
if self.input.value().is_simple_record("tuple", Some(0)) {
|
|
visitor.visit_unit()
|
|
} else {
|
|
Err(Error::Expected(ExpectedKind::SimpleRecord("tuple", Some(0)), self.input.copy_via_id()))
|
|
}
|
|
}
|
|
|
|
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
if self.input.value().is_simple_record(name, Some(0)) {
|
|
visitor.visit_unit()
|
|
} else {
|
|
Err(Error::Expected(ExpectedKind::SimpleRecord(name, Some(0)), self.input.copy_via_id()))
|
|
}
|
|
}
|
|
|
|
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
match super::magic::transmit_input_value(name, || self.input.clone()) {
|
|
Some(v) => visitor.visit_u64(v),
|
|
None => {
|
|
let fs = self.check(|v| v.as_simple_record(name, Some(1)),
|
|
ExpectedKind::SimpleRecord(name, Some(1)))?;
|
|
self.input = &fs[0];
|
|
visitor.visit_newtype_struct(self)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
|
let vs = self.check(|v| v.as_sequence(), ExpectedKind::Sequence)?;
|
|
visitor.visit_seq(VecSeq::new(self, vs))
|
|
}
|
|
|
|
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let fs = self.check(|v| v.as_simple_record("tuple", Some(len)),
|
|
ExpectedKind::SimpleRecord("tuple", Some(len)))?;
|
|
visitor.visit_seq(VecSeq::new(self, fs))
|
|
}
|
|
|
|
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let fs = self.check(|v| v.as_simple_record(name, Some(len)),
|
|
ExpectedKind::SimpleRecord(name, Some(len)))?;
|
|
visitor.visit_seq(VecSeq::new(self, fs))
|
|
}
|
|
|
|
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
|
let d = self.check(|v| v.as_dictionary(), ExpectedKind::Dictionary)?;
|
|
visitor.visit_map(DictMap::new(self, d))
|
|
}
|
|
|
|
fn deserialize_struct<V>(self,
|
|
name: &'static str,
|
|
fields: &'static [&'static str],
|
|
visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
let fs = self.check(|v| v.as_simple_record(name, Some(fields.len())),
|
|
ExpectedKind::SimpleRecord(name, Some(fields.len())))?;
|
|
visitor.visit_seq(VecSeq::new(self, fs))
|
|
}
|
|
|
|
fn deserialize_enum<V>(self,
|
|
_name: &'static str,
|
|
_variants: &'static [&'static str],
|
|
visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_enum(self)
|
|
}
|
|
|
|
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_borrowed_str(&self.check(|v| v.as_symbol(), ExpectedKind::Symbol)?)
|
|
}
|
|
|
|
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_none()
|
|
}
|
|
}
|
|
|
|
pub struct VecSeq<'a, 'de: 'a> {
|
|
index: usize,
|
|
vec: &'de [IOValue],
|
|
de: &'a mut Deserializer<'de>,
|
|
}
|
|
|
|
impl<'de, 'a> VecSeq<'a, 'de> {
|
|
fn new(de: &'a mut Deserializer<'de>, vec: &'de [IOValue]) -> Self {
|
|
VecSeq { index: 0, vec, de }
|
|
}
|
|
}
|
|
|
|
impl<'de, 'a> SeqAccess<'de> for VecSeq<'a, 'de> {
|
|
type Error = Error;
|
|
|
|
fn next_element_seed<T>(&mut self, seed: T)
|
|
-> Result<Option<T::Value>> where T: DeserializeSeed<'de>
|
|
{
|
|
if self.index == self.vec.len() {
|
|
return Ok(None)
|
|
}
|
|
|
|
self.de.input = &self.vec[self.index];
|
|
self.index += 1;
|
|
let value = seed.deserialize(&mut *self.de)?;
|
|
Ok(Some(value))
|
|
}
|
|
}
|
|
|
|
pub struct DictMap<'a, 'de: 'a> {
|
|
pending: Option<&'de IOValue>,
|
|
iter: Box<dyn Iterator<Item = (&'de IOValue, &'de IOValue)> + 'a>,
|
|
de: &'a mut Deserializer<'de>,
|
|
}
|
|
|
|
impl<'de, 'a> DictMap<'a, 'de> {
|
|
fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self {
|
|
DictMap{ pending: None, iter: Box::new(d.iter()), de }
|
|
}
|
|
}
|
|
|
|
impl<'de, 'a> MapAccess<'de> for DictMap<'a, 'de> {
|
|
type Error = Error;
|
|
|
|
fn next_key_seed<K>(&mut self, seed: K)
|
|
-> Result<Option<K::Value>> where K: DeserializeSeed<'de>
|
|
{
|
|
match self.iter.next() {
|
|
None => Ok(None),
|
|
Some((k, v)) => {
|
|
self.pending = Some(v);
|
|
self.de.input = k;
|
|
Ok(Some(seed.deserialize(&mut *self.de)?))
|
|
}
|
|
}
|
|
}
|
|
|
|
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> where V: DeserializeSeed<'de> {
|
|
let v = self.pending.unwrap();
|
|
self.pending = None;
|
|
self.de.input = v;
|
|
Ok(seed.deserialize(&mut *self.de)?)
|
|
}
|
|
}
|
|
|
|
impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
|
|
type Error = Error;
|
|
type Variant = Self;
|
|
|
|
fn variant_seed<V>(self, seed: V)
|
|
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
|
|
{
|
|
let (lp, _) = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
|
|
let v = self.input;
|
|
self.input = IOValue::boxunwrap(lp);
|
|
let variant = seed.deserialize(&mut *self)?;
|
|
self.input = v;
|
|
Ok((variant, self))
|
|
}
|
|
}
|
|
|
|
impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
|
|
type Error = Error;
|
|
|
|
fn unit_variant(self) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
|
|
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
|
|
let (_, fs) = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
|
|
self.input = &fs[0];
|
|
seed.deserialize(&mut *self)
|
|
}
|
|
|
|
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
|
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record(None).unwrap().1))
|
|
}
|
|
|
|
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V)
|
|
-> Result<V::Value> where V: Visitor<'de>
|
|
{
|
|
visitor.visit_seq(VecSeq::new(self, &self.input.value().as_record(Some(fields.len())).unwrap().1))
|
|
}
|
|
}
|