preserves/implementations/rust/preserves/src/de.rs

480 lines
13 KiB
Rust

//! Support for Serde deserialization of Preserves terms described by Rust data types.
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::Deserialize;
use std::borrow::Cow;
use std::io;
use std::marker::PhantomData;
use super::value::boundary as B;
use super::value::reader::{BytesBinarySource, IOBinarySource, Reader};
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
pub use super::error::Error;
/// A [std::result::Result] type including [Error], the Preserves Serde deserialization error
/// type, as its error.
pub type Result<T> = std::result::Result<T, Error>;
/// Serde deserializer for Preserves-encoded Rust data. Use [Deserializer::from_reader] to
/// construct instances, or [from_bytes]/[from_text]/[from_read]/[from_reader] etc to
/// deserialize single terms directly.
pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
/// The underlying Preserves [reader][crate::value::reader::Reader].
pub read: &'r mut R,
phantom: PhantomData<&'de ()>,
}
/// Deserialize a `T` from `bytes`, which must contain a Preserves [machine-oriented binary
/// syntax][crate::value::packed] term corresponding to the Serde serialization of a `T`.
pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result<T>
where
T: Deserialize<'de>,
{
from_reader(&mut PackedReader::new(
&mut BytesBinarySource::new(bytes),
IOValueDomainCodec,
))
}
/// Deserialize a `T` from `text`, which must contain a Preserves [text
/// syntax][crate::value::text] term corresponding to the Serde serialization of a `T`.
pub fn from_text<'de, T>(text: &'de str) -> Result<T>
where
T: Deserialize<'de>,
{
from_reader(&mut TextReader::new(
&mut BytesBinarySource::new(text.as_bytes()),
ViaCodec::new(IOValueDomainCodec),
))
}
/// Deserialize a `T` from `read`, which must yield a Preserves [machine-oriented binary
/// syntax][crate::value::packed] term corresponding to the Serde serialization of a `T`.
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) -> Result<T>
where
T: Deserialize<'de>,
{
from_reader(&mut PackedReader::new(
&mut IOBinarySource::new(read),
IOValueDomainCodec,
))
}
/// Deserialize a `T` from `read`, which must yield a Preserves term corresponding to the Serde
/// serialization of a `T`.
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) -> Result<T>
where
T: Deserialize<'de>,
{
let mut de = Deserializer::from_reader(read);
let t = T::deserialize(&mut de)?;
Ok(t)
}
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> {
/// Construct a Deserializer from `read`, a Preserves [reader][crate::value::Reader].
pub fn from_reader(read: &'r mut R) -> Self {
Deserializer {
read,
phantom: PhantomData,
}
}
}
impl<'r, 'de, 'a, R: Reader<'de, IOValue>> serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R>
{
type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
// Won't support this here -- use value::de::Deserializer for this
Err(Error::CannotDeserializeAny)
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_bool(self.read.next_boolean()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i8(self.read.next_i8()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i16(self.read.next_i16()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i32(self.read.next_i32()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i64(self.read.next_i64()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u8(self.read.next_u8()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u16(self.read.next_u16()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u32(self.read.next_u32()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u64(self.read.next_u64()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.read.next_f64()? as f32)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_f64(self.read.next_f64()?)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_char(self.read.next_char()?)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.read.next_str()? {
Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
Cow::Owned(s) => visitor.visit_str(&s),
}
}
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>,
{
match self.read.next_bytestring()? {
Cow::Borrowed(bs) => visitor.visit_borrowed_bytes(bs),
Cow::Owned(bs) => visitor.visit_bytes(&bs),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_byte_buf(self.read.next_bytestring()?.into_owned())
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if let Some(mut b) = self.read.open_option()? {
self.read
.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
} else {
Ok(visitor.visit_none::<Error>()?)
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record("tuple", Some(0))?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record(name, Some(0))?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match super::value::magic::transmit_input_value(name, || {
Ok(self.read.demand_next(true)?)
})? {
Some(v) => visitor.visit_u64(v),
None => {
let mut b = self.read.open_simple_record(name, Some(1))?;
self.read
.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_newtype_struct(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
}
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
// Hack around serde's model: Deserialize *sets* as sequences,
// too, and reconstruct them as Rust Sets on the visitor side.
let i = self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), i))
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record("tuple", Some(len))?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
fn deserialize_tuple_struct<V>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record(name, Some(len))?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.read.open_dictionary()?;
let mut seq = Seq::new(self, B::Type::default(), B::Item::DictionaryKey);
let result = visitor.visit_map(&mut seq)?;
Ok(result)
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let b = self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
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>,
{
match self.read.next_symbol()? {
Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
Cow::Owned(s) => visitor.visit_str(&s),
}
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_none()
}
}
#[doc(hidden)]
pub struct Seq<'de, 'r, 'a, R: Reader<'de, IOValue>> {
b: B::Type,
i: B::Item,
de: &'a mut Deserializer<'de, 'r, R>,
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>, b: B::Type, i: B::Item) -> Self {
Seq { b, i, de }
}
fn skip_remainder(&mut self) -> Result<()> {
while !self.de.read.close_compound(&mut self.b, &self.i)? {
self.de.read.skip_value()?;
}
Ok(())
}
fn next_item<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
match self.de.read.close_compound(&mut self.b, &self.i)? {
true => Ok(None),
false => Ok(Some(seed.deserialize(&mut *self.de)?)),
}
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
Ok(self.next_item(seed)?)
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
self.i = B::Item::DictionaryKey;
self.next_item(seed)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
self.i = B::Item::DictionaryValue;
match self.next_item(seed)? {
Some(item) => Ok(item),
None => Err(Error::MissingItem),
}
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
type Error = Error;
type Variant = Seq<'de, 'r, 'a, R>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let b = self.read.open_record(None)?;
let variant = seed.deserialize(&mut *self)?;
Ok((variant, Seq::new(self, b, B::Item::RecordField)))
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn unit_variant(mut self) -> Result<()> {
self.skip_remainder()
}
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value>
where
T: DeserializeSeed<'de>,
{
match self.next_item(seed)? {
None => Err(Error::MissingItem),
Some(v) => {
self.skip_remainder()?;
Ok(v)
}
}
}
fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?;
Ok(result)
}
fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let result = visitor.visit_seq(&mut self)?;
self.skip_remainder()?;
Ok(result)
}
}