2022-11-18 15:26:44 +00:00
|
|
|
use std::collections::{hash_map, HashMap};
|
|
|
|
|
|
|
|
use serde::de::{
|
|
|
|
self, DeserializeSeed, EnumAccess, Error as DeError, MapAccess, SeqAccess, VariantAccess,
|
|
|
|
Visitor,
|
|
|
|
};
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
2022-12-15 13:45:27 +00:00
|
|
|
use crate::debug as fmtdebug;
|
2022-11-18 15:26:44 +00:00
|
|
|
use crate::dec::*;
|
|
|
|
use crate::serde::error::{Error, Result};
|
|
|
|
|
2022-11-18 18:11:40 +00:00
|
|
|
/// Serde deserializer for nettext
|
2022-11-18 15:26:44 +00:00
|
|
|
pub struct Deserializer<'de, 'a>(Term<'de, 'a>);
|
|
|
|
|
|
|
|
impl<'de, 'a> Deserializer<'de, 'a> {
|
2022-12-15 15:47:04 +00:00
|
|
|
pub fn from_term(input: &'a Term<'de, 'a>) -> Deserializer<'de, 'a> {
|
2022-12-15 13:45:27 +00:00
|
|
|
Deserializer(Term(input.0.mkref()))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-18 18:11:40 +00:00
|
|
|
/// Deserialize nettext from bytes
|
2022-11-18 15:26:44 +00:00
|
|
|
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);
|
2022-11-18 15:29:18 +00:00
|
|
|
T::deserialize(&mut deserializer)
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
2022-11-18 18:11:40 +00:00
|
|
|
/// 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)
|
|
|
|
}
|
|
|
|
|
2022-11-18 15:26:44 +00:00
|
|
|
// ----
|
|
|
|
|
|
|
|
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>,
|
|
|
|
{
|
2022-11-18 17:59:06 +00:00
|
|
|
Err(Error::custom(format!(
|
|
|
|
"deserialize_any not supported, at: `{}`",
|
|
|
|
self.0
|
|
|
|
)))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
2022-11-18 15:29:18 +00:00
|
|
|
.ok_or_else(|| Error::custom("invalid char: empty string"))?;
|
2022-11-18 15:26:44 +00:00
|
|
|
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>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [variant, args] = self.0.seq_of_first()?;
|
2022-11-18 15:26:44 +00:00
|
|
|
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>,
|
|
|
|
{
|
2022-12-15 13:45:27 +00:00
|
|
|
visitor.visit_seq(&mut Seq(&self.0.list()?))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
|
|
|
|
where
|
|
|
|
V: Visitor<'de>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
visitor.visit_seq(&mut Seq(&self.0.seq()))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn deserialize_tuple_struct<V>(
|
|
|
|
self,
|
|
|
|
name: &'static str,
|
|
|
|
_len: usize,
|
|
|
|
visitor: V,
|
|
|
|
) -> Result<V::Value>
|
|
|
|
where
|
|
|
|
V: Visitor<'de>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [variant, args] = self.0.seq_of_first()?;
|
2022-11-18 15:26:44 +00:00
|
|
|
if variant.string()? == name {
|
2022-12-15 12:32:38 +00:00
|
|
|
visitor.visit_seq(&mut Seq(&args.seq()))
|
2022-11-18 15:26:44 +00:00
|
|
|
} 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>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [variant, data] = self.0.seq_of()?;
|
2022-11-18 15:26:44 +00:00
|
|
|
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..];
|
|
|
|
|
2022-11-18 16:57:21 +00:00
|
|
|
seed.deserialize(&mut Deserializer::from_term(&first))
|
|
|
|
.map(Some)
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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>,
|
|
|
|
{
|
2022-11-18 15:29:18 +00:00
|
|
|
let k = self
|
|
|
|
.1
|
|
|
|
.ok_or_else(|| Error::custom("invald mapaccess order"))?;
|
2022-11-18 15:26:44 +00:00
|
|
|
let v = self
|
|
|
|
.0
|
|
|
|
.get(k)
|
2022-11-18 15:29:18 +00:00
|
|
|
.ok_or_else(|| Error::custom("invald mapaccess order"))?;
|
2022-11-18 15:26:44 +00:00
|
|
|
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>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let variant = &self.0.seq()[0];
|
2022-11-18 17:59:06 +00:00
|
|
|
let variant = seed.deserialize(&mut Deserializer(Term(variant.0.mkref())))?;
|
|
|
|
Ok((variant, self))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de, 'a> VariantAccess<'de> for Enum<'de, 'a> {
|
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn unit_variant(self) -> Result<()> {
|
2022-12-15 12:32:38 +00:00
|
|
|
if self.0.seq().len() > 1 {
|
2022-11-18 15:26:44 +00:00
|
|
|
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>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [_, rest] = self.0.seq_of_first()?;
|
2022-11-18 16:57:21 +00:00
|
|
|
seed.deserialize(&mut Deserializer(rest))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
|
|
|
|
where
|
|
|
|
V: Visitor<'de>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [_, rest] = self.0.seq_of_first()?;
|
|
|
|
visitor.visit_seq(&mut Seq(&rest.seq()))
|
2022-11-18 15:26:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
|
|
|
|
where
|
|
|
|
V: Visitor<'de>,
|
|
|
|
{
|
2022-12-15 12:32:38 +00:00
|
|
|
let [_, rest] = self.0.seq_of_first()?;
|
2022-11-18 15:26:44 +00:00
|
|
|
visitor.visit_map(&mut Dict::from_term(&rest)?)
|
|
|
|
}
|
|
|
|
}
|