Files
flatbuffers/rust/flexbuffers/src/builder/push.rs
Colin 4174c10e7a [rust] Genericize flexbuffer reader (#6450)
* feature/rust-tokio-bytes added feature name for tokio-bytes

* Added flexbuffer implementation, TODO: typecast to avoid recurse

* Converted codebase to utilize FlexBuffer implementation, need to resolve deserialization issues

* Added todo for lifetime issue, may use &'de [u8] for deserializer instead of current method

* Added proper &[u8] implementation

* Removed unused struct

* Added experimental fix to get_slice

* Added experimental fix to get_slice

* Avoided lifetime issues via ref structs, need to check if this hurts peformance

* Updated deserializer implementation to allow for borrowed data from Reader struct

* Fixed bug with str

* Removed unnecessary generic parameter

* Added unsafe to avoid lifetime complaints, current tests pass, need to review alternatives to unsafe

* Opinionated: Removed bytes crate as this implementation could be done in a separate crate

* Cleaned up flatbuffer

* Fixed sample / example

* Resolved PR feedback, need to resolve issues with tests

* Cleaned up FlexBuffer trait to be an auto impl

* Removed TODO

* Reverted Deserializer to only support &'de [u8]

* Cleaned up / renamed function for clarification

* Renamed FlexBuffer -> InternalBuffer for clarification on it's purpose

* Fixed issue with key bytes

* resolved issues with broken tests, confirming this is a breaking change

* Removed FIXME that's solved by splitting String and Key variants

* Implemented associated types approach

* Fixed backward slice logic

* Fixed MapReader compile error

* Added from_buffer for deserialization, removed  function since it's only needed for deserialization

* Removed dead code

* Cleaned up buffer, removed AsRef in favor of Deref

* Renamed Buffer::as_str -> Buffer::buffer_str

* Minor cleanup

* Updated documentation, need to fix tests

* Removed unnecessary &

* Removed unused lifetime

* removed unnecessary as_ref

* Minor optimization wrap-up

* resolved issue with Clone

* Added test to verify no deep-copy

* Added  for optimization

* Updated to use empty fn instead of default

* Updated comments / test name - plus the 0.3.0 version bump

* comment
2021-02-16 08:04:48 -05:00

169 lines
5.5 KiB
Rust

// Copyright 2019 Google LLC
//
// 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
//
// https://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 crate::builder::Builder;
use crate::private::Sealed;
use crate::{Blob, Buffer, IndirectFloat, IndirectInt, IndirectUInt};
impl<B: Buffer> Sealed for Blob<B> {}
impl Sealed for () {}
// TODO: String interning
// TODO: Pushable for Map types?
/// Types that implement the Pushable trait can be written into a Flexbuffer.
///
/// All Rust's standard numbers, `u8, u16, u32, u64, i8, i16, i32, i64, f32, f64`,
/// can all be pushed. They are `FlexBufferType::{UInt, Int, Float}`.
/// Flexbuffers chooses the smallest width that can represent the given number.
/// Strings can pe pushed, they become `FlexBufferType::String` and are stored
/// with both a length and null terminator.
///
/// * For convenience and speed push typed vectors using rust arrays and slices.
/// Doing so will immediately serialize the data, skipping the `Builder`'s
/// internal cache.
///
/// * Pushable cannot not be implemented by any downstream crates.
pub trait Pushable: Sealed + Sized {
fn push_to_builder(self, _: &mut Builder) {}
}
impl Pushable for () {
fn push_to_builder(self, builder: &mut Builder) {
builder.push_null();
}
}
impl<B: Buffer> Pushable for Blob<B> {
fn push_to_builder(self, builder: &mut Builder) {
builder.push_blob(&self.0);
}
}
macro_rules! forward_to_builder {
($T: ty, $method: ident) => {
impl Sealed for $T {}
impl Pushable for $T {
fn push_to_builder(self, builder: &mut Builder) {
builder.$method(self);
}
}
};
($T: ty, $method: ident, $asT: ty) => {
impl Sealed for $T {}
impl Pushable for $T {
fn push_to_builder(self, builder: &mut Builder) {
builder.$method(self as $asT);
}
}
};
}
forward_to_builder!(&str, push_str);
forward_to_builder!(bool, push_bool);
forward_to_builder!(u8, push_uint);
forward_to_builder!(u16, push_uint);
forward_to_builder!(u32, push_uint);
forward_to_builder!(u64, push_uint);
forward_to_builder!(i8, push_int);
forward_to_builder!(i16, push_int);
forward_to_builder!(i32, push_int);
forward_to_builder!(i64, push_int);
forward_to_builder!(f32, push_float);
forward_to_builder!(f64, push_float);
forward_to_builder!(&[u8], push_uints);
forward_to_builder!(&[u16], push_uints);
forward_to_builder!(&[u32], push_uints);
forward_to_builder!(&[u64], push_uints);
forward_to_builder!(&[i8], push_ints);
forward_to_builder!(&[i16], push_ints);
forward_to_builder!(&[i32], push_ints);
forward_to_builder!(&[i64], push_ints);
forward_to_builder!(&[f32], push_floats);
forward_to_builder!(&[f64], push_floats);
forward_to_builder!(&[bool], push_bools);
forward_to_builder!(&Vec<u8>, push_uints);
forward_to_builder!(&Vec<u16>, push_uints);
forward_to_builder!(&Vec<u32>, push_uints);
forward_to_builder!(&Vec<u64>, push_uints);
forward_to_builder!(&Vec<i8>, push_ints);
forward_to_builder!(&Vec<i16>, push_ints);
forward_to_builder!(&Vec<i32>, push_ints);
forward_to_builder!(&Vec<i64>, push_ints);
forward_to_builder!(&Vec<f32>, push_floats);
forward_to_builder!(&Vec<f64>, push_floats);
forward_to_builder!(&Vec<bool>, push_bools);
macro_rules! impl_indirects {
($Indirect: ident, $method: ident) => {
impl Sealed for $Indirect {}
impl Pushable for $Indirect {
fn push_to_builder(self, builder: &mut Builder) {
builder.$method(self.0);
}
}
};
}
impl_indirects!(IndirectInt, push_indirect_int);
impl_indirects!(IndirectUInt, push_indirect_uint);
impl_indirects!(IndirectFloat, push_indirect_float);
macro_rules! impl_arrays {
($num: expr) => {
forward_to_builder!(&[u8; $num], push_uints, &[u8]);
forward_to_builder!(&[u16; $num], push_uints, &[u16]);
forward_to_builder!(&[u32; $num], push_uints, &[u32]);
forward_to_builder!(&[u64; $num], push_uints, &[u64]);
forward_to_builder!(&[i8; $num], push_ints, &[i8]);
forward_to_builder!(&[i16; $num], push_ints, &[i16]);
forward_to_builder!(&[i32; $num], push_ints, &[i32]);
forward_to_builder!(&[i64; $num], push_ints, &[i64]);
forward_to_builder!(&[f32; $num], push_floats, &[f32]);
forward_to_builder!(&[f64; $num], push_floats, &[f64]);
forward_to_builder!(&[bool; $num], push_bools, &[bool]);
};
}
impl_arrays!(0);
impl_arrays!(1);
impl_arrays!(2);
impl_arrays!(3);
impl_arrays!(4);
impl_arrays!(5);
impl_arrays!(6);
// impl_arrays!(7);
// impl_arrays!(8);
// impl_arrays!(9);
// impl_arrays!(10);
// impl_arrays!(11);
// impl_arrays!(12);
// impl_arrays!(13);
// impl_arrays!(14);
// impl_arrays!(15);
// impl_arrays!(16);
// impl_arrays!(17);
// impl_arrays!(18);
// impl_arrays!(19);
// impl_arrays!(20);
// impl_arrays!(21);
// impl_arrays!(22);
// impl_arrays!(23);
// impl_arrays!(24);
// impl_arrays!(25);
// impl_arrays!(26);
// impl_arrays!(27);
// impl_arrays!(28);
// impl_arrays!(29);
// impl_arrays!(30);
// impl_arrays!(31);
// impl_arrays!(32);