use crate::Row;
use crate::error::{Error, Result};
use crate::row_metadata::RowMetadata;
use crate::rowbinary::utils::{ensure_size, get_unsigned_leb128};
use crate::rowbinary::validation::{DataTypeValidator, SchemaValidator, SerdeType};
use crate::types::int256;
use bytes::Buf;
use core::mem::size_of;
use serde::de::MapAccess;
use serde::de::value::BytesDeserializer;
use serde::{
Deserialize,
de::{DeserializeSeed, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor},
};
use std::marker::PhantomData;
use std::{convert::TryFrom, str};
pub(crate) fn deserialize_row<'data, 'cursor, T: Deserialize<'data> + Row>(
input: &mut &'data [u8],
metadata: Option<&'cursor RowMetadata>,
) -> Result<T> {
match metadata {
Some(metadata) => deserialize_row_with_validation(input, metadata),
None => deserialize_row_without_validation(input),
}
}
fn deserialize_row_without_validation<'data, 'cursor, T: Deserialize<'data> + Row>(
input: &mut &'data [u8],
) -> Result<T> {
let mut deserializer = RowBinaryDeserializer::<T, _>::new(input, ());
T::deserialize(&mut deserializer)
}
fn deserialize_row_with_validation<'data, 'cursor, T: Deserialize<'data> + Row>(
input: &mut &'data [u8],
metadata: &'cursor RowMetadata,
) -> Result<T> {
let validator = DataTypeValidator::new(metadata);
let mut deserializer = RowBinaryDeserializer::<T, _>::new(input, validator);
T::deserialize(&mut deserializer)
}
struct RowBinaryDeserializer<'cursor, 'data, R: Row, V = ()>
where
V: SchemaValidator<R>,
{
input: &'cursor mut &'data [u8],
validator: V,
_marker: PhantomData<R>,
}
impl<'cursor, 'data, R: Row, V> RowBinaryDeserializer<'cursor, 'data, R, V>
where
V: SchemaValidator<R>,
{
fn new(input: &'cursor mut &'data [u8], validator: V) -> Self {
Self {
input,
validator,
_marker: PhantomData,
}
}
fn inner(
&mut self,
serde_type: SerdeType,
) -> Result<RowBinaryDeserializer<'_, 'data, R, V::Inner<'_>>> {
let validator = self.validator.validate(serde_type)?;
Ok(RowBinaryDeserializer {
validator,
input: self.input,
_marker: PhantomData,
})
}
fn read_vec(&mut self, size: usize) -> Result<Vec<u8>> {
Ok(self.read_slice(size)?.to_vec())
}
fn read_slice(&mut self, size: usize) -> Result<&'data [u8]> {
ensure_size(&mut self.input, size)?;
let slice = &self.input[..size];
self.input.advance(size);
Ok(slice)
}
fn read_size(&mut self) -> Result<usize> {
let size = get_unsigned_leb128(&mut self.input)?;
usize::try_from(size).map_err(|_| Error::NotEnoughData)
}
}
macro_rules! impl_num {
($ty:ty, $deser_method:ident, $visitor_method:ident, $reader_method:ident, $serde_type:expr) => {
#[inline(always)]
fn $deser_method<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
self.validator.validate($serde_type)?;
ensure_size(&mut self.input, core::mem::size_of::<$ty>())?;
let value = self.input.$reader_method();
visitor.$visitor_method(value)
}
};
}
macro_rules! impl_num_or_enum {
($ty:ty, $deser_method:ident, $visitor_method:ident, $reader_method:ident, $serde_type:expr) => {
#[inline(always)]
fn $deser_method<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
let mut maybe_enum_validator = self.validator.validate($serde_type)?;
ensure_size(&mut self.input, core::mem::size_of::<$ty>())?;
let value = self.input.$reader_method();
maybe_enum_validator.validate_identifier::<$ty>(value)?;
visitor.$visitor_method(value)
}
};
}
impl<'data, R: Row, Validator> Deserializer<'data>
for &mut RowBinaryDeserializer<'_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
impl_num_or_enum!(i8, deserialize_i8, visit_i8, get_i8, SerdeType::I8);
impl_num_or_enum!(i16, deserialize_i16, visit_i16, get_i16_le, SerdeType::I16);
impl_num!(i32, deserialize_i32, visit_i32, get_i32_le, SerdeType::I32);
impl_num!(i64, deserialize_i64, visit_i64, get_i64_le, SerdeType::I64);
#[rustfmt::skip]
impl_num!(i128, deserialize_i128, visit_i128, get_i128_le, SerdeType::I128);
impl_num!(u8, deserialize_u8, visit_u8, get_u8, SerdeType::U8);
impl_num!(u16, deserialize_u16, visit_u16, get_u16_le, SerdeType::U16);
impl_num!(u32, deserialize_u32, visit_u32, get_u32_le, SerdeType::U32);
impl_num!(u64, deserialize_u64, visit_u64, get_u64_le, SerdeType::U64);
#[rustfmt::skip]
impl_num!(u128, deserialize_u128, visit_u128, get_u128_le, SerdeType::U128);
impl_num!(f32, deserialize_f32, visit_f32, get_f32_le, SerdeType::F32);
impl_num!(f64, deserialize_f64, visit_f64, get_f64_le, SerdeType::F64);
#[inline(always)]
fn deserialize_any<V: Visitor<'data>>(self, _: V) -> Result<V::Value> {
Err(Error::DeserializeAnyNotSupported)
}
#[inline(always)]
fn deserialize_unit<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
visitor.visit_unit()
}
#[inline(always)]
fn deserialize_bool<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
self.validator.validate(SerdeType::Bool)?;
ensure_size(&mut self.input, 1)?;
match self.input.get_u8() {
0 => visitor.visit_bool(false),
1 => visitor.visit_bool(true),
v => Err(Error::InvalidTagEncoding(v as usize)),
}
}
#[inline(always)]
fn deserialize_str<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
self.validator.validate(SerdeType::Str)?;
let size = self.read_size()?;
let slice = self.read_slice(size)?;
let str = str::from_utf8(slice).map_err(Error::from)?;
visitor.visit_borrowed_str(str)
}
#[inline(always)]
fn deserialize_string<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
self.validator.validate(SerdeType::String)?;
let size = self.read_size()?;
let vec = self.read_vec(size)?;
let string = String::from_utf8(vec).map_err(|err| Error::from(err.utf8_error()))?;
visitor.visit_string(string)
}
#[inline(always)]
fn deserialize_bytes<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
let size = self.read_size()?;
self.validator.validate(SerdeType::Bytes(size))?;
let slice = self.read_slice(size)?;
visitor.visit_borrowed_bytes(slice)
}
#[inline(always)]
fn deserialize_byte_buf<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
let size = self.read_size()?;
self.validator.validate(SerdeType::ByteBuf(size))?;
visitor.visit_byte_buf(self.read_vec(size)?)
}
#[inline(always)]
fn deserialize_identifier<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
ensure_size(&mut self.input, size_of::<u8>())?;
let value = self.input.get_u8();
self.validator.validate_identifier::<u8>(value)?;
visitor.visit_u8(value)
}
#[inline(always)]
fn deserialize_enum<V: Visitor<'data>>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value> {
let deserializer = &mut self.inner(SerdeType::Variant)?;
visitor.visit_enum(RowBinaryEnumAccess { deserializer })
}
#[inline(always)]
fn deserialize_tuple<V: Visitor<'data>>(self, len: usize, visitor: V) -> Result<V::Value> {
let deserializer = &mut self.inner(SerdeType::Tuple(len))?;
visitor.visit_seq(RowBinaryTupleSeqAccess { deserializer, len })
}
#[inline(always)]
fn deserialize_option<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
ensure_size(&mut self.input, 1)?;
let is_null = self.input.get_u8();
let deserializer = &mut self.inner(SerdeType::Option)?;
match is_null {
0 => visitor.visit_some(deserializer),
1 => visitor.visit_none(),
v => Err(Error::InvalidTagEncoding(v as usize)),
}
}
#[inline(always)]
fn deserialize_seq<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
let len = self.read_size()?;
let deserializer = &mut self.inner(SerdeType::Seq(len))?;
visitor.visit_seq(RowBinarySeqAccess { deserializer, len })
}
#[inline(always)]
fn deserialize_map<V: Visitor<'data>>(self, visitor: V) -> Result<V::Value> {
let len = self.read_size()?;
let deserializer = &mut self.inner(SerdeType::Map(len))?;
visitor.visit_map(RowBinaryMapAccess {
deserializer,
remaining: len,
})
}
#[inline(always)]
fn deserialize_struct<V: Visitor<'data>>(
self,
_name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value> {
if !self.validator.is_field_order_wrong() {
visitor.visit_seq(RowBinarySeqAccess {
deserializer: self,
len: fields.len(),
})
} else {
visitor.visit_map(RowBinaryStructAsMapAccess {
deserializer: self,
current_field_idx: 0,
fields,
})
}
}
#[inline(always)]
fn deserialize_newtype_struct<V: Visitor<'data>>(
self,
name: &str,
visitor: V,
) -> Result<V::Value> {
if name.starts_with(int256::MODULE_PATH) {
self.validator
.validate(SerdeType::Bytes(int256::BYTE_LEN))?;
let slice = self.read_slice(int256::BYTE_LEN)?;
BytesDeserializer::new(slice).deserialize_bytes(visitor)
} else {
visitor.visit_newtype_struct(self)
}
}
#[inline(always)]
fn deserialize_char<V: Visitor<'data>>(self, _: V) -> Result<V::Value> {
panic!("character types are unsupported: `char`");
}
#[inline(always)]
fn deserialize_unit_struct<V: Visitor<'data>>(
self,
name: &'static str,
_visitor: V,
) -> Result<V::Value> {
panic!("unit types are unsupported: `{name}`");
}
#[inline(always)]
fn deserialize_tuple_struct<V: Visitor<'data>>(
self,
name: &'static str,
_len: usize,
_visitor: V,
) -> Result<V::Value> {
panic!("tuple struct types are unsupported: `{name}`");
}
#[inline(always)]
fn deserialize_ignored_any<V: Visitor<'data>>(self, _visitor: V) -> Result<V::Value> {
panic!("ignored types are unsupported");
}
#[inline(always)]
fn is_human_readable(&self) -> bool {
false
}
}
struct RowBinaryTupleSeqAccess<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
len: usize,
}
impl<'data, R: Row, Validator> SeqAccess<'data>
for RowBinaryTupleSeqAccess<'_, '_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'data>,
{
if self.len > 0 {
self.len -= 1;
let value = DeserializeSeed::deserialize(seed, &mut *self.deserializer)?;
if self.len == 0 {
self.deserializer.validator.check_tuple_fully_validated()?;
}
Ok(Some(value))
} else {
Ok(None)
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}
struct RowBinarySeqAccess<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
len: usize,
}
impl<'data, R: Row, Validator> SeqAccess<'data> for RowBinarySeqAccess<'_, '_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'data>,
{
if self.len > 0 {
self.len -= 1;
let value = DeserializeSeed::deserialize(seed, &mut *self.deserializer)?;
Ok(Some(value))
} else {
Ok(None)
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.len)
}
}
struct RowBinaryMapAccess<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
remaining: usize,
}
impl<'data, R: Row, Validator> MapAccess<'data> for RowBinaryMapAccess<'_, '_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'data>,
{
if self.remaining == 0 {
return Ok(None);
}
self.remaining -= 1;
seed.deserialize(&mut *self.deserializer).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'data>,
{
seed.deserialize(&mut *self.deserializer)
}
fn size_hint(&self) -> Option<usize> {
Some(self.remaining)
}
}
struct RowBinaryStructAsMapAccess<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
current_field_idx: usize,
fields: &'static [&'static str],
}
struct StructFieldIdentifier(&'static str);
impl<'de> Deserializer<'de> for StructFieldIdentifier {
type Error = Error;
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_borrowed_str(self.0)
}
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
panic!("StructFieldIdentifier is supposed to use `deserialize_identifier` only");
}
serde::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 ignored_any
}
}
impl<'data, R: Row, Validator> MapAccess<'data>
for RowBinaryStructAsMapAccess<'_, '_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'data>,
{
if self.current_field_idx >= self.fields.len() {
return Ok(None);
}
let schema_index = self
.deserializer
.validator
.get_schema_index(self.current_field_idx)?;
let field_id = StructFieldIdentifier(self.fields[schema_index]);
self.current_field_idx += 1;
seed.deserialize(field_id).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'data>,
{
seed.deserialize(&mut *self.deserializer)
}
fn size_hint(&self) -> Option<usize> {
Some(self.fields.len())
}
}
struct RowBinaryEnumAccess<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
}
struct VariantDeserializer<'de, 'cursor, 'data, R: Row, Validator>
where
Validator: SchemaValidator<R>,
{
deserializer: &'de mut RowBinaryDeserializer<'cursor, 'data, R, Validator>,
}
impl<'data, R: Row, Validator> VariantAccess<'data>
for VariantDeserializer<'_, '_, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
fn unit_variant(self) -> Result<()> {
panic!("unit variants are unsupported");
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: DeserializeSeed<'data>,
{
DeserializeSeed::deserialize(seed, &mut *self.deserializer)
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'data>,
{
self.deserializer.deserialize_tuple(len, visitor)
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'data>,
{
self.deserializer.deserialize_tuple(fields.len(), visitor)
}
}
impl<'de, 'cursor, 'data, R: Row, Validator> EnumAccess<'data>
for RowBinaryEnumAccess<'de, 'cursor, 'data, R, Validator>
where
Validator: SchemaValidator<R>,
{
type Error = Error;
type Variant = VariantDeserializer<'de, 'cursor, 'data, R, Validator>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where
T: DeserializeSeed<'data>,
{
let value = seed.deserialize(&mut *self.deserializer)?;
let deserializer = VariantDeserializer {
deserializer: self.deserializer,
};
Ok((value, deserializer))
}
}