forked from google/flatbuffers
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[rust] Genericize flexbuffer reader (google#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
- Loading branch information
Showing
14 changed files
with
385 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "flexbuffers" | ||
version = "0.2.2" | ||
version = "0.3.0" | ||
authors = ["Casper Neo <[email protected]>", "FlatBuffers Maintainers"] | ||
edition = "2018" | ||
license = "Apache-2.0" | ||
|
@@ -20,7 +20,6 @@ serialize_human_readable = [] | |
# You basically never need this to be true unless reading data from old binaries. | ||
deserialize_human_readable = [] | ||
|
||
|
||
[dependencies] | ||
serde = "1.0.119" | ||
serde_derive = "1.0.119" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use std::ops::{Deref, Range}; | ||
|
||
/// The underlying buffer that is used by a flexbuffer Reader. | ||
/// | ||
/// This allows for custom buffer implementations as long as they can be viewed as a &[u8]. | ||
pub trait Buffer: Deref<Target = [u8]> + Sized { | ||
// The `BufferString` allows for a buffer to return a custom string which will have the | ||
// lifetime of the underlying buffer. A simple `std::str::from_utf8` wouldn't work since that | ||
// returns a &str, which is then owned by the callee (cannot be returned from a function). | ||
// | ||
// Example: During deserialization a `BufferString` is returned, allowing the deserializer | ||
// to "borrow" the given str - b/c there is a "lifetime" guarantee, so to speak, from the | ||
// underlying buffer. | ||
/// A BufferString which will live at least as long as the Buffer itself. | ||
/// | ||
/// Deref's to UTF-8 `str`, and only generated from the `buffer_str` function Result. | ||
type BufferString: Deref<Target = str> + Sized; | ||
|
||
/// This method returns an instance of type Self. This allows for lifetimes to be tracked | ||
/// in cases of deserialization. | ||
/// | ||
/// It also lets custom buffers manage reference counts. | ||
/// | ||
/// Returns None if: | ||
/// - range start is greater than end | ||
/// - range end is out of bounds | ||
/// | ||
/// This operation should be fast -> O(1), ideally with no heap allocations. | ||
fn slice(&self, range: Range<usize>) -> Option<Self>; | ||
|
||
/// Creates a shallow copy of the given buffer, similar to `slice`. | ||
/// | ||
/// This operation should be fast -> O(1), ideally with no heap allocations. | ||
#[inline] | ||
fn shallow_copy(&self) -> Self { | ||
self.slice(0..self.len()).unwrap() | ||
} | ||
|
||
/// Creates an empty instance of a `Buffer`. This is different than `Default` b/c it | ||
/// guarantees that the buffer instance will have length zero. | ||
/// | ||
/// Most impls shold be able to implement this via `Default`. | ||
fn empty() -> Self; | ||
|
||
/// Based off of the `empty` function, allows override for optimization purposes. | ||
#[inline] | ||
fn empty_str() -> Self::BufferString { | ||
Self::empty().buffer_str().unwrap() | ||
} | ||
|
||
/// Attempts to convert the given buffer to a custom string type. | ||
/// | ||
/// This should fail if the type does not have valid UTF-8 bytes, and must be zero copy. | ||
fn buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error>; | ||
} | ||
|
||
impl<'de> Buffer for &'de [u8] { | ||
type BufferString = &'de str; | ||
|
||
#[inline] | ||
fn slice(&self, range: Range<usize>) -> Option<Self> { | ||
self.get(range) | ||
} | ||
|
||
#[inline] | ||
fn empty() -> Self { | ||
&[] | ||
} | ||
|
||
/// Based off of the `empty` function, allows override for optimization purposes. | ||
#[inline] | ||
fn empty_str() -> Self::BufferString { | ||
&"" | ||
} | ||
|
||
#[inline] | ||
fn buffer_str(&self) -> Result<Self::BufferString, std::str::Utf8Error> { | ||
std::str::from_utf8(self) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.