use crate::asyncdatabase::Value;
use serde::de::{self, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};
use serde::de::value::Error as ValueError;
use serde::de::Error;
#[derive(Debug)]
pub struct EntityDeserializer {
value: Value,
}
impl EntityDeserializer {
pub fn from_value(value: Value) -> Self {
EntityDeserializer { value }
}
}
impl<'de> Deserializer<'de> for EntityDeserializer {
type Error = ValueError;
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Byte(i) => visitor.visit_u8(i),
_ => Err(Error::custom("Expected u8 value")),
}
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Int(i) => visitor.visit_i32(i),
_ => Err(Error::custom("Expected i32 value")),
}
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Bigint(i) => visitor.visit_i64(i),
_ => Err(Error::custom("Expected i64 value")),
}
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Float(f) => visitor.visit_f32(f),
_ => Err(Error::custom("Expected f32 value")),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Double(f) => visitor.visit_f64(f),
_ => Err(Error::custom("Expected f64 value")),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Boolean(b) => visitor.visit_bool(b),
_ => Err(Error::custom("Expected boolean value")),
}
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Text(s) => visitor.visit_string(s),
Value::Bytes(s) => visitor.visit_bytes(&s),
_ => Err(Error::custom("Expected string value")),
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Text(s) => visitor.visit_str(&s),
Value::Bytes(s) => visitor.visit_bytes(&s),
_ => Err(Error::custom("Expected string value")),
}
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Bytes(b) => visitor.visit_bytes(&b),
_ => Err(Error::custom("Expected bytes value")),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Bytes(b) => visitor.visit_byte_buf(b),
_ => Err(Error::custom("Expected bytes value")),
}
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Table(fields) => {
let deserializer = StructDeserializer { fields, current: 0 };
visitor.visit_map(deserializer)
}
_ => Err(Error::custom("Expected struct value")),
}
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Null => visitor.visit_none(),
_ => visitor.visit_some(self),
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Bytes(ref bytes) => {
let vec_values: Vec<Value> = bincode::deserialize(bytes).unwrap();
let seq_access = EntitySeqAccess::new(vec_values);
visitor.visit_seq(seq_access)
}
_ => Err(de::Error::custom("Expected Value::Bytes for sequence")),
}
}
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.value {
Value::Null => visitor.visit_unit(),
Value::Boolean(b) => visitor.visit_bool(b),
Value::Int(i) => visitor.visit_i32(i),
Value::Bigint(i) => visitor.visit_i64(i),
Value::Float(f) => visitor.visit_f32(f),
Value::Double(f) => visitor.visit_f64(f),
Value::Text(s) => visitor.visit_string(s),
Value::Bytes(b) => visitor.visit_byte_buf(b), Value::Table(_) => self.deserialize_struct("", &[], visitor),
_ => Err(Error::custom("Unsupported value type for deserialize_any")),
}
}
serde::forward_to_deserialize_any! {
i8 i16 i128
u16 u32 u64 u128
char
unit unit_struct
newtype_struct tuple
tuple_struct map enum
identifier ignored_any
}
}
struct StructDeserializer {
fields: Vec<(String, Value)>,
current: usize,
}
impl<'de> MapAccess<'de> for StructDeserializer {
type Error = ValueError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeSeed<'de>,
{
if let Some((key, _value)) = self.fields.get(self.current) {
let key_de = EntityDeserializer::from_value(Value::Text(key.clone()));
seed.deserialize(key_de).map(Some)
} else {
Ok(None)
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeSeed<'de>,
{
if let Some((_, value)) = self.fields.get(self.current) {
let value_de = EntityDeserializer::from_value(value.clone());
self.current += 1;
seed.deserialize(value_de)
} else {
Err(Error::custom("Expected value"))
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.fields.len())
}
}
pub struct EntitySeqAccess {
values: Vec<Value>,
index: usize,
}
impl EntitySeqAccess {
pub fn new(values: Vec<Value>) -> Self {
EntitySeqAccess { values, index: 0 }
}
}
impl<'de> SeqAccess<'de> for EntitySeqAccess {
type Error = ValueError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
if self.index >= self.values.len() {
Ok(None)
} else {
let value = self.values[self.index].clone();
self.index += 1;
let deserializer = EntityDeserializer::from_value(value);
seed.deserialize(deserializer).map(Some)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Deserialize;
#[test]
fn test_deserialize_i32() {
let value = Value::Int(42);
let de = EntityDeserializer::from_value(value);
let result = i32::deserialize(de).unwrap();
assert_eq!(result, 42);
}
#[test]
fn test_deserialize_i64() {
let value = Value::Bigint(1234567890);
let de = EntityDeserializer::from_value(value);
let result = i64::deserialize(de).unwrap();
assert_eq!(result, 1234567890);
}
#[test]
fn test_deserialize_f32() {
let value = Value::Float(3.14);
let de = EntityDeserializer::from_value(value);
let result = f32::deserialize(de).unwrap();
assert_eq!(result, 3.14);
}
#[test]
fn test_deserialize_f64() {
let value = Value::Double(2.71828);
let de = EntityDeserializer::from_value(value);
let result = f64::deserialize(de).unwrap();
const F: f64 = 2.71828;
assert_eq!(result, F);
}
#[test]
fn test_deserialize_bool() {
let value = Value::Boolean(true);
let de = EntityDeserializer::from_value(value);
let result = bool::deserialize(de).unwrap();
assert!(result);
}
#[test]
fn test_deserialize_string() {
let value = Value::Text("hello".to_string());
let de = EntityDeserializer::from_value(value);
let result = String::deserialize(de).unwrap();
assert_eq!(result, "hello");
}
#[test]
fn test_deserialize_option_some() {
let value = Value::Text("hello".to_string());
let de = EntityDeserializer::from_value(value);
let result = Option::<String>::deserialize(de).unwrap();
assert_eq!(result, Some("hello".to_string()));
}
#[test]
fn test_deserialize_option_none() {
let value = Value::Null;
let de = EntityDeserializer::from_value(value);
let result = Option::<String>::deserialize(de).unwrap();
assert_eq!(result, None);
}
#[test]
fn test_deserialize_struct() {
#[derive(Deserialize, Debug, PartialEq)]
struct TestStruct {
a: i32,
b: String,
}
let fields = vec![
("a".to_string(), Value::Int(42)),
("b".to_string(), Value::Text("hello".to_string())),
];
let value = Value::Table(fields);
let de = EntityDeserializer::from_value(value);
let result = TestStruct::deserialize(de).unwrap();
assert_eq!(
result,
TestStruct {
a: 42,
b: "hello".to_string()
}
);
}
}