nettext/src/serde/de.rs

454 lines
11 KiB
Rust

use std::collections::{hash_map, HashMap};
use serde::de::{
self, DeserializeSeed, EnumAccess, Error as DeError, MapAccess, SeqAccess, VariantAccess,
Visitor,
};
use serde::Deserialize;
use crate::debug as fmtdebug;
use crate::dec::*;
use crate::serde::error::{Error, Result};
/// Serde deserializer for nettext
pub struct Deserializer<'de, 'a>(Term<'de, 'a>);
impl<'de, 'a> Deserializer<'de, 'a> {
fn from_term(input: &'a Term<'de, 'a>) -> Deserializer<'de, 'a> {
Deserializer(Term(input.0.mkref()))
}
}
/// Deserialize nettext from bytes
pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T>
where
T: Deserialize<'a>,
{
let term = decode(s)?;
let mut deserializer = Deserializer::from_term(&term);
T::deserialize(&mut deserializer)
}
/// Deserialize nettext from decoded term
pub fn from_term<'a, T>(term: &'a Term<'a, 'a>) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::from_term(term);
T::deserialize(&mut deserializer)
}
// ----
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de, 'a> {
type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
Err(Error::custom(format!(
"deserialize_any not supported, at: `{}`",
self.0
)))
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let value = match self.0.string()? {
"true" => true,
"false" => false,
_ => return Err(Error::custom("Invalid boolean litteral")),
};
visitor.visit_bool(value)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i8(self.0.string()?.parse()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i16(self.0.string()?.parse()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i32(self.0.string()?.parse()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_i64(self.0.string()?.parse()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u8(self.0.string()?.parse()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u16(self.0.string()?.parse()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u32(self.0.string()?.parse()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_u64(self.0.string()?.parse()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.0.string()?.parse()?)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_f64(self.0.string()?.parse()?)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let s = String::from_utf8(self.0.bytes()?)?;
let mut chars = s.chars();
let c = chars
.next()
.ok_or_else(|| Error::custom("invalid char: empty string"))?;
if chars.next().is_some() {
Err(Error::custom("invalid char: too many chars"))
} else {
visitor.visit_char(c)
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let s = String::from_utf8(self.0.bytes()?)?;
visitor.visit_string(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>,
{
visitor.visit_byte_buf(self.0.bytes()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_byte_buf(self.0.bytes()?)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if self.0.dict_of::<0, &[u8]>([], false).is_ok() {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if self.0.dict_of::<0, &[u8]>([], false).is_ok() {
visitor.visit_unit()
} else {
Err(Error::custom(format!(
"Expected unit, got: `{}`",
fmtdebug(self.0.raw())
)))
}
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
if self.0.string()? == name {
visitor.visit_unit()
} else {
Err(Error::custom(format!(
"Expected {}, got: `{}`",
name,
fmtdebug(self.0.raw())
)))
}
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let [variant, args] = self.0.seq_of_first()?;
if variant.string()? == name {
visitor.visit_newtype_struct(&mut Deserializer(args))
} else {
Err(Error::custom(format!(
"Expected {}, got: `{}`",
name,
fmtdebug(variant.raw())
)))
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_seq(&mut Seq(&self.0.list()?))
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_seq(&mut Seq(&self.0.seq()))
}
fn deserialize_tuple_struct<V>(
self,
name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let [variant, args] = self.0.seq_of_first()?;
if variant.string()? == name {
visitor.visit_seq(&mut Seq(&args.seq()))
} else {
Err(Error::custom(format!(
"Expected {}, got: `{}`",
name,
fmtdebug(variant.raw())
)))
}
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_map(&mut Dict::from_term(&self.0)?)
}
fn deserialize_struct<V>(
self,
name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let [variant, data] = self.0.seq_of()?;
if variant.string()? != name {
return Err(Error::custom(format!(
"Expected {}, got: `{}`",
name,
fmtdebug(variant.raw())
)));
}
Deserializer(data).deserialize_map(visitor)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_enum(Enum(&self.0))
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let s = self.0.string()?;
match s.split_once('.') {
Some((_a, b)) => visitor.visit_borrowed_str(b),
None => visitor.visit_borrowed_str(s),
}
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
pub struct Seq<'de, 'a>(&'a [Term<'de, 'a>]);
impl<'de, 'a> SeqAccess<'de> for &'a mut Seq<'de, 'a> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
// Check if there are no more elements.
if self.0.is_empty() {
return Ok(None);
}
let first = Term(self.0[0].0.mkref());
self.0 = &self.0[1..];
seed.deserialize(&mut Deserializer::from_term(&first))
.map(Some)
}
}
pub struct Dict<'de, 'a>(
&'a HashMap<&'de [u8], AnyTerm<'de, 'a>>,
Option<&'de [u8]>,
hash_map::Keys<'a, &'de [u8], AnyTerm<'de, 'a>>,
);
impl<'de, 'a> Dict<'de, 'a> {
fn from_term(t: &'a Term<'de, 'a>) -> Result<Dict<'de, 'a>> {
match t.0.mkref() {
AnyTerm::DictRef(_, d) => Ok(Dict(d, None, d.keys())),
_ => Err(Error::custom("expected a DICT")),
}
}
}
impl<'de, 'a> MapAccess<'de> for &'a mut Dict<'de, 'a> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
match self.2.next() {
None => Ok(None),
Some(k) => {
self.1 = Some(k);
seed.deserialize(&mut Deserializer(Term(AnyTerm::Str(k))))
.map(Some)
}
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
let k = self
.1
.ok_or_else(|| Error::custom("invald mapaccess order"))?;
let v = self
.0
.get(k)
.ok_or_else(|| Error::custom("invald mapaccess order"))?;
seed.deserialize(&mut Deserializer(Term(v.mkref())))
}
}
// ----
struct Enum<'de, 'a>(&'a Term<'de, 'a>);
impl<'de, 'a> EnumAccess<'de> for Enum<'de, 'a> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let variant = &self.0.seq()[0];
let variant = seed.deserialize(&mut Deserializer(Term(variant.0.mkref())))?;
Ok((variant, self))
}
}
impl<'de, 'a> VariantAccess<'de> for Enum<'de, 'a> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
if self.0.seq().len() > 1 {
Err(Error::custom("Spurrious data in unit variant"))
} else {
Ok(())
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: DeserializeSeed<'de>,
{
let [_, rest] = self.0.seq_of_first()?;
seed.deserialize(&mut Deserializer(rest))
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let [_, rest] = self.0.seq_of_first()?;
visitor.visit_seq(&mut Seq(&rest.seq()))
}
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let [_, rest] = self.0.seq_of_first()?;
visitor.visit_map(&mut Dict::from_term(&rest)?)
}
}