diff --git a/parquet/CONTRIBUTING.md b/parquet/CONTRIBUTING.md index 903126d9f4f8..5670eef08101 100644 --- a/parquet/CONTRIBUTING.md +++ b/parquet/CONTRIBUTING.md @@ -62,10 +62,6 @@ To compile and view in the browser, run `cargo doc --no-deps --open`. ## Update Parquet Format -To generate the parquet format (thrift definitions) code run from the repository root run - -``` -$ docker run -v $(pwd):/thrift/src -it archlinux pacman -Sy --noconfirm thrift && wget https://raw.githubusercontent.com/apache/parquet-format/apache-parquet-format-2.9.0/src/main/thrift/parquet.thrift -O /tmp/parquet.thrift && thrift --gen rs /tmp/parquet.thrift && sed -i '/use thrift::server::TProcessor;/d' parquet.rs && mv parquet.rs parquet/src/format.rs -``` +To generate the parquet format (thrift definitions) code run [`./regen.sh`](./regen.sh). You may need to manually patch up doc comments that contain unescaped `[]` diff --git a/parquet/Cargo.toml b/parquet/Cargo.toml index c710c83213b9..eaafb5130fcb 100644 --- a/parquet/Cargo.toml +++ b/parquet/Cargo.toml @@ -173,5 +173,10 @@ name = "compression" required-features = ["experimental", "default"] harness = false + +[[bench]] +name = "metadata" +harness = false + [lib] bench = false diff --git a/parquet/benches/metadata.rs b/parquet/benches/metadata.rs new file mode 100644 index 000000000000..c817385f6ba9 --- /dev/null +++ b/parquet/benches/metadata.rs @@ -0,0 +1,42 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 bytes::Bytes; +use criterion::*; +use parquet::file::reader::SerializedFileReader; +use parquet::file::serialized_reader::ReadOptionsBuilder; + +fn criterion_benchmark(c: &mut Criterion) { + // Read file into memory to isolate filesystem performance + let file = "../parquet-testing/data/alltypes_tiny_pages.parquet"; + let data = std::fs::read(file).unwrap(); + let data = Bytes::from(data); + + c.bench_function("open(default)", |b| { + b.iter(|| SerializedFileReader::new(data.clone()).unwrap()) + }); + + c.bench_function("open(page index)", |b| { + b.iter(|| { + let options = ReadOptionsBuilder::new().with_page_index().build(); + SerializedFileReader::new_with_options(data.clone(), options).unwrap() + }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/parquet/regen.sh b/parquet/regen.sh new file mode 100755 index 000000000000..b8c3549e2324 --- /dev/null +++ b/parquet/regen.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +REVISION=aeae80660c1d0c97314e9da837de1abdebd49c37 + +SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" + +docker run -v $SOURCE_DIR:/thrift/src -it archlinux pacman -Sy --noconfirm thrift && \ + wget https://raw.githubusercontent.com/apache/parquet-format/$REVISION/src/main/thrift/parquet.thrift -O /tmp/parquet.thrift && \ + thrift --gen rs /tmp/parquet.thrift && \ + echo "Removing TProcessor" && \ + sed -i '/use thrift::server::TProcessor;/d' parquet.rs && \ + echo "Replacing TSerializable" && \ + sed -i 's/impl TSerializable for/impl crate::thrift::TSerializable for/g' parquet.rs && \ + echo "Rewriting write_to_out_protocol" && \ + sed -i 's/fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol)/fn write_to_out_protocol(\&self, o_prot: \&mut T)/g' parquet.rs && \ + echo "Rewriting read_from_in_protocol" && \ + sed -i 's/fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol)/fn read_from_in_protocol(i_prot: \&mut T)/g' parquet.rs && \ + mv parquet.rs src/format.rs diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 5dae81d4711c..752eff86c5e9 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -23,7 +23,7 @@ use std::iter::Peekable; use std::slice::Iter; use std::sync::{Arc, Mutex}; use std::vec::IntoIter; -use thrift::protocol::{TCompactOutputProtocol, TSerializable}; +use thrift::protocol::TCompactOutputProtocol; use arrow_array::cast::AsArray; use arrow_array::types::*; @@ -50,6 +50,7 @@ use crate::file::properties::{WriterProperties, WriterPropertiesPtr}; use crate::file::reader::{ChunkReader, Length}; use crate::file::writer::{SerializedFileWriter, SerializedRowGroupWriter}; use crate::schema::types::{ColumnDescPtr, SchemaDescriptor}; +use crate::thrift::TSerializable; use levels::{calculate_array_levels, ArrayLevels}; mod byte_array; diff --git a/parquet/src/arrow/async_reader/metadata.rs b/parquet/src/arrow/async_reader/metadata.rs index 076ae5c54052..fe7b4427647c 100644 --- a/parquet/src/arrow/async_reader/metadata.rs +++ b/parquet/src/arrow/async_reader/metadata.rs @@ -17,7 +17,7 @@ use crate::arrow::async_reader::AsyncFileReader; use crate::errors::{ParquetError, Result}; -use crate::file::footer::{decode_footer, read_metadata}; +use crate::file::footer::{decode_footer, decode_metadata}; use crate::file::metadata::ParquetMetaData; use crate::file::page_index::index::Index; use crate::file::page_index::index_reader::{ @@ -27,7 +27,6 @@ use bytes::Bytes; use futures::future::BoxFuture; use futures::FutureExt; use std::future::Future; -use std::io::Read; use std::ops::Range; /// A data source that can be used with [`MetadataLoader`] to load [`ParquetMetaData`] @@ -95,16 +94,14 @@ impl MetadataLoader { // Did not fetch the entire file metadata in the initial read, need to make a second request let (metadata, remainder) = if length > suffix_len - 8 { let metadata_start = file_size - length - 8; - let remaining_metadata = fetch.fetch(metadata_start..footer_start).await?; - - let reader = remaining_metadata.as_ref().chain(&suffix[..suffix_len - 8]); - (read_metadata(reader)?, None) + let meta = fetch.fetch(metadata_start..file_size - 8).await?; + (decode_metadata(&meta)?, None) } else { let metadata_start = file_size - length - 8 - footer_start; let slice = &suffix[metadata_start..suffix_len - 8]; ( - read_metadata(slice)?, + decode_metadata(slice)?, Some((footer_start, suffix.slice(..metadata_start))), ) }; diff --git a/parquet/src/bin/parquet-layout.rs b/parquet/src/bin/parquet-layout.rs index d749bb8a4ba7..901ac9ea2309 100644 --- a/parquet/src/bin/parquet-layout.rs +++ b/parquet/src/bin/parquet-layout.rs @@ -38,12 +38,13 @@ use std::io::Read; use clap::Parser; use serde::Serialize; -use thrift::protocol::{TCompactInputProtocol, TSerializable}; +use thrift::protocol::TCompactInputProtocol; use parquet::basic::{Compression, Encoding}; use parquet::errors::Result; use parquet::file::reader::ChunkReader; use parquet::format::PageHeader; +use parquet::thrift::TSerializable; #[derive(Serialize, Debug)] struct ParquetFile { diff --git a/parquet/src/bloom_filter/mod.rs b/parquet/src/bloom_filter/mod.rs index c893d492b52a..a3807eb37011 100644 --- a/parquet/src/bloom_filter/mod.rs +++ b/parquet/src/bloom_filter/mod.rs @@ -26,13 +26,12 @@ use crate::format::{ BloomFilterAlgorithm, BloomFilterCompression, BloomFilterHash, BloomFilterHeader, SplitBlockAlgorithm, Uncompressed, XxHash, }; -use bytes::{Buf, Bytes}; +use crate::thrift::{TCompactSliceInputProtocol, TSerializable}; +use bytes::Bytes; use std::hash::Hasher; use std::io::Write; use std::sync::Arc; -use thrift::protocol::{ - TCompactInputProtocol, TCompactOutputProtocol, TOutputProtocol, TSerializable, -}; +use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol}; use twox_hash::XxHash64; /// Salt as defined in the [spec](https://github.com/apache/parquet-format/blob/master/BloomFilter.md#technical-approach). @@ -152,15 +151,11 @@ fn read_bloom_filter_header_and_length( buffer: Bytes, ) -> Result<(BloomFilterHeader, u64), ParquetError> { let total_length = buffer.len(); - let mut buf_reader = buffer.reader(); - let mut prot = TCompactInputProtocol::new(&mut buf_reader); + let mut prot = TCompactSliceInputProtocol::new(buffer.as_ref()); let header = BloomFilterHeader::read_from_in_protocol(&mut prot).map_err(|e| { ParquetError::General(format!("Could not read bloom filter header: {e}")) })?; - Ok(( - header, - (total_length - buf_reader.into_inner().remaining()) as u64, - )) + Ok((header, (total_length - prot.as_slice().len()) as u64)) } pub(crate) const BITSET_MIN_LENGTH: usize = 32; diff --git a/parquet/src/file/footer.rs b/parquet/src/file/footer.rs index 21de63e0c234..53496a66b572 100644 --- a/parquet/src/file/footer.rs +++ b/parquet/src/file/footer.rs @@ -18,7 +18,7 @@ use std::{io::Read, sync::Arc}; use crate::format::{ColumnOrder as TColumnOrder, FileMetaData as TFileMetaData}; -use thrift::protocol::{TCompactInputProtocol, TSerializable}; +use crate::thrift::{TCompactSliceInputProtocol, TSerializable}; use crate::basic::ColumnOrder; @@ -62,18 +62,13 @@ pub fn parse_metadata(chunk_reader: &R) -> Result Result { - read_metadata(metadata_read) -} - -/// Decodes [`ParquetMetaData`] from the provided [`Read`] -pub(crate) fn read_metadata(read: R) -> Result { +pub fn decode_metadata(buf: &[u8]) -> Result { // TODO: row group filtering - let mut prot = TCompactInputProtocol::new(read); + let mut prot = TCompactSliceInputProtocol::new(buf); let t_file_metadata: TFileMetaData = TFileMetaData::read_from_in_protocol(&mut prot) .map_err(|e| ParquetError::General(format!("Could not parse metadata: {e}")))?; let schema = types::from_thrift(&t_file_metadata.schema)?; diff --git a/parquet/src/file/page_index/index_reader.rs b/parquet/src/file/page_index/index_reader.rs index c36708a59aeb..ae3bf3699c1c 100644 --- a/parquet/src/file/page_index/index_reader.rs +++ b/parquet/src/file/page_index/index_reader.rs @@ -24,9 +24,8 @@ use crate::file::metadata::ColumnChunkMetaData; use crate::file::page_index::index::{Index, NativeIndex}; use crate::file::reader::ChunkReader; use crate::format::{ColumnIndex, OffsetIndex, PageLocation}; -use std::io::Cursor; +use crate::thrift::{TCompactSliceInputProtocol, TSerializable}; use std::ops::Range; -use thrift::protocol::{TCompactInputProtocol, TSerializable}; /// Computes the covering range of two optional ranges /// @@ -116,7 +115,7 @@ pub fn read_pages_locations( pub(crate) fn decode_offset_index( data: &[u8], ) -> Result, ParquetError> { - let mut prot = TCompactInputProtocol::new(data); + let mut prot = TCompactSliceInputProtocol::new(data); let offset = OffsetIndex::read_from_in_protocol(&mut prot)?; Ok(offset.page_locations) } @@ -125,8 +124,7 @@ pub(crate) fn decode_column_index( data: &[u8], column_type: Type, ) -> Result { - let mut d = Cursor::new(data); - let mut prot = TCompactInputProtocol::new(&mut d); + let mut prot = TCompactSliceInputProtocol::new(data); let index = ColumnIndex::read_from_in_protocol(&mut prot)?; diff --git a/parquet/src/file/serialized_reader.rs b/parquet/src/file/serialized_reader.rs index 4924dcc6f35a..4bc484144a81 100644 --- a/parquet/src/file/serialized_reader.rs +++ b/parquet/src/file/serialized_reader.rs @@ -19,7 +19,6 @@ //! Also contains implementations of the ChunkReader for files (with buffering) and byte arrays (RAM) use std::collections::VecDeque; -use std::io::Cursor; use std::iter; use std::{convert::TryFrom, fs::File, io::Read, path::Path, sync::Arc}; @@ -40,8 +39,9 @@ use crate::format::{PageHeader, PageLocation, PageType}; use crate::record::reader::RowIter; use crate::record::Row; use crate::schema::types::Type as SchemaType; +use crate::thrift::{TCompactSliceInputProtocol, TSerializable}; use crate::util::memory::ByteBufferPtr; -use thrift::protocol::{TCompactInputProtocol, TSerializable}; +use thrift::protocol::TCompactInputProtocol; impl TryFrom for SerializedFileReader { type Error = ParquetError; @@ -661,11 +661,11 @@ impl PageReader for SerializedPageReader { let buffer = self.reader.get_bytes(front.offset as u64, page_len)?; - let mut cursor = Cursor::new(buffer.as_ref()); - let header = read_page_header(&mut cursor)?; - let offset = cursor.position(); + let mut prot = TCompactSliceInputProtocol::new(buffer.as_ref()); + let header = PageHeader::read_from_in_protocol(&mut prot)?; + let offset = buffer.len() - prot.as_slice().len(); - let bytes = buffer.slice(offset as usize..); + let bytes = buffer.slice(offset..); decode_page( header, bytes.into(), diff --git a/parquet/src/file/writer.rs b/parquet/src/file/writer.rs index d723158de9f4..7796be6013df 100644 --- a/parquet/src/file/writer.rs +++ b/parquet/src/file/writer.rs @@ -21,10 +21,11 @@ use crate::bloom_filter::Sbbf; use crate::format as parquet; use crate::format::{ColumnIndex, OffsetIndex, RowGroup}; +use crate::thrift::TSerializable; use std::fmt::Debug; use std::io::{BufWriter, IoSlice, Read}; use std::{io::Write, sync::Arc}; -use thrift::protocol::{TCompactOutputProtocol, TSerializable}; +use thrift::protocol::TCompactOutputProtocol; use crate::column::writer::{ get_typed_column_writer_mut, ColumnCloseResult, ColumnWriterImpl, diff --git a/parquet/src/format.rs b/parquet/src/format.rs index 12c572c23cf5..46adc39e6406 100644 --- a/parquet/src/format.rs +++ b/parquet/src/format.rs @@ -53,12 +53,12 @@ impl Type { ]; } -impl TSerializable for Type { +impl crate::thrift::TSerializable for Type { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(Type::from(enum_value)) } @@ -222,12 +222,12 @@ impl ConvertedType { ]; } -impl TSerializable for ConvertedType { +impl crate::thrift::TSerializable for ConvertedType { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(ConvertedType::from(enum_value)) } @@ -299,12 +299,12 @@ impl FieldRepetitionType { ]; } -impl TSerializable for FieldRepetitionType { +impl crate::thrift::TSerializable for FieldRepetitionType { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(FieldRepetitionType::from(enum_value)) } @@ -397,12 +397,12 @@ impl Encoding { ]; } -impl TSerializable for Encoding { +impl crate::thrift::TSerializable for Encoding { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(Encoding::from(enum_value)) } @@ -474,12 +474,12 @@ impl CompressionCodec { ]; } -impl TSerializable for CompressionCodec { +impl crate::thrift::TSerializable for CompressionCodec { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(CompressionCodec::from(enum_value)) } @@ -535,12 +535,12 @@ impl PageType { ]; } -impl TSerializable for PageType { +impl crate::thrift::TSerializable for PageType { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(PageType::from(enum_value)) } @@ -592,12 +592,12 @@ impl BoundaryOrder { ]; } -impl TSerializable for BoundaryOrder { +impl crate::thrift::TSerializable for BoundaryOrder { #[allow(clippy::trivially_copy_pass_by_ref)] - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { o_prot.write_i32(self.0) } - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let enum_value = i_prot.read_i32()?; Ok(BoundaryOrder::from(enum_value)) } @@ -678,8 +678,8 @@ impl Statistics { } } -impl TSerializable for Statistics { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for Statistics { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option> = None; @@ -735,7 +735,7 @@ impl TSerializable for Statistics { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("Statistics"); o_prot.write_struct_begin(&struct_ident)?; if let Some(ref fld_var) = self.max { @@ -788,8 +788,8 @@ impl StringType { } } -impl TSerializable for StringType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for StringType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -803,7 +803,7 @@ impl TSerializable for StringType { let ret = StringType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("StringType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -825,8 +825,8 @@ impl UUIDType { } } -impl TSerializable for UUIDType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for UUIDType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -840,7 +840,7 @@ impl TSerializable for UUIDType { let ret = UUIDType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("UUIDType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -862,8 +862,8 @@ impl MapType { } } -impl TSerializable for MapType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for MapType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -877,7 +877,7 @@ impl TSerializable for MapType { let ret = MapType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("MapType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -899,8 +899,8 @@ impl ListType { } } -impl TSerializable for ListType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ListType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -914,7 +914,7 @@ impl TSerializable for ListType { let ret = ListType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ListType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -936,8 +936,8 @@ impl EnumType { } } -impl TSerializable for EnumType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for EnumType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -951,7 +951,7 @@ impl TSerializable for EnumType { let ret = EnumType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("EnumType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -973,8 +973,8 @@ impl DateType { } } -impl TSerializable for DateType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for DateType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -988,7 +988,7 @@ impl TSerializable for DateType { let ret = DateType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("DateType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1015,8 +1015,8 @@ impl NullType { } } -impl TSerializable for NullType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for NullType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1030,7 +1030,7 @@ impl TSerializable for NullType { let ret = NullType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("NullType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1066,8 +1066,8 @@ impl DecimalType { } } -impl TSerializable for DecimalType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for DecimalType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -1101,7 +1101,7 @@ impl TSerializable for DecimalType { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("DecimalType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("scale", TType::I32, 1))?; @@ -1130,8 +1130,8 @@ impl MilliSeconds { } } -impl TSerializable for MilliSeconds { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for MilliSeconds { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1145,7 +1145,7 @@ impl TSerializable for MilliSeconds { let ret = MilliSeconds {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("MilliSeconds"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1167,8 +1167,8 @@ impl MicroSeconds { } } -impl TSerializable for MicroSeconds { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for MicroSeconds { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1182,7 +1182,7 @@ impl TSerializable for MicroSeconds { let ret = MicroSeconds {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("MicroSeconds"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1204,8 +1204,8 @@ impl NanoSeconds { } } -impl TSerializable for NanoSeconds { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for NanoSeconds { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1219,7 +1219,7 @@ impl TSerializable for NanoSeconds { let ret = NanoSeconds {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("NanoSeconds"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1238,8 +1238,8 @@ pub enum TimeUnit { NANOS(NanoSeconds), } -impl TSerializable for TimeUnit { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for TimeUnit { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -1301,7 +1301,7 @@ impl TSerializable for TimeUnit { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("TimeUnit"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -1348,8 +1348,8 @@ impl TimestampType { } } -impl TSerializable for TimestampType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for TimestampType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -1383,7 +1383,7 @@ impl TSerializable for TimestampType { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("TimestampType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("isAdjustedToUTC", TType::Bool, 1))?; @@ -1419,8 +1419,8 @@ impl TimeType { } } -impl TSerializable for TimeType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for TimeType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -1454,7 +1454,7 @@ impl TSerializable for TimeType { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("TimeType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("isAdjustedToUTC", TType::Bool, 1))?; @@ -1492,8 +1492,8 @@ impl IntType { } } -impl TSerializable for IntType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for IntType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -1527,7 +1527,7 @@ impl TSerializable for IntType { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("IntType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("bitWidth", TType::I08, 1))?; @@ -1558,8 +1558,8 @@ impl JsonType { } } -impl TSerializable for JsonType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for JsonType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1573,7 +1573,7 @@ impl TSerializable for JsonType { let ret = JsonType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("JsonType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1598,8 +1598,8 @@ impl BsonType { } } -impl TSerializable for BsonType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for BsonType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -1613,7 +1613,7 @@ impl TSerializable for BsonType { let ret = BsonType {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("BsonType"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -1642,8 +1642,8 @@ pub enum LogicalType { UUID(UUIDType), } -impl TSerializable for LogicalType { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for LogicalType { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -1775,7 +1775,7 @@ impl TSerializable for LogicalType { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("LogicalType"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -1915,8 +1915,8 @@ impl SchemaElement { } } -impl TSerializable for SchemaElement { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for SchemaElement { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -1997,7 +1997,7 @@ impl TSerializable for SchemaElement { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("SchemaElement"); o_prot.write_struct_begin(&struct_ident)?; if let Some(ref fld_var) = self.type_ { @@ -2084,8 +2084,8 @@ impl DataPageHeader { } } -impl TSerializable for DataPageHeader { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for DataPageHeader { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -2139,7 +2139,7 @@ impl TSerializable for DataPageHeader { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("DataPageHeader"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("num_values", TType::I32, 1))?; @@ -2178,8 +2178,8 @@ impl IndexPageHeader { } } -impl TSerializable for IndexPageHeader { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for IndexPageHeader { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -2193,7 +2193,7 @@ impl TSerializable for IndexPageHeader { let ret = IndexPageHeader {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("IndexPageHeader"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -2229,8 +2229,8 @@ impl DictionaryPageHeader { } } -impl TSerializable for DictionaryPageHeader { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for DictionaryPageHeader { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -2270,7 +2270,7 @@ impl TSerializable for DictionaryPageHeader { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("DictionaryPageHeader"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("num_values", TType::I32, 1))?; @@ -2337,8 +2337,8 @@ impl DataPageHeaderV2 { } } -impl TSerializable for DataPageHeaderV2 { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for DataPageHeaderV2 { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -2412,7 +2412,7 @@ impl TSerializable for DataPageHeaderV2 { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("DataPageHeaderV2"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("num_values", TType::I32, 1))?; @@ -2463,8 +2463,8 @@ impl SplitBlockAlgorithm { } } -impl TSerializable for SplitBlockAlgorithm { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for SplitBlockAlgorithm { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -2478,7 +2478,7 @@ impl TSerializable for SplitBlockAlgorithm { let ret = SplitBlockAlgorithm {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("SplitBlockAlgorithm"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -2495,8 +2495,8 @@ pub enum BloomFilterAlgorithm { BLOCK(SplitBlockAlgorithm), } -impl TSerializable for BloomFilterAlgorithm { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for BloomFilterAlgorithm { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -2544,7 +2544,7 @@ impl TSerializable for BloomFilterAlgorithm { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("BloomFilterAlgorithm"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -2576,8 +2576,8 @@ impl XxHash { } } -impl TSerializable for XxHash { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for XxHash { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -2591,7 +2591,7 @@ impl TSerializable for XxHash { let ret = XxHash {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("XxHash"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -2608,8 +2608,8 @@ pub enum BloomFilterHash { XXHASH(XxHash), } -impl TSerializable for BloomFilterHash { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for BloomFilterHash { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -2657,7 +2657,7 @@ impl TSerializable for BloomFilterHash { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("BloomFilterHash"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -2688,8 +2688,8 @@ impl Uncompressed { } } -impl TSerializable for Uncompressed { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for Uncompressed { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -2703,7 +2703,7 @@ impl TSerializable for Uncompressed { let ret = Uncompressed {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("Uncompressed"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -2720,8 +2720,8 @@ pub enum BloomFilterCompression { UNCOMPRESSED(Uncompressed), } -impl TSerializable for BloomFilterCompression { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for BloomFilterCompression { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -2769,7 +2769,7 @@ impl TSerializable for BloomFilterCompression { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("BloomFilterCompression"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -2814,8 +2814,8 @@ impl BloomFilterHeader { } } -impl TSerializable for BloomFilterHeader { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for BloomFilterHeader { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -2863,7 +2863,7 @@ impl TSerializable for BloomFilterHeader { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("BloomFilterHeader"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("numBytes", TType::I32, 1))?; @@ -2933,8 +2933,8 @@ impl PageHeader { } } -impl TSerializable for PageHeader { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for PageHeader { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -3005,7 +3005,7 @@ impl TSerializable for PageHeader { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("PageHeader"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("type", TType::I32, 1))?; @@ -3067,8 +3067,8 @@ impl KeyValue { } } -impl TSerializable for KeyValue { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for KeyValue { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -3101,7 +3101,7 @@ impl TSerializable for KeyValue { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("KeyValue"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("key", TType::String, 1))?; @@ -3143,8 +3143,8 @@ impl SortingColumn { } } -impl TSerializable for SortingColumn { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for SortingColumn { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -3185,7 +3185,7 @@ impl TSerializable for SortingColumn { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("SortingColumn"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("column_idx", TType::I32, 1))?; @@ -3227,8 +3227,8 @@ impl PageEncodingStats { } } -impl TSerializable for PageEncodingStats { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for PageEncodingStats { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -3269,7 +3269,7 @@ impl TSerializable for PageEncodingStats { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("PageEncodingStats"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("page_type", TType::I32, 1))?; @@ -3355,8 +3355,8 @@ impl ColumnMetaData { } } -impl TSerializable for ColumnMetaData { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ColumnMetaData { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option> = None; @@ -3498,7 +3498,7 @@ impl TSerializable for ColumnMetaData { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ColumnMetaData"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("type", TType::I32, 1))?; @@ -3595,8 +3595,8 @@ impl EncryptionWithFooterKey { } } -impl TSerializable for EncryptionWithFooterKey { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for EncryptionWithFooterKey { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -3610,7 +3610,7 @@ impl TSerializable for EncryptionWithFooterKey { let ret = EncryptionWithFooterKey {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("EncryptionWithFooterKey"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -3639,8 +3639,8 @@ impl EncryptionWithColumnKey { } } -impl TSerializable for EncryptionWithColumnKey { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for EncryptionWithColumnKey { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option> = None; @@ -3679,7 +3679,7 @@ impl TSerializable for EncryptionWithColumnKey { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("EncryptionWithColumnKey"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("path_in_schema", TType::List, 1))?; @@ -3709,8 +3709,8 @@ pub enum ColumnCryptoMetaData { ENCRYPTIONWITHCOLUMNKEY(EncryptionWithColumnKey), } -impl TSerializable for ColumnCryptoMetaData { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ColumnCryptoMetaData { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -3765,7 +3765,7 @@ impl TSerializable for ColumnCryptoMetaData { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ColumnCryptoMetaData"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -3832,8 +3832,8 @@ impl ColumnChunk { } } -impl TSerializable for ColumnChunk { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ColumnChunk { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -3908,7 +3908,7 @@ impl TSerializable for ColumnChunk { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ColumnChunk"); o_prot.write_struct_begin(&struct_ident)?; if let Some(ref fld_var) = self.file_path { @@ -4000,8 +4000,8 @@ impl RowGroup { } } -impl TSerializable for RowGroup { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for RowGroup { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option = None; @@ -4078,7 +4078,7 @@ impl TSerializable for RowGroup { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("RowGroup"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("columns", TType::List, 1))?; @@ -4138,8 +4138,8 @@ impl TypeDefinedOrder { } } -impl TSerializable for TypeDefinedOrder { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for TypeDefinedOrder { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; loop { let field_ident = i_prot.read_field_begin()?; @@ -4153,7 +4153,7 @@ impl TSerializable for TypeDefinedOrder { let ret = TypeDefinedOrder {}; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("TypeDefinedOrder"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_stop()?; @@ -4170,8 +4170,8 @@ pub enum ColumnOrder { TYPEORDER(TypeDefinedOrder), } -impl TSerializable for ColumnOrder { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ColumnOrder { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -4219,7 +4219,7 @@ impl TSerializable for ColumnOrder { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ColumnOrder"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -4260,8 +4260,8 @@ impl PageLocation { } } -impl TSerializable for PageLocation { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for PageLocation { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option = None; @@ -4302,7 +4302,7 @@ impl TSerializable for PageLocation { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("PageLocation"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("offset", TType::I64, 1))?; @@ -4338,8 +4338,8 @@ impl OffsetIndex { } } -impl TSerializable for OffsetIndex { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for OffsetIndex { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; loop { @@ -4372,7 +4372,7 @@ impl TSerializable for OffsetIndex { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("OffsetIndex"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("page_locations", TType::List, 1))?; @@ -4432,8 +4432,8 @@ impl ColumnIndex { } } -impl TSerializable for ColumnIndex { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for ColumnIndex { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option>> = None; @@ -4511,7 +4511,7 @@ impl TSerializable for ColumnIndex { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("ColumnIndex"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("null_pages", TType::List, 1))?; @@ -4577,8 +4577,8 @@ impl AesGcmV1 { } } -impl TSerializable for AesGcmV1 { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for AesGcmV1 { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option> = None; @@ -4616,7 +4616,7 @@ impl TSerializable for AesGcmV1 { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("AesGcmV1"); o_prot.write_struct_begin(&struct_ident)?; if let Some(ref fld_var) = self.aad_prefix { @@ -4664,8 +4664,8 @@ impl AesGcmCtrV1 { } } -impl TSerializable for AesGcmCtrV1 { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for AesGcmCtrV1 { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option> = None; let mut f_2: Option> = None; @@ -4703,7 +4703,7 @@ impl TSerializable for AesGcmCtrV1 { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("AesGcmCtrV1"); o_prot.write_struct_begin(&struct_ident)?; if let Some(ref fld_var) = self.aad_prefix { @@ -4736,8 +4736,8 @@ pub enum EncryptionAlgorithm { AESGCMCTRV1(AesGcmCtrV1), } -impl TSerializable for EncryptionAlgorithm { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for EncryptionAlgorithm { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { let mut ret: Option = None; let mut received_field_count = 0; i_prot.read_struct_begin()?; @@ -4792,7 +4792,7 @@ impl TSerializable for EncryptionAlgorithm { Ok(ret.expect("return value should have been constructed")) } } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("EncryptionAlgorithm"); o_prot.write_struct_begin(&struct_ident)?; match *self { @@ -4879,8 +4879,8 @@ impl FileMetaData { } } -impl TSerializable for FileMetaData { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for FileMetaData { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option> = None; @@ -4982,7 +4982,7 @@ impl TSerializable for FileMetaData { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("FileMetaData"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("version", TType::I32, 1))?; @@ -5068,8 +5068,8 @@ impl FileCryptoMetaData { } } -impl TSerializable for FileCryptoMetaData { - fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result { +impl crate::thrift::TSerializable for FileCryptoMetaData { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result { i_prot.read_struct_begin()?; let mut f_1: Option = None; let mut f_2: Option> = None; @@ -5102,7 +5102,7 @@ impl TSerializable for FileCryptoMetaData { }; Ok(ret) } - fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> { + fn write_to_out_protocol(&self, o_prot: &mut T) -> thrift::Result<()> { let struct_ident = TStructIdentifier::new("FileCryptoMetaData"); o_prot.write_struct_begin(&struct_ident)?; o_prot.write_field_begin(&TFieldIdentifier::new("encryption_algorithm", TType::Struct, 1))?; diff --git a/parquet/src/lib.rs b/parquet/src/lib.rs index 2371f8837bb0..f1612c90cc2a 100644 --- a/parquet/src/lib.rs +++ b/parquet/src/lib.rs @@ -88,3 +88,5 @@ pub mod bloom_filter; pub mod file; pub mod record; pub mod schema; + +pub mod thrift; diff --git a/parquet/src/thrift.rs b/parquet/src/thrift.rs new file mode 100644 index 000000000000..57f52edc6ef0 --- /dev/null +++ b/parquet/src/thrift.rs @@ -0,0 +1,284 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +//! Custom thrift definitions + +use thrift::protocol::{ + TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, + TMessageIdentifier, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType, +}; + +/// Reads and writes the struct to Thrift protocols. +/// +/// Unlike [`thrift::protocol::TSerializable`] this uses generics instead of trait objects +pub trait TSerializable: Sized { + fn read_from_in_protocol(i_prot: &mut T) -> thrift::Result; + fn write_to_out_protocol( + &self, + o_prot: &mut T, + ) -> thrift::Result<()>; +} + +/// A more performant implementation of [`TCompactInputProtocol`] that reads a slice +/// +/// [`TCompactInputProtocol`]: thrift::protocol::TCompactInputProtocol +pub(crate) struct TCompactSliceInputProtocol<'a> { + buf: &'a [u8], + // Identifier of the last field deserialized for a struct. + last_read_field_id: i16, + // Stack of the last read field ids (a new entry is added each time a nested struct is read). + read_field_id_stack: Vec, + // Boolean value for a field. + // Saved because boolean fields and their value are encoded in a single byte, + // and reading the field only occurs after the field id is read. + pending_read_bool_value: Option, +} + +impl<'a> TCompactSliceInputProtocol<'a> { + pub fn new(buf: &'a [u8]) -> Self { + Self { + buf, + last_read_field_id: 0, + read_field_id_stack: Vec::with_capacity(16), + pending_read_bool_value: None, + } + } + + pub fn as_slice(&self) -> &'a [u8] { + self.buf + } + + fn read_vlq(&mut self) -> thrift::Result { + let mut in_progress = 0; + let mut shift = 0; + loop { + let byte = self.read_byte()?; + in_progress |= ((byte & 0x7F) as u64) << shift; + shift += 7; + if byte & 0x80 == 0 { + return Ok(in_progress); + } + } + } + + fn read_zig_zag(&mut self) -> thrift::Result { + let val = self.read_vlq()?; + Ok((val >> 1) as i64 ^ -((val & 1) as i64)) + } + + fn read_list_set_begin(&mut self) -> thrift::Result<(TType, i32)> { + let header = self.read_byte()?; + let element_type = collection_u8_to_type(header & 0x0F)?; + + let possible_element_count = (header & 0xF0) >> 4; + let element_count = if possible_element_count != 15 { + // high bits set high if count and type encoded separately + possible_element_count as i32 + } else { + self.read_vlq()? as _ + }; + + Ok((element_type, element_count)) + } +} + +impl<'a> TInputProtocol for TCompactSliceInputProtocol<'a> { + fn read_message_begin(&mut self) -> thrift::Result { + unimplemented!() + } + + fn read_message_end(&mut self) -> thrift::Result<()> { + unimplemented!() + } + + fn read_struct_begin(&mut self) -> thrift::Result> { + self.read_field_id_stack.push(self.last_read_field_id); + self.last_read_field_id = 0; + Ok(None) + } + + fn read_struct_end(&mut self) -> thrift::Result<()> { + self.last_read_field_id = self + .read_field_id_stack + .pop() + .expect("should have previous field ids"); + Ok(()) + } + + fn read_field_begin(&mut self) -> thrift::Result { + // we can read at least one byte, which is: + // - the type + // - the field delta and the type + let field_type = self.read_byte()?; + let field_delta = (field_type & 0xF0) >> 4; + let field_type = match field_type & 0x0F { + 0x01 => { + self.pending_read_bool_value = Some(true); + Ok(TType::Bool) + } + 0x02 => { + self.pending_read_bool_value = Some(false); + Ok(TType::Bool) + } + ttu8 => u8_to_type(ttu8), + }?; + + match field_type { + TType::Stop => Ok( + TFieldIdentifier::new::, String, Option>( + None, + TType::Stop, + None, + ), + ), + _ => { + if field_delta != 0 { + self.last_read_field_id += field_delta as i16; + } else { + self.last_read_field_id = self.read_i16()?; + }; + + Ok(TFieldIdentifier { + name: None, + field_type, + id: Some(self.last_read_field_id), + }) + } + } + } + + fn read_field_end(&mut self) -> thrift::Result<()> { + Ok(()) + } + + fn read_bool(&mut self) -> thrift::Result { + match self.pending_read_bool_value.take() { + Some(b) => Ok(b), + None => { + let b = self.read_byte()?; + match b { + 0x01 => Ok(true), + 0x02 => Ok(false), + unkn => Err(thrift::Error::Protocol(thrift::ProtocolError { + kind: thrift::ProtocolErrorKind::InvalidData, + message: format!("cannot convert {} into bool", unkn), + })), + } + } + } + } + + fn read_bytes(&mut self) -> thrift::Result> { + let len = self.read_vlq()? as usize; + let ret = self.buf.get(..len).ok_or_else(eof_error)?.to_vec(); + self.buf = &self.buf[len..]; + Ok(ret) + } + + fn read_i8(&mut self) -> thrift::Result { + Ok(self.read_byte()? as _) + } + + fn read_i16(&mut self) -> thrift::Result { + Ok(self.read_zig_zag()? as _) + } + + fn read_i32(&mut self) -> thrift::Result { + Ok(self.read_zig_zag()? as _) + } + + fn read_i64(&mut self) -> thrift::Result { + self.read_zig_zag() + } + + fn read_double(&mut self) -> thrift::Result { + let slice = (self.buf[..8]).try_into().unwrap(); + self.buf = &self.buf[8..]; + Ok(f64::from_le_bytes(slice)) + } + + fn read_string(&mut self) -> thrift::Result { + let bytes = self.read_bytes()?; + String::from_utf8(bytes).map_err(From::from) + } + + fn read_list_begin(&mut self) -> thrift::Result { + let (element_type, element_count) = self.read_list_set_begin()?; + Ok(TListIdentifier::new(element_type, element_count)) + } + + fn read_list_end(&mut self) -> thrift::Result<()> { + Ok(()) + } + + fn read_set_begin(&mut self) -> thrift::Result { + unimplemented!() + } + + fn read_set_end(&mut self) -> thrift::Result<()> { + unimplemented!() + } + + fn read_map_begin(&mut self) -> thrift::Result { + unimplemented!() + } + + fn read_map_end(&mut self) -> thrift::Result<()> { + Ok(()) + } + + #[inline] + fn read_byte(&mut self) -> thrift::Result { + let ret = *self.buf.first().ok_or_else(eof_error)?; + self.buf = &self.buf[1..]; + Ok(ret) + } +} + +fn collection_u8_to_type(b: u8) -> thrift::Result { + match b { + 0x01 => Ok(TType::Bool), + o => u8_to_type(o), + } +} + +fn u8_to_type(b: u8) -> thrift::Result { + match b { + 0x00 => Ok(TType::Stop), + 0x03 => Ok(TType::I08), // equivalent to TType::Byte + 0x04 => Ok(TType::I16), + 0x05 => Ok(TType::I32), + 0x06 => Ok(TType::I64), + 0x07 => Ok(TType::Double), + 0x08 => Ok(TType::String), + 0x09 => Ok(TType::List), + 0x0A => Ok(TType::Set), + 0x0B => Ok(TType::Map), + 0x0C => Ok(TType::Struct), + unkn => Err(thrift::Error::Protocol(thrift::ProtocolError { + kind: thrift::ProtocolErrorKind::InvalidData, + message: format!("cannot convert {} into TType", unkn), + })), + } +} + +fn eof_error() -> thrift::Error { + thrift::Error::Transport(thrift::TransportError { + kind: thrift::TransportErrorKind::EndOfFile, + message: "Unexpected EOF".to_string(), + }) +}