use std::collections::HashMap;
use std::fmt;
use std::marker::PhantomData;
use indexmap::IndexMap;
use serde::forward_to_deserialize_any;
use serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, SeqAccess, MapAccess, Visitor};
use crate::Label;
use crate::string::{GffString, StringKey};
use crate::value::Value;
macro_rules! string_key {
($method:ident, $type:ty) => (
#[inline]
fn $method<E>(self, value: $type) -> Result<Key, E>
where E: Error,
{
Ok(Key::String(StringKey(value as u32)))
}
);
}
enum Key {
Label(Label),
String(StringKey),
}
struct KeyVisitor;
impl<'de> Visitor<'de> for KeyVisitor {
type Value = Key;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string with length in UTF-8 <=16, byte buffer with length <=16, char or integer")
}
string_key!(visit_u8, u8);
string_key!(visit_i8, i8);
string_key!(visit_u16, u16);
string_key!(visit_i16, i16);
string_key!(visit_u32, u32);
string_key!(visit_i32, i32);
string_key!(visit_u64, u64);
string_key!(visit_i64, i64);
string_key!(visit_u128, u128);
string_key!(visit_i128, i128);
#[inline]
fn visit_char<E>(self, value: char) -> Result<Key, E>
where E: Error,
{
self.visit_string(value.to_string())
}
#[inline]
fn visit_str<E>(self, value: &str) -> Result<Key, E>
where E: Error,
{
self.visit_bytes(value.as_bytes())
}
#[inline]
fn visit_bytes<E>(self, value: &[u8]) -> Result<Key, E>
where E: Error,
{
use crate::error::Error::TooLongLabel;
match Label::from_bytes(value) {
Ok(label) => Ok(Key::Label(label)),
Err(TooLongLabel(len)) => Err(E::invalid_length(len, &self)),
Err(err) => Err(E::custom(err)), }
}
}
impl<'de> Deserialize<'de> for Key {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,
{
deserializer.deserialize_any(KeyVisitor)
}
}
struct LabelVisitor;
impl<'de> Visitor<'de> for LabelVisitor {
type Value = Label;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string with length in UTF-8 <=16, byte buffer with length <=16, or char")
}
#[inline]
fn visit_char<E>(self, value: char) -> Result<Label, E>
where E: Error,
{
self.visit_string(value.to_string())
}
#[inline]
fn visit_str<E>(self, value: &str) -> Result<Label, E>
where E: Error,
{
self.visit_bytes(value.as_bytes())
}
#[inline]
fn visit_bytes<E>(self, value: &[u8]) -> Result<Label, E>
where E: Error,
{
use crate::error::Error::TooLongLabel;
match Label::from_bytes(value) {
Ok(label) => Ok(label),
Err(TooLongLabel(len)) => Err(E::invalid_length(len, &self)),
Err(err) => Err(E::custom(err)), }
}
}
impl<'de> Deserialize<'de> for Label {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,
{
deserializer.deserialize_any(LabelVisitor)
}
}
#[derive(Debug)]
pub struct LabelDeserializer<E> {
value: Label,
marker: PhantomData<E>,
}
impl<'de, E> IntoDeserializer<'de, E> for Label
where E: Error,
{
type Deserializer = LabelDeserializer<E>;
#[inline]
fn into_deserializer(self) -> Self::Deserializer {
LabelDeserializer { value: self, marker: PhantomData }
}
}
impl<'de, E> Deserializer<'de> for LabelDeserializer<E>
where E: Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>,
{
if let Ok(str) = self.value.as_str() {
return visitor.visit_str(str);
}
visitor.visit_bytes(self.value.as_ref())
}
forward_to_deserialize_any!(
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum identifier ignored_any
);
}
macro_rules! value_from_primitive {
($name:ident, $type:ty => $variant:ident) => (
#[inline]
fn $name<E>(self, value: $type) -> Result<Value, E> {
Ok(Value::$variant(value.into()))
}
);
}
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid GFF value")
}
#[inline]
fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
Ok(Value::Byte(if value { 1 } else { 0 }))
}
value_from_primitive!(visit_i8 , i8 => Char);
value_from_primitive!(visit_i16, i16 => Short);
value_from_primitive!(visit_i32, i32 => Int);
value_from_primitive!(visit_i64, i64 => Int64);
value_from_primitive!(visit_u8 , u8 => Byte);
value_from_primitive!(visit_u16, u16 => Word);
value_from_primitive!(visit_u32, u32 => Dword);
value_from_primitive!(visit_u64, u64 => Dword64);
value_from_primitive!(visit_f32, f32 => Float);
value_from_primitive!(visit_f64, f64 => Double);
value_from_primitive!(visit_str, &str => String);
value_from_primitive!(visit_string, String => String);
value_from_primitive!(visit_bytes, &[u8] => Void);
value_from_primitive!(visit_byte_buf, Vec<u8> => Void);
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
where D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer)
}
#[inline]
fn visit_unit<E>(self) -> Result<Value, E> {
Ok(Value::Struct(IndexMap::with_capacity(0)))
}
#[inline]
fn visit_seq<V>(self, mut seq: V) -> Result<Value, V::Error>
where V: SeqAccess<'de>,
{
let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(elem) = seq.next_element()? {
vec.push(elem);
}
Ok(Value::List(vec))
}
fn visit_map<V>(self, mut map: V) -> Result<Value, V::Error>
where V: MapAccess<'de>,
{
let size = map.size_hint().unwrap_or(0);
if let Some(key) = map.next_key()? {
match key {
Key::Label(label) => {
let mut values = IndexMap::with_capacity(size);
values.insert(label, map.next_value()?);
while let Some((key, value)) = map.next_entry()? {
values.insert(key, value);
}
Ok(Value::Struct(values))
},
Key::String(key) => {
let mut values = HashMap::with_capacity(size);
values.insert(key, map.next_value()?);
while let Some((key, value)) = map.next_entry()? {
values.insert(StringKey(key), value);
}
Ok(Value::LocString(GffString::Internal(values).into()))
},
}
} else {
Ok(Value::Struct(IndexMap::with_capacity(0)))
}
}
}
impl<'de> Deserialize<'de> for Value {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
where D: Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor)
}
}
#[derive(Debug)]
pub struct ValueDeserializer<E> {
value: Value,
marker: PhantomData<E>,
}
impl<'de, E> IntoDeserializer<'de, E> for Value
where E: Error,
{
type Deserializer = ValueDeserializer<E>;
#[inline]
fn into_deserializer(self) -> Self::Deserializer {
ValueDeserializer { value: self, marker: PhantomData }
}
}
impl<'de, E> Deserializer<'de> for ValueDeserializer<E>
where E: Error,
{
type Error = E;
#[inline]
fn is_human_readable(&self) -> bool { false }
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>,
{
use self::Value::*;
match self.value {
Byte(val) => visitor.visit_u8(val),
Char(val) => visitor.visit_i8(val),
Word(val) => visitor.visit_u16(val),
Short(val) => visitor.visit_i16(val),
Dword(val) => visitor.visit_u32(val),
Int(val) => visitor.visit_i32(val),
Dword64(val) => visitor.visit_u64(val),
Int64(val) => visitor.visit_i64(val),
Float(val) => visitor.visit_f32(val),
Double(val) => visitor.visit_f64(val),
String(val) => visitor.visit_string(val),
ResRef(val) => {
if let Ok(str) = val.as_str() {
return visitor.visit_str(str);
}
visitor.visit_byte_buf(val.0)
},
LocString(val) => {
let value: GffString = val.into();
value.into_deserializer().deserialize_any(visitor)
},
Void(val) => visitor.visit_byte_buf(val),
Struct(val) => {
use serde::de::value::MapDeserializer;
MapDeserializer::new(val.into_iter()).deserialize_any(visitor)
},
List(val) => val.into_deserializer().deserialize_any(visitor),
}
}
forward_to_deserialize_any!(
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
string bytes byte_buf option unit unit_struct newtype_struct seq
tuple tuple_struct map struct enum identifier ignored_any
);
}