/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashMap;
use std::collections::HashSet;
use std::hash::Hash;
use std::sync::Arc;
use bytes::Bytes;
use ordered_float::OrderedFloat;
use crate::protocol::should_break;
use crate::protocol::ProtocolReader;
use crate::Result;
// Read trait. Every type that needs to be deserialized will implement this trait.
pub trait Deserialize
: Sized
where
P: ProtocolReader,
{
fn read(p: &mut P) -> Result;
}
impl Deserialize
for Box
where
P: ProtocolReader,
T: Deserialize,
{
#[inline]
fn read(p: &mut P) -> Result {
T::read(p).map(Box::new)
}
}
impl Deserialize
for Arc
where
P: ProtocolReader,
T: Deserialize,
{
fn read(p: &mut P) -> Result {
T::read(p).map(Arc::new)
}
}
impl Deserialize
for ()
where
P: ProtocolReader,
{
#[inline]
fn read(_p: &mut P) -> Result {
Ok(())
}
}
impl Deserialize
for bool
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_bool()
}
}
impl Deserialize
for i8
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_byte()
}
}
impl Deserialize
for i16
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_i16()
}
}
impl Deserialize
for i32
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_i32()
}
}
impl Deserialize
for i64
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_i64()
}
}
impl Deserialize
for f64
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_double()
}
}
impl Deserialize
for f32
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_float()
}
}
impl Deserialize
for OrderedFloat
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_double().map(OrderedFloat)
}
}
impl Deserialize
for OrderedFloat
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_float().map(OrderedFloat)
}
}
impl Deserialize
for String
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_string()
}
}
impl Deserialize
for Bytes
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_binary()
}
}
impl Deserialize
for Vec
where
P: ProtocolReader,
{
#[inline]
fn read(p: &mut P) -> Result {
p.read_binary()
}
}
impl Deserialize
for BTreeSet
where
P: ProtocolReader,
T: Deserialize + Ord,
{
fn read(p: &mut P) -> Result {
let (_elem_ty, len) = p.read_set_begin()?;
let mut bset = BTreeSet::new();
if let Some(0) = len {
return Ok(bset);
}
let mut idx = 0;
loop {
let more = p.read_set_value_begin()?;
if !more {
break;
}
let item = Deserialize::read(p)?;
p.read_set_value_end()?;
bset.insert(item);
idx += 1;
if should_break(len, more, idx) {
break;
}
}
p.read_set_end()?;
Ok(bset)
}
}
impl Deserialize
for HashSet
where
P: ProtocolReader,
T: Deserialize + Hash + Eq,
S: std::hash::BuildHasher + Default,
{
fn read(p: &mut P) -> Result {
let (_elem_ty, len) = p.read_set_begin()?;
let mut hset =
HashSet::with_capacity_and_hasher(len.unwrap_or_default(), Default::default());
if let Some(0) = len {
return Ok(hset);
}
let mut idx = 0;
loop {
let more = p.read_set_value_begin()?;
if !more {
break;
}
let item = Deserialize::read(p)?;
p.read_set_value_end()?;
hset.insert(item);
idx += 1;
if should_break(len, more, idx) {
break;
}
}
p.read_set_end()?;
Ok(hset)
}
}
impl Deserialize
for BTreeMap
where
P: ProtocolReader,
K: Deserialize + Ord,
V: Deserialize
,
{
fn read(p: &mut P) -> Result {
let (_key_ty, _val_ty, len) = p.read_map_begin()?;
let mut btree = BTreeMap::new();
if let Some(0) = len {
return Ok(btree);
}
let mut idx = 0;
loop {
let more = p.read_map_key_begin()?;
if !more {
break;
}
let key = Deserialize::read(p)?;
p.read_map_value_begin()?;
let val = Deserialize::read(p)?;
p.read_map_value_end()?;
btree.insert(key, val);
idx += 1;
if should_break(len, more, idx) {
break;
}
}
p.read_map_end()?;
Ok(btree)
}
}
impl Deserialize
for HashMap
where
P: ProtocolReader,
K: Deserialize + Hash + Eq,
V: Deserialize
,
S: std::hash::BuildHasher + Default,
{
fn read(p: &mut P) -> Result {
let (_key_ty, _val_ty, len) = p.read_map_begin()?;
let mut hmap =
HashMap::with_capacity_and_hasher(len.unwrap_or_default(), Default::default());
if let Some(0) = len {
return Ok(hmap);
}
let mut idx = 0;
loop {
let more = p.read_map_key_begin()?;
if !more {
break;
}
let key = Deserialize::read(p)?;
p.read_map_value_begin()?;
let val = Deserialize::read(p)?;
p.read_map_value_end()?;
hmap.insert(key, val);
idx += 1;
if should_break(len, more, idx) {
break;
}
}
p.read_map_end()?;
Ok(hmap)
}
}
impl Deserialize
for Vec
where
P: ProtocolReader,
T: Deserialize + crate::ttype::GetTType, // GetTType just to exclude Vec
{
/// Vec is Thrift List type
fn read(p: &mut P) -> Result {
let (_elem_ty, len) = p.read_list_begin()?;
let mut list = Vec::with_capacity(len.unwrap_or_default());
if let Some(0) = len {
return Ok(list);
}
let mut idx = 0;
loop {
let more = p.read_list_value_begin()?;
if !more {
break;
}
let item = Deserialize::read(p)?;
p.read_list_value_end()?;
list.push(item);
idx += 1;
if should_break(len, more, idx) {
break;
}
}
p.read_list_end()?;
Ok(list)
}
}