forked from BigfootDev/flatbuffers
Rust Flatbuffers Verifier (#6269)
* Updated comments and fixed a fundemental type error. * bump rust flatbuffers semver * Initial commit with verifier, need to clean up * Verifier tested. Needs clean up and refactoring. * Display for InvalidFlatbuffer and better errors for strings * SimpleToVerify, some refactoring * Combined VerifierType TableAccessorFuncBody into FollowType * scrub todos * Update Rust get_root functions. There are 6 variants, with verifier options, default verifier options and no verification "fast". * Rename root fns * inline * Update to use thiserror * fix for bad compiler * improve error formatting * Replace multiply with saturating_multiply * saturating adds too * Add docs disclaiming experimental verification system Co-authored-by: Casper Neo <cneo@google.com>
This commit is contained in:
@@ -13,3 +13,4 @@ categories = ["encoding", "data-structures", "memory-management"]
|
||||
[dependencies]
|
||||
smallvec = "1.0"
|
||||
bitflags = "1.2"
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -435,7 +435,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
||||
// Write the vtable offset, which is the start of any Table.
|
||||
// We fill its value later.
|
||||
let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
|
||||
WIPOffset::new(self.push::<UOffsetT>(0xF0F0_F0F0 as UOffsetT).value());
|
||||
WIPOffset::new(self.push::<UOffsetT>(0xF0F0_F0F0).value());
|
||||
|
||||
// Layout of the data this function will create when a new vtable is
|
||||
// needed.
|
||||
|
||||
@@ -27,16 +27,9 @@ use std::marker::PhantomData;
|
||||
/// Writing a new Follow implementation primarily involves deciding whether
|
||||
/// you want to return data (of the type Self::Inner) or do you want to
|
||||
/// continue traversing the FlatBuffer.
|
||||
pub trait Follow<'a> {
|
||||
pub trait Follow<'buf> {
|
||||
type Inner;
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner;
|
||||
}
|
||||
|
||||
/// Execute a follow as a top-level function.
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn lifted_follow<'a, T: Follow<'a>>(buf: &'a [u8], loc: usize) -> T::Inner {
|
||||
T::follow(buf, loc)
|
||||
fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner;
|
||||
}
|
||||
|
||||
/// FollowStart wraps a Follow impl in a struct type. This can make certain
|
||||
|
||||
107
rust/flatbuffers/src/get_root.rs
Normal file
107
rust/flatbuffers/src/get_root.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 crate::{
|
||||
Follow, ForwardsUOffset, InvalidFlatbuffer, SkipSizePrefix, Verifiable, Verifier,
|
||||
VerifierOptions,
|
||||
};
|
||||
|
||||
/// Gets the root of the Flatbuffer, verifying it first with default options.
|
||||
/// Note that verification is an experimental feature and may not be maximally performant or
|
||||
/// catch every error (though that is the goal). See the `_unchecked` variants for previous
|
||||
/// behavior.
|
||||
pub fn root<'buf, T>(data: &'buf [u8]) -> Result<T::Inner, InvalidFlatbuffer>
|
||||
where
|
||||
T: 'buf + Follow<'buf> + Verifiable,
|
||||
{
|
||||
let opts = VerifierOptions::default();
|
||||
root_with_opts::<T>(&opts, data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets the root of the Flatbuffer, verifying it first with given options.
|
||||
/// Note that verification is an experimental feature and may not be maximally performant or
|
||||
/// catch every error (though that is the goal). See the `_unchecked` variants for previous
|
||||
/// behavior.
|
||||
pub fn root_with_opts<'opts, 'buf, T>(
|
||||
opts: &'opts VerifierOptions,
|
||||
data: &'buf [u8],
|
||||
) -> Result<T::Inner, InvalidFlatbuffer>
|
||||
where
|
||||
T: 'buf + Follow<'buf> + Verifiable,
|
||||
{
|
||||
let mut v = Verifier::new(&opts, data);
|
||||
<ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
|
||||
Ok(unsafe { root_unchecked::<T>(data) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets the root of a size prefixed Flatbuffer, verifying it first with default options.
|
||||
/// Note that verification is an experimental feature and may not be maximally performant or
|
||||
/// catch every error (though that is the goal). See the `_unchecked` variants for previous
|
||||
/// behavior.
|
||||
pub fn size_prefixed_root<'buf, T>(data: &'buf [u8]) -> Result<T::Inner, InvalidFlatbuffer>
|
||||
where
|
||||
T: 'buf + Follow<'buf> + Verifiable,
|
||||
{
|
||||
let opts = VerifierOptions::default();
|
||||
size_prefixed_root_with_opts::<T>(&opts, data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets the root of a size prefixed Flatbuffer, verifying it first with given options.
|
||||
/// Note that verification is an experimental feature and may not be maximally performant or
|
||||
/// catch every error (though that is the goal). See the `_unchecked` variants for previous
|
||||
/// behavior.
|
||||
pub fn size_prefixed_root_with_opts<'opts, 'buf, T>(
|
||||
opts: &'opts VerifierOptions,
|
||||
data: &'buf [u8],
|
||||
) -> Result<T::Inner, InvalidFlatbuffer>
|
||||
where
|
||||
T: 'buf + Follow<'buf> + Verifiable,
|
||||
{
|
||||
let mut v = Verifier::new(&opts, data);
|
||||
<SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
|
||||
Ok(unsafe { size_prefixed_root_unchecked::<T>(data) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets root for a trusted Flatbuffer.
|
||||
/// # Safety
|
||||
/// Flatbuffers accessors do not perform validation checks before accessing. Unlike the other
|
||||
/// `root` functions, this does not validate the flatbuffer before returning the accessor. Users
|
||||
/// must trust `data` contains a valid flatbuffer (e.g. b/c it was built by your software). Reading
|
||||
/// unchecked buffers may cause panics or even UB.
|
||||
pub unsafe fn root_unchecked<'buf, T>(data: &'buf [u8]) -> T::Inner
|
||||
where
|
||||
T: Follow<'buf> + 'buf,
|
||||
{
|
||||
<ForwardsUOffset<T>>::follow(data, 0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Gets root for a trusted, size prefixed, Flatbuffer.
|
||||
/// # Safety
|
||||
/// Flatbuffers accessors do not perform validation checks before accessing. Unlike the other
|
||||
/// `root` functions, this does not validate the flatbuffer before returning the accessor. Users
|
||||
/// must trust `data` contains a valid flatbuffer (e.g. b/c it was built by your software). Reading
|
||||
/// unchecked buffers may cause panics or even UB.
|
||||
pub unsafe fn size_prefixed_root_unchecked<'buf, T>(data: &'buf [u8]) -> T::Inner
|
||||
where
|
||||
T: Follow<'buf> + 'buf,
|
||||
{
|
||||
<SkipSizePrefix<ForwardsUOffset<T>>>::follow(data, 0)
|
||||
}
|
||||
@@ -19,26 +19,27 @@
|
||||
//! A library for memory-efficient serialization of data.
|
||||
//!
|
||||
//! This crate provides runtime support for the FlatBuffers format in the Rust programming language.
|
||||
//! To use this crate, first generate code with the `flatc` compiler, as described here: https://google.github.io/flatbuffers/
|
||||
//! To use this crate, first generate code with the `flatc` compiler, as described here: <https://google.github.io/flatbuffers/>
|
||||
//! Then, include that code into your project.
|
||||
//! Finally, add this crate to your `Cargo.toml`.
|
||||
//!
|
||||
//! At this time, Rust support is experimental, and APIs may change between minor versions.
|
||||
//!
|
||||
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: https://github.com/google/flatbuffers
|
||||
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: <https://github.com/google/flatbuffers>
|
||||
//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
|
||||
|
||||
mod builder;
|
||||
mod endian_scalar;
|
||||
mod follow;
|
||||
mod get_root;
|
||||
mod primitives;
|
||||
mod push;
|
||||
mod table;
|
||||
mod vector;
|
||||
mod verifier;
|
||||
mod vtable;
|
||||
mod vtable_writer;
|
||||
|
||||
pub use bitflags;
|
||||
pub use crate::builder::FlatBufferBuilder;
|
||||
pub use crate::endian_scalar::{
|
||||
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
|
||||
@@ -46,9 +47,15 @@ pub use crate::endian_scalar::{
|
||||
pub use crate::follow::{Follow, FollowStart};
|
||||
pub use crate::primitives::*;
|
||||
pub use crate::push::Push;
|
||||
pub use crate::table::{buffer_has_identifier, get_root, get_size_prefixed_root, Table};
|
||||
pub use crate::table::{buffer_has_identifier, Table};
|
||||
pub use crate::vector::{follow_cast_ref, SafeSliceAccess, Vector, VectorIter};
|
||||
pub use crate::verifier::{
|
||||
ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier,
|
||||
VerifierOptions,
|
||||
};
|
||||
pub use crate::vtable::field_index_to_field_offset;
|
||||
pub use bitflags;
|
||||
pub use get_root::*;
|
||||
|
||||
// TODO(rw): Unify `create_vector` and `create_vector_direct` by using
|
||||
// `Into<Vector<...>>`.
|
||||
|
||||
@@ -55,14 +55,6 @@ impl<'a> Follow<'a> for Table<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
|
||||
<ForwardsUOffset<T>>::follow(data, 0)
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_size_prefixed_root<'a, T: Follow<'a> + 'a>(data: &'a [u8]) -> T::Inner {
|
||||
<SkipSizePrefix<ForwardsUOffset<T>>>::follow(data, 0)
|
||||
}
|
||||
#[inline]
|
||||
pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
|
||||
assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::fmt::{Debug, Formatter, Result};
|
||||
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::size_of;
|
||||
use std::slice::from_raw_parts;
|
||||
use std::str::from_utf8_unchecked;
|
||||
use std::fmt::{Debug, Result, Formatter};
|
||||
|
||||
use crate::endian_scalar::read_scalar_at;
|
||||
#[cfg(target_endian = "little")]
|
||||
@@ -32,14 +32,13 @@ pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
|
||||
impl<'a, T> Debug for Vector<'a, T>
|
||||
where
|
||||
T: 'a + Follow<'a>,
|
||||
<T as Follow<'a>>::Inner : Debug
|
||||
<T as Follow<'a>>::Inner: Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We cannot use derive for these two impls, as it would only implement Copy
|
||||
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
|
||||
// can always be copied, no matter that `T` you have.
|
||||
@@ -104,6 +103,8 @@ impl SafeSliceAccess for u8 {}
|
||||
impl SafeSliceAccess for i8 {}
|
||||
impl SafeSliceAccess for bool {}
|
||||
|
||||
// TODO(caspern): Get rid of this. Conditional compliation is unnecessary complexity.
|
||||
// Vectors of primitives just don't work on big endian machines!!!
|
||||
#[cfg(target_endian = "little")]
|
||||
mod le_safe_slice_impls {
|
||||
impl super::SafeSliceAccess for u16 {}
|
||||
|
||||
559
rust/flatbuffers/src/verifier.rs
Normal file
559
rust/flatbuffers/src/verifier.rs
Normal file
@@ -0,0 +1,559 @@
|
||||
use crate::follow::Follow;
|
||||
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
|
||||
use std::ops::Range;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Traces the location of data errors. Not populated for Dos detecting errors.
|
||||
/// Useful for MissingRequiredField and Utf8Error in particular, though
|
||||
/// the other errors should not be producible by correct flatbuffers implementations.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ErrorTraceDetail {
|
||||
VectorElement {
|
||||
index: usize,
|
||||
position: usize,
|
||||
},
|
||||
TableField {
|
||||
field_name: &'static str,
|
||||
position: usize,
|
||||
},
|
||||
UnionVariant {
|
||||
variant: &'static str,
|
||||
position: usize,
|
||||
},
|
||||
}
|
||||
#[derive(PartialEq, Eq, Default, Debug, Clone)]
|
||||
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
|
||||
impl std::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[ErrorTraceDetail] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how a flatuffer is invalid and, for data errors, roughly where. No extra tracing
|
||||
/// information is given for DoS detecting errors since it will probably be a lot.
|
||||
#[derive(Clone, Error, Debug, PartialEq, Eq)]
|
||||
pub enum InvalidFlatbuffer {
|
||||
#[error("Missing required field `{required}`.\n{error_trace}")]
|
||||
MissingRequiredField {
|
||||
required: &'static str,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Union exactly one of union discriminant (`{field_type}`) and value \
|
||||
(`{field}`) are present.\n{error_trace}")]
|
||||
InconsistentUnion {
|
||||
field: &'static str,
|
||||
field_type: &'static str,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Utf8 error for string in {range:?}: {error}\n{error_trace}")]
|
||||
Utf8Error {
|
||||
#[source]
|
||||
error: std::str::Utf8Error,
|
||||
range: Range<usize>,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
|
||||
range.start, range.end)]
|
||||
MissingNullTerminator {
|
||||
range: Range<usize>,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Type `{unaligned_type}` at position {position} is unaligned.\n{error_trace}")]
|
||||
Unaligned {
|
||||
position: usize,
|
||||
unaligned_type: &'static str,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Range [{}, {}) is out of bounds.\n{error_trace}", range.start, range.end)]
|
||||
RangeOutOfBounds {
|
||||
range: Range<usize>,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Signed offset at position {position} has value {soffset} which points out of bounds.\
|
||||
\n{error_trace}")]
|
||||
SignedOffsetOutOfBounds {
|
||||
soffset: SOffsetT,
|
||||
position: usize,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
// Dos detecting errors. These do not get error traces since it will probably be very large.
|
||||
#[error("Too many tables.")]
|
||||
TooManyTables,
|
||||
#[error("Apparent size too large.")]
|
||||
ApparentSizeTooLarge,
|
||||
#[error("Nested table depth limit reached.")]
|
||||
DepthLimitReached,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ErrorTrace {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
use ErrorTraceDetail::*;
|
||||
for e in self.0.iter() {
|
||||
match e {
|
||||
VectorElement { index, position } => {
|
||||
writeln!(
|
||||
f,
|
||||
"\twhile verifying vector element {:?} at position {:?}",
|
||||
index, position
|
||||
)?;
|
||||
}
|
||||
TableField {
|
||||
field_name,
|
||||
position,
|
||||
} => {
|
||||
writeln!(
|
||||
f,
|
||||
"\twhile verifying table field `{}` at position {:?}",
|
||||
field_name, position
|
||||
)?;
|
||||
}
|
||||
UnionVariant { variant, position } => {
|
||||
writeln!(
|
||||
f,
|
||||
"\t while verifying union variant `{}` at position {:?}",
|
||||
variant, position
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::prelude::v1::Result<T, InvalidFlatbuffer>;
|
||||
|
||||
impl InvalidFlatbuffer {
|
||||
fn new_range_oob<T>(start: usize, end: usize) -> Result<T> {
|
||||
Err(Self::RangeOutOfBounds {
|
||||
range: Range { start, end },
|
||||
error_trace: Default::default(),
|
||||
})
|
||||
}
|
||||
fn new_inconsistent_union<T>(field: &'static str, field_type: &'static str) -> Result<T> {
|
||||
Err(Self::InconsistentUnion {
|
||||
field,
|
||||
field_type,
|
||||
error_trace: Default::default(),
|
||||
})
|
||||
}
|
||||
fn new_missing_required<T>(required: &'static str) -> Result<T> {
|
||||
Err(Self::MissingRequiredField {
|
||||
required,
|
||||
error_trace: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Records the path to the verifier detail if the error is a data error and not a DoS error.
|
||||
fn append_trace<T>(mut res: Result<T>, d: ErrorTraceDetail) -> Result<T> {
|
||||
if let Err(e) = res.as_mut() {
|
||||
use InvalidFlatbuffer::*;
|
||||
if let MissingRequiredField { error_trace, .. }
|
||||
| Unaligned { error_trace, .. }
|
||||
| RangeOutOfBounds { error_trace, .. }
|
||||
| InconsistentUnion { error_trace, .. }
|
||||
| Utf8Error { error_trace, .. }
|
||||
| MissingNullTerminator { error_trace, .. }
|
||||
| SignedOffsetOutOfBounds { error_trace, .. } = e
|
||||
{
|
||||
error_trace.0.push(d)
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// Adds a TableField trace detail if `res` is a data error.
|
||||
fn trace_field<T>(res: Result<T>, field_name: &'static str, position: usize) -> Result<T> {
|
||||
append_trace(
|
||||
res,
|
||||
ErrorTraceDetail::TableField {
|
||||
field_name,
|
||||
position,
|
||||
},
|
||||
)
|
||||
}
|
||||
/// Adds a TableField trace detail if `res` is a data error.
|
||||
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
|
||||
append_trace(res, ErrorTraceDetail::VectorElement { index, position })
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VerifierOptions {
|
||||
/// Maximum depth of nested tables allowed in a valid flatbuffer.
|
||||
pub max_depth: usize,
|
||||
/// Maximum number of tables allowed in a valid flatbuffer.
|
||||
pub max_tables: usize,
|
||||
/// Maximum "apparent" size of the message if the Flatbuffer object DAG is expanded into a
|
||||
/// tree.
|
||||
pub max_apparent_size: usize,
|
||||
/// Ignore errors where a string is missing its null terminator.
|
||||
/// This is mostly a problem if the message will be sent to a client using old c-strings.
|
||||
pub ignore_missing_null_terminator: bool,
|
||||
// probably want an option to ignore utf8 errors since strings come from c++
|
||||
// options to error un-recognized enums and unions? possible footgun.
|
||||
// Ignore nested flatbuffers, etc?
|
||||
}
|
||||
impl Default for VerifierOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_depth: 64,
|
||||
max_tables: 1_000_000,
|
||||
// size_ might do something different.
|
||||
max_apparent_size: 1 << 31,
|
||||
ignore_missing_null_terminator: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Carries the verification state. Should not be reused between tables.
|
||||
#[derive(Debug)]
|
||||
pub struct Verifier<'opts, 'buf> {
|
||||
buffer: &'buf [u8],
|
||||
opts: &'opts VerifierOptions,
|
||||
depth: usize,
|
||||
num_tables: usize,
|
||||
apparent_size: usize,
|
||||
}
|
||||
impl<'opts, 'buf> Verifier<'opts, 'buf> {
|
||||
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
|
||||
Self {
|
||||
opts,
|
||||
buffer,
|
||||
depth: 0,
|
||||
num_tables: 0,
|
||||
apparent_size: 0,
|
||||
}
|
||||
}
|
||||
/// Resets verifier internal state.
|
||||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
self.depth = 0;
|
||||
self.num_tables = 0;
|
||||
self.num_tables = 0;
|
||||
}
|
||||
/// Check that there really is a T in there.
|
||||
#[inline]
|
||||
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
|
||||
// Safe because we're not dereferencing.
|
||||
let p = unsafe { self.buffer.as_ptr().add(pos) };
|
||||
if (p as usize) % std::mem::align_of::<T>() == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(InvalidFlatbuffer::Unaligned {
|
||||
unaligned_type: std::any::type_name::<T>(),
|
||||
position: pos,
|
||||
error_trace: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn range_in_buffer(&mut self, pos: usize, size: usize) -> Result<()> {
|
||||
let end = pos.saturating_add(size);
|
||||
if end > self.buffer.len() {
|
||||
return InvalidFlatbuffer::new_range_oob(pos, end);
|
||||
}
|
||||
self.apparent_size += size;
|
||||
if self.apparent_size > self.opts.max_apparent_size {
|
||||
return Err(InvalidFlatbuffer::ApparentSizeTooLarge);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[inline]
|
||||
pub fn in_buffer<T>(&mut self, pos: usize) -> Result<()> {
|
||||
self.is_aligned::<T>(pos)?;
|
||||
self.range_in_buffer(pos, std::mem::size_of::<T>())
|
||||
}
|
||||
#[inline]
|
||||
fn get_u16(&mut self, pos: usize) -> Result<u16> {
|
||||
self.in_buffer::<u16>(pos)?;
|
||||
Ok(u16::from_le_bytes([self.buffer[pos], self.buffer[pos + 1]]))
|
||||
}
|
||||
#[inline]
|
||||
fn get_uoffset(&mut self, pos: usize) -> Result<UOffsetT> {
|
||||
self.in_buffer::<u32>(pos)?;
|
||||
Ok(u32::from_le_bytes([
|
||||
self.buffer[pos],
|
||||
self.buffer[pos + 1],
|
||||
self.buffer[pos + 2],
|
||||
self.buffer[pos + 3],
|
||||
]))
|
||||
}
|
||||
#[inline]
|
||||
fn deref_soffset(&mut self, pos: usize) -> Result<usize> {
|
||||
self.in_buffer::<SOffsetT>(pos)?;
|
||||
let offset = SOffsetT::from_le_bytes([
|
||||
self.buffer[pos],
|
||||
self.buffer[pos + 1],
|
||||
self.buffer[pos + 2],
|
||||
self.buffer[pos + 3],
|
||||
]);
|
||||
|
||||
// signed offsets are subtracted.
|
||||
let derefed = if offset > 0 {
|
||||
pos.checked_sub(offset.abs() as usize)
|
||||
} else {
|
||||
pos.checked_add(offset.abs() as usize)
|
||||
};
|
||||
if let Some(x) = derefed {
|
||||
if x < self.buffer.len() {
|
||||
return Ok(x);
|
||||
}
|
||||
}
|
||||
Err(InvalidFlatbuffer::SignedOffsetOutOfBounds {
|
||||
soffset: offset,
|
||||
position: pos,
|
||||
error_trace: Default::default(),
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
pub fn visit_table<'ver>(
|
||||
&'ver mut self,
|
||||
table_pos: usize,
|
||||
) -> Result<TableVerifier<'ver, 'opts, 'buf>> {
|
||||
let vtable_pos = self.deref_soffset(table_pos)?;
|
||||
let vtable_len = self.get_u16(vtable_pos)? as usize;
|
||||
self.is_aligned::<VOffsetT>(vtable_pos.saturating_add(vtable_len))?; // i.e. vtable_len is even.
|
||||
self.range_in_buffer(vtable_pos, vtable_len)?;
|
||||
// Check bounds.
|
||||
self.num_tables += 1;
|
||||
if self.num_tables > self.opts.max_tables {
|
||||
return Err(InvalidFlatbuffer::TooManyTables);
|
||||
}
|
||||
self.depth += 1;
|
||||
if self.depth > self.opts.max_depth {
|
||||
return Err(InvalidFlatbuffer::DepthLimitReached);
|
||||
}
|
||||
Ok(TableVerifier {
|
||||
pos: table_pos,
|
||||
vtable: vtable_pos,
|
||||
vtable_len,
|
||||
verifier: self,
|
||||
})
|
||||
}
|
||||
|
||||
/// Runs the union variant's type's verifier assuming the variant is at the given position,
|
||||
/// tracing the error.
|
||||
pub fn verify_union_variant<T: Verifiable>(
|
||||
&mut self,
|
||||
variant: &'static str,
|
||||
position: usize,
|
||||
) -> Result<()> {
|
||||
let res = T::run_verifier(self, position);
|
||||
append_trace(res, ErrorTraceDetail::UnionVariant { variant, position })
|
||||
}
|
||||
}
|
||||
|
||||
// Cache table metadata in usize so we don't have to cast types or jump around so much.
|
||||
// We will visit every field anyway.
|
||||
pub struct TableVerifier<'ver, 'opts, 'buf> {
|
||||
// Absolute position of table in buffer
|
||||
pos: usize,
|
||||
// Absolute position of vtable in buffer.
|
||||
vtable: usize,
|
||||
// Length of vtable.
|
||||
vtable_len: usize,
|
||||
// Verifier struct which holds the surrounding state and options.
|
||||
verifier: &'ver mut Verifier<'opts, 'buf>,
|
||||
}
|
||||
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
|
||||
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
|
||||
let field = field as usize;
|
||||
if field < self.vtable_len {
|
||||
let field_offset = self.verifier.get_u16(self.vtable.saturating_add(field))?;
|
||||
if field_offset > 0 {
|
||||
// Field is present.
|
||||
let field_pos = self.pos.saturating_add(field_offset as usize);
|
||||
return Ok(Some(field_pos));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visit_field<T: Verifiable>(
|
||||
mut self,
|
||||
field_name: &'static str,
|
||||
field: VOffsetT,
|
||||
required: bool,
|
||||
) -> Result<Self> {
|
||||
if let Some(field_pos) = self.deref(field)? {
|
||||
trace_field(
|
||||
T::run_verifier(self.verifier, field_pos),
|
||||
field_name,
|
||||
field_pos,
|
||||
)?;
|
||||
return Ok(self);
|
||||
}
|
||||
if required {
|
||||
InvalidFlatbuffer::new_missing_required(field_name)
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
/// Union verification is complicated. The schemas passes this function the metadata of the
|
||||
/// union's key (discriminant) and value fields, and a callback. The function verifies and
|
||||
/// reads the key, then invokes the callback to perform data-dependent verification.
|
||||
pub fn visit_union<Key, UnionVerifier>(
|
||||
mut self,
|
||||
key_field_name: &'static str,
|
||||
key_field_voff: VOffsetT,
|
||||
val_field_name: &'static str,
|
||||
val_field_voff: VOffsetT,
|
||||
required: bool,
|
||||
verify_union: UnionVerifier,
|
||||
) -> Result<Self>
|
||||
where
|
||||
Key: Follow<'buf> + Verifiable,
|
||||
UnionVerifier:
|
||||
(std::ops::FnOnce(<Key as Follow<'buf>>::Inner, &mut Verifier, usize) -> Result<()>),
|
||||
// NOTE: <Key as Follow<'buf>>::Inner == Key
|
||||
{
|
||||
// TODO(caspern): how to trace vtable errors?
|
||||
let val_pos = self.deref(val_field_voff)?;
|
||||
let key_pos = self.deref(key_field_voff)?;
|
||||
match (key_pos, val_pos) {
|
||||
(None, None) => {
|
||||
if required {
|
||||
InvalidFlatbuffer::new_missing_required(val_field_name)
|
||||
} else {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
(Some(k), Some(v)) => {
|
||||
trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?;
|
||||
let discriminant = Key::follow(self.verifier.buffer, k);
|
||||
trace_field(
|
||||
verify_union(discriminant, self.verifier, v),
|
||||
val_field_name,
|
||||
v,
|
||||
)?;
|
||||
Ok(self)
|
||||
}
|
||||
_ => InvalidFlatbuffer::new_inconsistent_union(key_field_name, val_field_name),
|
||||
}
|
||||
}
|
||||
pub fn finish(self) -> &'ver mut Verifier<'opts, 'buf> {
|
||||
self.verifier.depth -= 1;
|
||||
self.verifier
|
||||
}
|
||||
}
|
||||
|
||||
// Needs to be implemented for Tables and maybe structs.
|
||||
// Unions need some special treatment.
|
||||
pub trait Verifiable {
|
||||
/// Runs the verifier for this type, assuming its at position `pos` in the verifier's buffer.
|
||||
/// Should not need to be called directly.
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()>;
|
||||
}
|
||||
|
||||
// Verify the uoffset and then pass verifier to the type being pointed to.
|
||||
impl<T: Verifiable> Verifiable for ForwardsUOffset<T> {
|
||||
#[inline]
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
|
||||
let offset = v.get_uoffset(pos)? as usize;
|
||||
let next_pos = offset.saturating_add(pos);
|
||||
T::run_verifier(v, next_pos)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks and returns the range containing the flatbuffers vector.
|
||||
fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<std::ops::Range<usize>> {
|
||||
let len = v.get_uoffset(pos)? as usize;
|
||||
let start = pos.saturating_add(SIZE_UOFFSET);
|
||||
v.is_aligned::<T>(start)?;
|
||||
let size = len.saturating_mul(std::mem::size_of::<T>());
|
||||
let end = start.saturating_add(size);
|
||||
v.range_in_buffer(start, size)?;
|
||||
Ok(std::ops::Range { start, end })
|
||||
}
|
||||
|
||||
pub trait SimpleToVerifyInSlice {}
|
||||
impl SimpleToVerifyInSlice for bool {}
|
||||
impl SimpleToVerifyInSlice for i8 {}
|
||||
impl SimpleToVerifyInSlice for u8 {}
|
||||
impl SimpleToVerifyInSlice for i16 {}
|
||||
impl SimpleToVerifyInSlice for u16 {}
|
||||
impl SimpleToVerifyInSlice for i32 {}
|
||||
impl SimpleToVerifyInSlice for u32 {}
|
||||
impl SimpleToVerifyInSlice for f32 {}
|
||||
impl SimpleToVerifyInSlice for i64 {}
|
||||
impl SimpleToVerifyInSlice for u64 {}
|
||||
impl SimpleToVerifyInSlice for f64 {}
|
||||
|
||||
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
|
||||
verify_vector_range::<T>(v, pos)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Verifiable> Verifiable for SkipSizePrefix<T> {
|
||||
#[inline]
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
|
||||
T::run_verifier(v, pos.saturating_add(crate::SIZE_SIZEPREFIX))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Verifiable> Verifiable for Vector<'_, ForwardsUOffset<T>> {
|
||||
#[inline]
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
|
||||
let range = verify_vector_range::<ForwardsUOffset<T>>(v, pos)?;
|
||||
let size = std::mem::size_of::<ForwardsUOffset<T>>();
|
||||
for (i, element_pos) in range.step_by(size).enumerate() {
|
||||
trace_elem(
|
||||
<ForwardsUOffset<T>>::run_verifier(v, element_pos),
|
||||
i,
|
||||
element_pos,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Verifiable for &'a str {
|
||||
#[inline]
|
||||
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
|
||||
let range = verify_vector_range::<u8>(v, pos)?;
|
||||
let has_null_terminator = v.buffer.get(range.end).map(|&b| b == 0).unwrap_or(false);
|
||||
let s = std::str::from_utf8(&v.buffer[range.clone()]);
|
||||
if let Err(error) = s {
|
||||
return Err(InvalidFlatbuffer::Utf8Error {
|
||||
error,
|
||||
range,
|
||||
error_trace: Default::default(),
|
||||
});
|
||||
}
|
||||
if !v.opts.ignore_missing_null_terminator && !has_null_terminator {
|
||||
return Err(InvalidFlatbuffer::MissingNullTerminator {
|
||||
range,
|
||||
error_trace: Default::default(),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Verify VectorOfTables, Unions, Arrays, Structs...
|
||||
macro_rules! impl_verifiable_for {
|
||||
($T: ty) => {
|
||||
impl Verifiable for $T {
|
||||
#[inline]
|
||||
fn run_verifier<'opts, 'buf>(v: &mut Verifier<'opts, 'buf>, pos: usize) -> Result<()> {
|
||||
v.in_buffer::<$T>(pos)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
impl_verifiable_for!(bool);
|
||||
impl_verifiable_for!(u8);
|
||||
impl_verifiable_for!(i8);
|
||||
impl_verifiable_for!(u16);
|
||||
impl_verifiable_for!(i16);
|
||||
impl_verifiable_for!(u32);
|
||||
impl_verifiable_for!(i32);
|
||||
impl_verifiable_for!(f32);
|
||||
impl_verifiable_for!(u64);
|
||||
impl_verifiable_for!(i64);
|
||||
impl_verifiable_for!(f64);
|
||||
@@ -77,7 +77,8 @@ impl<'a> flatbuffers::Follow<'a> for Color {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,14 +93,27 @@ impl flatbuffers::Push for Color {
|
||||
impl flatbuffers::EndianScalar for Color {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(i8::to_le(self.0))
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(i8::from_le(self.0))
|
||||
let b = i8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Color {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Color {}
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_EQUIPMENT: u8 = 0;
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
@@ -143,11 +157,13 @@ impl std::fmt::Debug for Equipment {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct EquipmentUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Equipment {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,15 +178,27 @@ impl flatbuffers::Push for Equipment {
|
||||
impl flatbuffers::EndianScalar for Equipment {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(u8::to_le(self.0))
|
||||
let b = u8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(u8::from_le(self.0))
|
||||
let b = u8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EquipmentUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Verifiable for Equipment {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
u8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Equipment {}
|
||||
// struct Vec3, aligned to 4
|
||||
#[repr(C, align(4))]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@@ -189,6 +217,7 @@ impl std::fmt::Debug for Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Vec3 {}
|
||||
impl flatbuffers::SafeSliceAccess for Vec3 {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Vec3 {
|
||||
type Inner = &'a Vec3;
|
||||
@@ -226,7 +255,15 @@ impl<'b> flatbuffers::Push for &'b Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Vec3 {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Vec3 {
|
||||
pub fn new(_x: f32, _y: f32, _z: f32) -> Self {
|
||||
Vec3 {
|
||||
@@ -324,7 +361,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn weapons(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Weapon<'a>>>>>(Monster::VT_WEAPONS, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn equipped_type(&self) -> Equipment {
|
||||
@@ -336,7 +373,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn path(&self) -> Option<&'a [Vec3]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice() )
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None).map(|v| v.safe_slice())
|
||||
}
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
@@ -350,6 +387,31 @@ impl<'a> Monster<'a> {
|
||||
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Monster<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<Vec3>(&"pos", Self::VT_POS, false)?
|
||||
.visit_field::<i16>(&"mana", Self::VT_MANA, false)?
|
||||
.visit_field::<i16>(&"hp", Self::VT_HP, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"name", Self::VT_NAME, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"inventory", Self::VT_INVENTORY, false)?
|
||||
.visit_field::<Color>(&"color", Self::VT_COLOR, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Weapon>>>>(&"weapons", Self::VT_WEAPONS, false)?
|
||||
.visit_union::<Equipment, _>(&"equipped_type", Self::VT_EQUIPPED_TYPE, &"equipped", Self::VT_EQUIPPED, false, |key, v, pos| {
|
||||
match key {
|
||||
Equipment::Weapon => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Weapon>>("Equipment::Weapon", pos),
|
||||
_ => Ok(()),
|
||||
}
|
||||
})?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Vec3>>>(&"path", Self::VT_PATH, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct MonsterArgs<'a> {
|
||||
pub pos: Option<&'a Vec3>,
|
||||
pub mana: i16,
|
||||
@@ -512,6 +574,19 @@ impl<'a> Weapon<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Weapon<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"name", Self::VT_NAME, false)?
|
||||
.visit_field::<i16>(&"damage", Self::VT_DAMAGE, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct WeaponArgs<'a> {
|
||||
pub name: Option<flatbuffers::WIPOffset<&'a str>>,
|
||||
pub damage: i16,
|
||||
@@ -562,15 +637,77 @@ impl std::fmt::Debug for Weapon<'_> {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
flatbuffers::get_root::<Monster<'a>>(buf)
|
||||
unsafe { flatbuffers::root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
|
||||
unsafe { flatbuffers::size_prefixed_root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `Monster`
|
||||
/// and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `Monster` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `size_prefixed_root_as_monster_unchecked`.
|
||||
pub fn size_prefixed_root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `Monster` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn root_as_monster_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root_with_opts::<Monster<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `Monster` and returns
|
||||
/// it. Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn size_prefixed_root_as_monster_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root_with_opts::<Monster<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a Monster and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `Monster`.
|
||||
pub unsafe fn root_as_monster_unchecked(buf: &[u8]) -> Monster {
|
||||
flatbuffers::root_unchecked::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Monster and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Monster`.
|
||||
pub unsafe fn size_prefixed_root_as_monster_unchecked(buf: &[u8]) -> Monster {
|
||||
flatbuffers::size_prefixed_root_unchecked::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish_monster_buffer<'a, 'b>(
|
||||
fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
|
||||
@@ -20,8 +20,7 @@ extern crate flatbuffers;
|
||||
// import the generated code
|
||||
#[path = "./monster_generated.rs"]
|
||||
mod monster_generated;
|
||||
pub use monster_generated::my_game::sample::{get_root_as_monster,
|
||||
Color, Equipment,
|
||||
pub use monster_generated::my_game::sample::{Color, Equipment,
|
||||
Monster, MonsterArgs,
|
||||
Vec3,
|
||||
Weapon, WeaponArgs};
|
||||
@@ -98,7 +97,7 @@ fn main() {
|
||||
let buf = builder.finished_data(); // Of type `&[u8]`
|
||||
|
||||
// Get access to the root:
|
||||
let monster = get_root_as_monster(buf);
|
||||
let monster = flatbuffers::root::<Monster>(buf).unwrap();
|
||||
|
||||
// Get and test some scalar types from the FlatBuffer.
|
||||
let hp = monster.hp();
|
||||
|
||||
@@ -555,111 +555,93 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += "pub use self::bitflags_{{ENUM_NAME_SNAKE}}::{{ENUM_NAME}};";
|
||||
code_ += "";
|
||||
|
||||
// Generate Follow and Push so we can serialize and stuff.
|
||||
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
|
||||
code_ += " type Inner = Self;";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
|
||||
code_ += " let bits = flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc);";
|
||||
code_ += " unsafe { Self::from_bits_unchecked(bits) }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_.SetValue("FROM_BASE", "unsafe { Self::from_bits_unchecked(b) }");
|
||||
code_.SetValue("INTO_BASE", "self.bits()");
|
||||
} else {
|
||||
// Normal, c-modelled enums.
|
||||
// Deprecated associated constants;
|
||||
const std::string deprecation_warning =
|
||||
"#[deprecated(since = \"1.13\", note = \"Use associated constants"
|
||||
" instead. This will no longer be generated in 2021.\")]";
|
||||
code_ += deprecation_warning;
|
||||
code_ += "pub const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}"
|
||||
" = {{ENUM_MIN_BASE_VALUE}};";
|
||||
code_ += deprecation_warning;
|
||||
code_ += "pub const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}"
|
||||
" = {{ENUM_MAX_BASE_VALUE}};";
|
||||
auto num_fields = NumToString(enum_def.size());
|
||||
code_ += deprecation_warning;
|
||||
code_ += "#[allow(non_camel_case_types)]";
|
||||
code_ += "pub const ENUM_VALUES_{{ENUM_NAME_CAPS}}: [{{ENUM_NAME}}; " +
|
||||
num_fields + "] = [";
|
||||
ForAllEnumValues1(enum_def, [&](const EnumVal &ev){
|
||||
code_ += " " + GetEnumValue(enum_def, ev) + ",";
|
||||
});
|
||||
code_ += "];";
|
||||
code_ += "";
|
||||
code_ += "impl flatbuffers::Push for {{ENUM_NAME}} {";
|
||||
code_ += " type Output = {{ENUM_NAME}};";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
|
||||
code_ += " flatbuffers::emplace_scalar::<{{BASE_TYPE}}>"
|
||||
"(dst, self.bits());";
|
||||
|
||||
GenComment(enum_def.doc_comment);
|
||||
code_ +=
|
||||
"#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]";
|
||||
code_ += "#[repr(transparent)]";
|
||||
code_ += "pub struct {{ENUM_NAME}}(pub {{BASE_TYPE}});";
|
||||
code_ += "#[allow(non_upper_case_globals)]";
|
||||
code_ += "impl {{ENUM_NAME}} {";
|
||||
ForAllEnumValues1(enum_def, [&](const EnumVal &ev){
|
||||
this->GenComment(ev.doc_comment, " ");
|
||||
code_ += " pub const {{VARIANT}}: Self = Self({{VALUE}});";
|
||||
});
|
||||
code_ += "";
|
||||
// Generate Associated constants
|
||||
code_ += " pub const ENUM_MIN: {{BASE_TYPE}} = {{ENUM_MIN_BASE_VALUE}};";
|
||||
code_ += " pub const ENUM_MAX: {{BASE_TYPE}} = {{ENUM_MAX_BASE_VALUE}};";
|
||||
code_ += " pub const ENUM_VALUES: &'static [Self] = &[";
|
||||
ForAllEnumValues(enum_def, [&](){
|
||||
code_ += " Self::{{VARIANT}},";
|
||||
});
|
||||
code_ += " ];";
|
||||
code_ += " /// Returns the variant's name or \"\" if unknown.";
|
||||
code_ += " pub fn variant_name(self) -> Option<&'static str> {";
|
||||
code_ += " match self {";
|
||||
ForAllEnumValues(enum_def, [&](){
|
||||
code_ += " Self::{{VARIANT}} => Some(\"{{VARIANT}}\"),";
|
||||
});
|
||||
code_ += " _ => None,";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn to_little_endian(self) -> Self {";
|
||||
code_ += " let bits = {{BASE_TYPE}}::to_le(self.bits());";
|
||||
code_ += " unsafe { Self::from_bits_unchecked(bits) }";
|
||||
code_ += " }";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn from_little_endian(self) -> Self {";
|
||||
code_ += " let bits = {{BASE_TYPE}}::from_le(self.bits());";
|
||||
code_ += " unsafe { Self::from_bits_unchecked(bits) }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
return;
|
||||
|
||||
// Generate Debug. Unknown variants are printed like "<UNKNOWN 42>".
|
||||
code_ += "impl std::fmt::Debug for {{ENUM_NAME}} {";
|
||||
code_ += " fn fmt(&self, f: &mut std::fmt::Formatter) ->"
|
||||
" std::fmt::Result {";
|
||||
code_ += " if let Some(name) = self.variant_name() {";
|
||||
code_ += " f.write_str(name)";
|
||||
code_ += " } else {";
|
||||
code_ += " f.write_fmt(format_args!(\"<UNKNOWN {:?}>\", self.0))";
|
||||
code_ += " }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
|
||||
if (enum_def.is_union) {
|
||||
// Generate tyoesafe offset(s) for unions
|
||||
code_.SetValue("NAME", Name(enum_def));
|
||||
code_.SetValue("UNION_OFFSET_NAME", Name(enum_def) + "UnionTableOffset");
|
||||
code_ += "pub struct {{UNION_OFFSET_NAME}} {}";
|
||||
}
|
||||
|
||||
code_.SetValue("FROM_BASE", "Self(b)");
|
||||
code_.SetValue("INTO_BASE", "self.0");
|
||||
}
|
||||
|
||||
// Deprecated associated constants;
|
||||
code_ += "#[deprecated(since = \"1.13\", note = \"Use associated constants"
|
||||
" instead. This will no longer be generated in 2021.\")]";
|
||||
code_ += "pub const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}"
|
||||
" = {{ENUM_MIN_BASE_VALUE}};";
|
||||
code_ += "#[deprecated(since = \"1.13\", note = \"Use associated constants"
|
||||
" instead. This will no longer be generated in 2021.\")]";
|
||||
code_ += "pub const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}"
|
||||
" = {{ENUM_MAX_BASE_VALUE}};";
|
||||
auto num_fields = NumToString(enum_def.size());
|
||||
code_ += "#[deprecated(since = \"1.13\", note = \"Use associated constants"
|
||||
" instead. This will no longer be generated in 2021.\")]";
|
||||
code_ += "#[allow(non_camel_case_types)]";
|
||||
code_ += "pub const ENUM_VALUES_{{ENUM_NAME_CAPS}}: [{{ENUM_NAME}}; " +
|
||||
num_fields + "] = [";
|
||||
ForAllEnumValues1(enum_def, [&](const EnumVal &ev){
|
||||
code_ += " " + GetEnumValue(enum_def, ev) + ",";
|
||||
});
|
||||
code_ += "];";
|
||||
code_ += "";
|
||||
|
||||
GenComment(enum_def.doc_comment);
|
||||
code_ +=
|
||||
"#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]";
|
||||
code_ += "#[repr(transparent)]";
|
||||
code_ += "pub struct {{ENUM_NAME}}(pub {{BASE_TYPE}});";
|
||||
code_ += "#[allow(non_upper_case_globals)]";
|
||||
code_ += "impl {{ENUM_NAME}} {";
|
||||
ForAllEnumValues1(enum_def, [&](const EnumVal &ev){
|
||||
this->GenComment(ev.doc_comment, " ");
|
||||
code_ += " pub const {{VARIANT}}: Self = Self({{VALUE}});";
|
||||
});
|
||||
code_ += "";
|
||||
// Generate Associated constants
|
||||
code_ += " pub const ENUM_MIN: {{BASE_TYPE}} = {{ENUM_MIN_BASE_VALUE}};";
|
||||
code_ += " pub const ENUM_MAX: {{BASE_TYPE}} = {{ENUM_MAX_BASE_VALUE}};";
|
||||
code_ += " pub const ENUM_VALUES: &'static [Self] = &[";
|
||||
ForAllEnumValues(enum_def, [&](){
|
||||
code_ += " Self::{{VARIANT}},";
|
||||
});
|
||||
code_ += " ];";
|
||||
code_ += " /// Returns the variant's name or \"\" if unknown.";
|
||||
code_ += " pub fn variant_name(self) -> Option<&'static str> {";
|
||||
code_ += " match self {";
|
||||
ForAllEnumValues(enum_def, [&](){
|
||||
code_ += " Self::{{VARIANT}} => Some(\"{{VARIANT}}\"),";
|
||||
});
|
||||
code_ += " _ => None,";
|
||||
code_ += " }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
|
||||
// Generate Debug. Unknown variants are printed like "<UNKNOWN 42>".
|
||||
code_ += "impl std::fmt::Debug for {{ENUM_NAME}} {";
|
||||
code_ += " fn fmt(&self, f: &mut std::fmt::Formatter) ->"
|
||||
" std::fmt::Result {";
|
||||
code_ += " if let Some(name) = self.variant_name() {";
|
||||
code_ += " f.write_str(name)";
|
||||
code_ += " } else {";
|
||||
code_ += " f.write_fmt(format_args!(\"<UNKNOWN {:?}>\", self.0))";
|
||||
code_ += " }";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
|
||||
// Generate Follow and Push so we can serialize and stuff.
|
||||
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
|
||||
code_ += " type Inner = Self;";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
|
||||
code_ += " Self(flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc))";
|
||||
code_ += " let b = flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf,"
|
||||
" loc);";
|
||||
code_ += " {{FROM_BASE}}";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
@@ -668,28 +650,36 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
|
||||
code_ += " flatbuffers::emplace_scalar::<{{BASE_TYPE}}>"
|
||||
"(dst, self.0);";
|
||||
"(dst, {{INTO_BASE}});";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn to_little_endian(self) -> Self {";
|
||||
code_ += " Self({{BASE_TYPE}}::to_le(self.0))";
|
||||
code_ += " let b = {{BASE_TYPE}}::to_le({{INTO_BASE}});";
|
||||
code_ += " {{FROM_BASE}}";
|
||||
code_ += " }";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn from_little_endian(self) -> Self {";
|
||||
code_ += " Self({{BASE_TYPE}}::from_le(self.0))";
|
||||
code_ += " let b = {{BASE_TYPE}}::from_le({{INTO_BASE}});";
|
||||
code_ += " {{FROM_BASE}}";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
if (enum_def.is_union) {
|
||||
// Generate tyoesafe offset(s) for unions
|
||||
code_.SetValue("NAME", Name(enum_def));
|
||||
code_.SetValue("UNION_OFFSET_NAME", Name(enum_def) + "UnionTableOffset");
|
||||
code_ += "pub struct {{UNION_OFFSET_NAME}} {}";
|
||||
}
|
||||
// Generate verifier - deferring to the base type.
|
||||
code_ += "impl<'a> flatbuffers::Verifiable for {{ENUM_NAME}} {";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn run_verifier<'o, 'b>(";
|
||||
code_ += " v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize";
|
||||
code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {";
|
||||
code_ += " use self::flatbuffers::Verifiable;";
|
||||
code_ += " {{BASE_TYPE}}::run_verifier(v, pos)";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
// Enums are basically integers.
|
||||
code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{ENUM_NAME}} {}";
|
||||
}
|
||||
|
||||
std::string GetFieldOffsetName(const FieldDef &field) {
|
||||
@@ -1003,109 +993,60 @@ class RustGenerator : public BaseGenerator {
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
|
||||
std::string GenTableAccessorFuncBody(const FieldDef &field,
|
||||
const std::string &lifetime,
|
||||
const std::string &offset_prefix) {
|
||||
const std::string offset_name =
|
||||
offset_prefix + "::" + GetFieldOffsetName(field);
|
||||
const Type &type = field.value.type;
|
||||
std::string FollowType(const Type &type, const std::string &lifetime) {
|
||||
// IsVector... This can be made iterative?
|
||||
|
||||
switch (GetFullType(field.value.type)) {
|
||||
const auto WrapForwardsUOffset = [](std::string ty) -> std::string {
|
||||
return "flatbuffers::ForwardsUOffset<" + ty + ">";
|
||||
};
|
||||
const auto WrapVector = [&](std::string ty) -> std::string {
|
||||
return "flatbuffers::Vector<" + lifetime + ", " + ty + ">";
|
||||
};
|
||||
switch (GetFullType(type)) {
|
||||
case ftInteger:
|
||||
case ftFloat:
|
||||
case ftBool: {
|
||||
const auto typname = GetTypeBasic(type);
|
||||
if (field.optional) {
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
|
||||
} else {
|
||||
const auto default_value = GetDefaultScalarValue(field);
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||
default_value + ")).unwrap()";
|
||||
}
|
||||
return GetTypeBasic(type);
|
||||
}
|
||||
case ftStruct: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<" + typname + ">(" + offset_name + ", None)",
|
||||
field.required);
|
||||
}
|
||||
case ftTable: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<" + typname + "<" +
|
||||
lifetime + ">>>(" + offset_name + ", None)",
|
||||
field.required);
|
||||
}
|
||||
case ftUnionValue: {
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Table<" +
|
||||
lifetime + ">>>(" + offset_name + ", None)",
|
||||
field.required);
|
||||
return WrapInNameSpace(*type.struct_def);
|
||||
}
|
||||
case ftUnionKey:
|
||||
case ftEnumKey: {
|
||||
const std::string typname = WrapInNameSpace(*type.enum_def);
|
||||
const std::string default_value = GetDefaultScalarValue(field);
|
||||
if (field.optional) {
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
|
||||
} else {
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||
default_value + ")).unwrap()";
|
||||
}
|
||||
return WrapInNameSpace(*type.enum_def);
|
||||
}
|
||||
case ftTable: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return WrapForwardsUOffset(typname);
|
||||
}
|
||||
case ftUnionValue: {
|
||||
return WrapForwardsUOffset("flatbuffers::Table<" + lifetime + ">");
|
||||
}
|
||||
case ftString: {
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" +
|
||||
offset_name + ", None)",
|
||||
field.required);
|
||||
return WrapForwardsUOffset("&str");
|
||||
}
|
||||
|
||||
case ftVectorOfInteger:
|
||||
case ftVectorOfBool:
|
||||
case ftVectorOfFloat: {
|
||||
const auto typname = GetTypeBasic(type.VectorType());
|
||||
std::string s =
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Vector<" +
|
||||
lifetime + ", " + typname + ">>>(" + offset_name + ", None)";
|
||||
// single-byte values are safe to slice
|
||||
if (IsOneByte(type.VectorType().base_type)) {
|
||||
s += ".map(|v| v.safe_slice())";
|
||||
}
|
||||
return AddUnwrapIfRequired(s, field.required);
|
||||
return WrapForwardsUOffset(WrapVector(typname));
|
||||
}
|
||||
case ftVectorOfEnumKey: {
|
||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Vector<" +
|
||||
lifetime + ", " + typname + ">>>(" + offset_name + ", None)",
|
||||
field.required);
|
||||
const auto typname = WrapInNameSpace(*type.VectorType().enum_def);
|
||||
return WrapForwardsUOffset(WrapVector(typname));
|
||||
|
||||
}
|
||||
case ftVectorOfStruct: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Vector<" +
|
||||
typname + ">>>(" + offset_name +
|
||||
", None).map(|v| v.safe_slice() )",
|
||||
field.required);
|
||||
return WrapForwardsUOffset(WrapVector(typname));
|
||||
}
|
||||
case ftVectorOfTable: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<" +
|
||||
typname + "<" + lifetime + ">>>>>(" + offset_name + ", None)",
|
||||
field.required);
|
||||
return WrapForwardsUOffset(WrapVector(WrapForwardsUOffset(typname)));
|
||||
}
|
||||
case ftVectorOfString: {
|
||||
return AddUnwrapIfRequired(
|
||||
"self._tab.get::<flatbuffers::ForwardsUOffset<"
|
||||
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" +
|
||||
lifetime + " str>>>>(" + offset_name + ", None)",
|
||||
field.required);
|
||||
return WrapForwardsUOffset(WrapVector(WrapForwardsUOffset(
|
||||
"&" + lifetime + " str")));
|
||||
}
|
||||
case ftVectorOfUnionValue: {
|
||||
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
|
||||
@@ -1115,6 +1056,28 @@ class RustGenerator : public BaseGenerator {
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
|
||||
std::string GenTableAccessorFuncBody(const FieldDef &field,
|
||||
const std::string &lifetime) {
|
||||
const std::string vt_offset = GetFieldOffsetName(field);
|
||||
const std::string typname = FollowType(field.value.type, lifetime);
|
||||
// Default-y fields (scalars so far) are neither optional nor required.
|
||||
const std::string default_value = !(field.optional || field.required) ?
|
||||
"Some(" + GetDefaultScalarValue(field) + ")" : "None";
|
||||
const std::string unwrap = field.optional ? "" : ".unwrap()";
|
||||
|
||||
const auto t = GetFullType(field.value.type);
|
||||
|
||||
// TODO(caspern): Shouldn't 1byte VectorOfEnumKey be slice too?
|
||||
const std::string safe_slice = (
|
||||
t == ftVectorOfStruct ||
|
||||
((t == ftVectorOfBool || t == ftVectorOfFloat || t == ftVectorOfInteger)
|
||||
&& IsOneByte(field.value.type.VectorType().base_type))
|
||||
) ? ".map(|v| v.safe_slice())" : "";
|
||||
|
||||
return "self._tab.get::<" + typname + ">({{STRUCT_NAME}}::" +
|
||||
vt_offset + ", " + default_value + ")" + safe_slice + unwrap;
|
||||
}
|
||||
|
||||
bool TableFieldReturnsOption(const FieldDef &field) {
|
||||
if (field.optional) return true;
|
||||
switch (GetFullType(field.value.type)) {
|
||||
@@ -1272,17 +1235,14 @@ class RustGenerator : public BaseGenerator {
|
||||
// pub fn name(&'a self) -> user_facing_type {
|
||||
// self._tab.get::<internal_type>(offset, defaultval).unwrap()
|
||||
// }
|
||||
const auto offset_prefix = Name(struct_def);
|
||||
ForAllTableFields(struct_def, [&](const FieldDef &field) {
|
||||
code_.SetValue("RETURN_TYPE",
|
||||
GenTableAccessorFuncReturnType(field, "'a"));
|
||||
code_.SetValue("FUNC_BODY",
|
||||
GenTableAccessorFuncBody(field, "'a", offset_prefix));
|
||||
|
||||
this->GenComment(field.doc_comment, " ");
|
||||
code_ += " #[inline]";
|
||||
code_ += " pub fn {{FIELD_NAME}}(&self) -> {{RETURN_TYPE}} {";
|
||||
code_ += " {{FUNC_BODY}}";
|
||||
code_ += " " + GenTableAccessorFuncBody(field, "'a");
|
||||
code_ += " }";
|
||||
|
||||
// Generate a comparison function for this field if it is a key.
|
||||
@@ -1369,6 +1329,50 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += "}"; // End of table impl.
|
||||
code_ += "";
|
||||
|
||||
// Generate Verifier;
|
||||
code_ += "impl flatbuffers::Verifiable for {{STRUCT_NAME}}<'_> {";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn run_verifier<'o, 'b>(";
|
||||
code_ += " v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize";
|
||||
code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {";
|
||||
code_ += " use self::flatbuffers::Verifiable;";
|
||||
code_ += " v.visit_table(pos)?\\";
|
||||
// Escape newline and insert it onthe next line so we can end the builder
|
||||
// with a nice semicolon.
|
||||
ForAllTableFields(struct_def, [&](const FieldDef &field) {
|
||||
if (GetFullType(field.value.type) == ftUnionKey) return;
|
||||
|
||||
code_.SetValue("IS_REQ", field.required ? "true" : "false");
|
||||
if (GetFullType(field.value.type) != ftUnionValue) {
|
||||
// All types besides unions.
|
||||
code_.SetValue("TY", FollowType(field.value.type, "'_"));
|
||||
code_ += "\n .visit_field::<{{TY}}>(&\"{{FIELD_NAME}}\", "
|
||||
"Self::{{OFFSET_NAME}}, {{IS_REQ}})?\\";
|
||||
return;
|
||||
}
|
||||
// Unions.
|
||||
EnumDef &union_def = *field.value.type.enum_def;
|
||||
code_.SetValue("UNION_TYPE", Name(union_def));
|
||||
code_ += "\n .visit_union::<{{UNION_TYPE}}, _>("
|
||||
"&\"{{FIELD_NAME}}_type\", Self::{{OFFSET_NAME}}_TYPE, "
|
||||
"&\"{{FIELD_NAME}}\", Self::{{OFFSET_NAME}}, {{IS_REQ}}, "
|
||||
"|key, v, pos| {";
|
||||
code_ += " match key {";
|
||||
ForAllUnionVariantsBesidesNone(union_def, [&](const EnumVal &unused) {
|
||||
(void) unused;
|
||||
code_ += " {{U_ELEMENT_ENUM_TYPE}} => v.verify_union_variant::"
|
||||
"<flatbuffers::ForwardsUOffset<{{U_ELEMENT_TABLE_TYPE}}>>("
|
||||
"\"{{U_ELEMENT_ENUM_TYPE}}\", pos),";
|
||||
});
|
||||
code_ += " _ => Ok(()),";
|
||||
code_ += " }";
|
||||
code_ += " })?\\";
|
||||
});
|
||||
code_ += "\n .finish();";
|
||||
code_ += " Ok(())";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
|
||||
// Generate an args struct:
|
||||
code_.SetValue("MAYBE_LT",
|
||||
TableBuilderArgsNeedsLifetime(struct_def) ? "<'a>" : "");
|
||||
@@ -1538,22 +1542,105 @@ class RustGenerator : public BaseGenerator {
|
||||
|
||||
// The root datatype accessors:
|
||||
code_ += "#[inline]";
|
||||
code_ += "#[deprecated(since=\"1.13\", "
|
||||
"note=\"Deprecated in favor of `root_as...` methods.\")]";
|
||||
code_ +=
|
||||
"pub fn get_root_as_{{STRUCT_NAME_SNAKECASE}}<'a>(buf: &'a [u8])"
|
||||
" -> {{STRUCT_NAME}}<'a> {";
|
||||
code_ += " flatbuffers::get_root::<{{STRUCT_NAME}}<'a>>(buf)";
|
||||
code_ += " unsafe { flatbuffers::root_unchecked::<{{STRUCT_NAME}}"
|
||||
"<'a>>(buf) }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
||||
code_ += "#[inline]";
|
||||
code_ += "#[deprecated(since=\"1.13\", "
|
||||
"note=\"Deprecated in favor of `root_as...` methods.\")]";
|
||||
code_ +=
|
||||
"pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
|
||||
"<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {";
|
||||
code_ +=
|
||||
" flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>"
|
||||
"(buf)";
|
||||
" unsafe { flatbuffers::size_prefixed_root_unchecked::<{{STRUCT_NAME}}"
|
||||
"<'a>>(buf) }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
// Default verifier root fns.
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Verifies that a buffer of bytes contains a `{{STRUCT_NAME}}`";
|
||||
code_ += "/// and returns it.";
|
||||
code_ += "/// Note that verification is still experimental and may not";
|
||||
code_ += "/// catch every error, or be maximally performant. For the";
|
||||
code_ += "/// previous, unchecked, behavior use";
|
||||
code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`.";
|
||||
code_ += "pub fn root_as_{{STRUCT_NAME_SNAKECASE}}(buf: &[u8]) "
|
||||
"-> Result<{{STRUCT_NAME}}, flatbuffers::InvalidFlatbuffer> {";
|
||||
code_ += " flatbuffers::root::<{{STRUCT_NAME}}>(buf)";
|
||||
code_ += "}";
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Verifies that a buffer of bytes contains a size prefixed";
|
||||
code_ += "/// `{{STRUCT_NAME}}` and returns it.";
|
||||
code_ += "/// Note that verification is still experimental and may not";
|
||||
code_ += "/// catch every error, or be maximally performant. For the";
|
||||
code_ += "/// previous, unchecked, behavior use";
|
||||
code_ += "/// `size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`.";
|
||||
code_ += "pub fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
|
||||
"(buf: &[u8]) -> Result<{{STRUCT_NAME}}, "
|
||||
"flatbuffers::InvalidFlatbuffer> {";
|
||||
code_ += " flatbuffers::size_prefixed_root::<{{STRUCT_NAME}}>(buf)";
|
||||
code_ += "}";
|
||||
// Verifier with options root fns.
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Verifies, with the given options, that a buffer of bytes";
|
||||
code_ += "/// contains a `{{STRUCT_NAME}}` and returns it.";
|
||||
code_ += "/// Note that verification is still experimental and may not";
|
||||
code_ += "/// catch every error, or be maximally performant. For the";
|
||||
code_ += "/// previous, unchecked, behavior use";
|
||||
code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`.";
|
||||
code_ += "pub fn root_as_{{STRUCT_NAME_SNAKECASE}}_with_opts<'b, 'o>(";
|
||||
code_ += " opts: &'o flatbuffers::VerifierOptions,";
|
||||
code_ += " buf: &'b [u8],";
|
||||
code_ += ") -> Result<{{STRUCT_NAME}}<'b>, flatbuffers::InvalidFlatbuffer>"
|
||||
" {";
|
||||
code_ += " flatbuffers::root_with_opts::<{{STRUCT_NAME}}<'b>>(opts, buf)";
|
||||
code_ += "}";
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Verifies, with the given verifier options, that a buffer of";
|
||||
code_ += "/// bytes contains a size prefixed `{{STRUCT_NAME}}` and returns";
|
||||
code_ += "/// it. Note that verification is still experimental and may not";
|
||||
code_ += "/// catch every error, or be maximally performant. For the";
|
||||
code_ += "/// previous, unchecked, behavior use";
|
||||
code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`.";
|
||||
code_ += "pub fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}_with_opts"
|
||||
"<'b, 'o>(";
|
||||
code_ += " opts: &'o flatbuffers::VerifierOptions,";
|
||||
code_ += " buf: &'b [u8],";
|
||||
code_ += ") -> Result<{{STRUCT_NAME}}<'b>, flatbuffers::InvalidFlatbuffer>"
|
||||
" {";
|
||||
code_ += " flatbuffers::size_prefixed_root_with_opts::<{{STRUCT_NAME}}"
|
||||
"<'b>>(opts, buf)";
|
||||
code_ += "}";
|
||||
// Unchecked root fns.
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Assumes, without verification, that a buffer of bytes "
|
||||
"contains a {{STRUCT_NAME}} and returns it.";
|
||||
code_ += "/// # Safety";
|
||||
code_ += "/// Callers must trust the given bytes do indeed contain a valid"
|
||||
" `{{STRUCT_NAME}}`.";
|
||||
code_ += "pub unsafe fn root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked"
|
||||
"(buf: &[u8]) -> {{STRUCT_NAME}} {";
|
||||
code_ += " flatbuffers::root_unchecked::<{{STRUCT_NAME}}>(buf)";
|
||||
code_ += "}";
|
||||
code_ += "#[inline]";
|
||||
code_ += "/// Assumes, without verification, that a buffer of bytes "
|
||||
"contains a size prefixed {{STRUCT_NAME}} and returns it.";
|
||||
code_ += "/// # Safety";
|
||||
code_ += "/// Callers must trust the given bytes do indeed contain a valid"
|
||||
" size prefixed `{{STRUCT_NAME}}`.";
|
||||
code_ += "pub unsafe fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
|
||||
"_unchecked(buf: &[u8]) -> {{STRUCT_NAME}} {";
|
||||
code_ += " flatbuffers::size_prefixed_root_unchecked::<{{STRUCT_NAME}}>"
|
||||
"(buf)";
|
||||
code_ += "}";
|
||||
|
||||
|
||||
if (parser_.file_identifier_.length()) {
|
||||
// Declare the identifier
|
||||
@@ -1697,6 +1784,7 @@ class RustGenerator : public BaseGenerator {
|
||||
// Generate impls for SafeSliceAccess (because all structs are endian-safe),
|
||||
// Follow for the value type, Follow for the reference type, Push for the
|
||||
// value type, and Push for the reference type.
|
||||
code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{STRUCT_NAME}} {}";
|
||||
code_ += "impl flatbuffers::SafeSliceAccess for {{STRUCT_NAME}} {}";
|
||||
code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_NAME}} {";
|
||||
code_ += " type Inner = &'a {{STRUCT_NAME}};";
|
||||
@@ -1738,7 +1826,18 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
code_ += "";
|
||||
|
||||
// Generate verifier: Structs are simple so presence and alignment are
|
||||
// all that need to be checked.
|
||||
code_ += "impl<'a> flatbuffers::Verifiable for {{STRUCT_NAME}} {";
|
||||
code_ += " #[inline]";
|
||||
code_ += " fn run_verifier<'o, 'b>(";
|
||||
code_ += " v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize";
|
||||
code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {";
|
||||
code_ += " use self::flatbuffers::Verifiable;";
|
||||
code_ += " v.in_buffer::<Self>(pos)";
|
||||
code_ += " }";
|
||||
code_ += "}";
|
||||
|
||||
// Generate a constructor that takes all fields as arguments.
|
||||
code_ += "impl {{STRUCT_NAME}} {";
|
||||
|
||||
@@ -45,10 +45,22 @@ impl<'a> TableA<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn b(&self) -> Option<my_game::other_name_space::TableB<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB<'a>>>(TableA::VT_B, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB>>(TableA::VT_B, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TableA<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB>>(&"b", Self::VT_B, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TableAArgs<'a> {
|
||||
pub b: Option<flatbuffers::WIPOffset<my_game::other_name_space::TableB<'a>>>,
|
||||
}
|
||||
|
||||
@@ -72,7 +72,8 @@ impl<'a> flatbuffers::Follow<'a> for FromInclude {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<i64>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<i64>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,14 +88,27 @@ impl flatbuffers::Push for FromInclude {
|
||||
impl flatbuffers::EndianScalar for FromInclude {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(i64::to_le(self.0))
|
||||
let b = i64::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(i64::from_le(self.0))
|
||||
let b = i64::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for FromInclude {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i64::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for FromInclude {}
|
||||
// struct Unused, aligned to 4
|
||||
#[repr(C, align(4))]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@@ -109,6 +123,7 @@ impl std::fmt::Debug for Unused {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Unused {}
|
||||
impl flatbuffers::SafeSliceAccess for Unused {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Unused {
|
||||
type Inner = &'a Unused;
|
||||
@@ -146,7 +161,15 @@ impl<'b> flatbuffers::Push for &'b Unused {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Unused {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Unused {
|
||||
pub fn new(_a: i32) -> Self {
|
||||
Unused {
|
||||
@@ -194,10 +217,22 @@ impl<'a> TableB<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn a(&self) -> Option<super::super::TableA<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::super::TableA<'a>>>(TableB::VT_A, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::super::TableA>>(TableB::VT_A, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TableB<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<super::super::TableA>>(&"a", Self::VT_A, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TableBArgs<'a> {
|
||||
pub a: Option<flatbuffers::WIPOffset<super::super::TableA<'a>>>,
|
||||
}
|
||||
|
||||
@@ -58,6 +58,17 @@ impl<'a> InParentNamespace<'a> {
|
||||
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for InParentNamespace<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct InParentNamespaceArgs {
|
||||
}
|
||||
impl<'a> Default for InParentNamespaceArgs {
|
||||
@@ -140,6 +151,17 @@ impl<'a> Monster<'a> {
|
||||
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Monster<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct MonsterArgs {
|
||||
}
|
||||
impl<'a> Default for MonsterArgs {
|
||||
@@ -208,8 +230,8 @@ impl<'a> flatbuffers::Follow<'a> for Color {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let bits = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
unsafe { Self::from_bits_unchecked(bits) }
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
unsafe { Self::from_bits_unchecked(b) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,16 +246,27 @@ impl flatbuffers::Push for Color {
|
||||
impl flatbuffers::EndianScalar for Color {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
let bits = u8::to_le(self.bits());
|
||||
unsafe { Self::from_bits_unchecked(bits) }
|
||||
let b = u8::to_le(self.bits());
|
||||
unsafe { Self::from_bits_unchecked(b) }
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
let bits = u8::from_le(self.bits());
|
||||
unsafe { Self::from_bits_unchecked(bits) }
|
||||
let b = u8::from_le(self.bits());
|
||||
unsafe { Self::from_bits_unchecked(b) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Color {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
u8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Color {}
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_RACE: i8 = -1;
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
@@ -289,7 +322,8 @@ impl<'a> flatbuffers::Follow<'a> for Race {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,14 +338,27 @@ impl flatbuffers::Push for Race {
|
||||
impl flatbuffers::EndianScalar for Race {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(i8::to_le(self.0))
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(i8::from_le(self.0))
|
||||
let b = i8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Race {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Race {}
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_ANY: u8 = 0;
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
@@ -363,11 +410,13 @@ impl std::fmt::Debug for Any {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct AnyUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Any {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,15 +431,27 @@ impl flatbuffers::Push for Any {
|
||||
impl flatbuffers::EndianScalar for Any {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(u8::to_le(self.0))
|
||||
let b = u8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(u8::from_le(self.0))
|
||||
let b = u8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Verifiable for Any {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
u8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Any {}
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0;
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
@@ -442,11 +503,13 @@ impl std::fmt::Debug for AnyUniqueAliases {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct AnyUniqueAliasesUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,15 +524,27 @@ impl flatbuffers::Push for AnyUniqueAliases {
|
||||
impl flatbuffers::EndianScalar for AnyUniqueAliases {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(u8::to_le(self.0))
|
||||
let b = u8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(u8::from_le(self.0))
|
||||
let b = u8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyUniqueAliasesUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Verifiable for AnyUniqueAliases {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
u8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for AnyUniqueAliases {}
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0;
|
||||
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
@@ -521,11 +596,13 @@ impl std::fmt::Debug for AnyAmbiguousAliases {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct AnyAmbiguousAliasesUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<u8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,15 +617,27 @@ impl flatbuffers::Push for AnyAmbiguousAliases {
|
||||
impl flatbuffers::EndianScalar for AnyAmbiguousAliases {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(u8::to_le(self.0))
|
||||
let b = u8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(u8::from_le(self.0))
|
||||
let b = u8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnyAmbiguousAliasesUnionTableOffset {}
|
||||
impl<'a> flatbuffers::Verifiable for AnyAmbiguousAliases {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
u8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for AnyAmbiguousAliases {}
|
||||
// struct Test, aligned to 2
|
||||
#[repr(C, align(2))]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@@ -566,6 +655,7 @@ impl std::fmt::Debug for Test {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Test {}
|
||||
impl flatbuffers::SafeSliceAccess for Test {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Test {
|
||||
type Inner = &'a Test;
|
||||
@@ -603,7 +693,15 @@ impl<'b> flatbuffers::Push for &'b Test {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Test {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Test {
|
||||
pub fn new(_a: i16, _b: i8) -> Self {
|
||||
Test {
|
||||
@@ -652,6 +750,7 @@ impl std::fmt::Debug for Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Vec3 {}
|
||||
impl flatbuffers::SafeSliceAccess for Vec3 {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Vec3 {
|
||||
type Inner = &'a Vec3;
|
||||
@@ -689,7 +788,15 @@ impl<'b> flatbuffers::Push for &'b Vec3 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Vec3 {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Vec3 {
|
||||
pub fn new(_x: f32, _y: f32, _z: f32, _test1: f64, _test2: Color, _test3: &Test) -> Self {
|
||||
Vec3 {
|
||||
@@ -745,6 +852,7 @@ impl std::fmt::Debug for Ability {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for Ability {}
|
||||
impl flatbuffers::SafeSliceAccess for Ability {}
|
||||
impl<'a> flatbuffers::Follow<'a> for Ability {
|
||||
type Inner = &'a Ability;
|
||||
@@ -782,7 +890,15 @@ impl<'b> flatbuffers::Push for &'b Ability {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for Ability {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Ability {
|
||||
pub fn new(_id: u32, _distance: u32) -> Self {
|
||||
Ability {
|
||||
@@ -856,6 +972,18 @@ impl<'a> TestSimpleTableWithEnum<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TestSimpleTableWithEnum<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<Color>(&"color", Self::VT_COLOR, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TestSimpleTableWithEnumArgs {
|
||||
pub color: Color,
|
||||
}
|
||||
@@ -953,6 +1081,20 @@ impl<'a> Stat<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Stat<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"id", Self::VT_ID, false)?
|
||||
.visit_field::<i64>(&"val", Self::VT_VAL, false)?
|
||||
.visit_field::<u16>(&"count", Self::VT_COUNT, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct StatArgs<'a> {
|
||||
pub id: Option<flatbuffers::WIPOffset<&'a str>>,
|
||||
pub val: i64,
|
||||
@@ -1062,6 +1204,18 @@ impl<'a> Referrable<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Referrable<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<u64>(&"id", Self::VT_ID, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ReferrableArgs {
|
||||
pub id: u64,
|
||||
}
|
||||
@@ -1282,21 +1436,21 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn test4(&self) -> Option<&'a [Test]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST4, None).map(|v| v.safe_slice() )
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Test>>>(Monster::VT_TEST4, None).map(|v| v.safe_slice())
|
||||
}
|
||||
#[inline]
|
||||
pub fn testarrayofstring(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING, None)
|
||||
}
|
||||
/// an example documentation comment: this will end up in the generated code
|
||||
/// multiline too
|
||||
#[inline]
|
||||
pub fn testarrayoftables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Monster<'a>>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Monster<'a>>>>>(Monster::VT_TESTARRAYOFTABLES, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Monster>>>>(Monster::VT_TESTARRAYOFTABLES, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn enemy(&self) -> Option<Monster<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<Monster<'a>>>(Monster::VT_ENEMY, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<Monster>>(Monster::VT_ENEMY, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn testnestedflatbuffer(&self) -> Option<&'a [u8]> {
|
||||
@@ -1310,7 +1464,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn testempty(&self) -> Option<Stat<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<Stat<'a>>>(Monster::VT_TESTEMPTY, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<Stat>>(Monster::VT_TESTEMPTY, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn testbool(&self) -> bool {
|
||||
@@ -1366,11 +1520,11 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn testarrayofstring2(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING2, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>>(Monster::VT_TESTARRAYOFSTRING2, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn testarrayofsortedstruct(&self) -> Option<&'a [Ability]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Ability>>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, None).map(|v| v.safe_slice() )
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Ability>>>(Monster::VT_TESTARRAYOFSORTEDSTRUCT, None).map(|v| v.safe_slice())
|
||||
}
|
||||
#[inline]
|
||||
pub fn flex(&self) -> Option<&'a [u8]> {
|
||||
@@ -1378,7 +1532,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn test5(&self) -> Option<&'a [Test]> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<Test>>>(Monster::VT_TEST5, None).map(|v| v.safe_slice() )
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Test>>>(Monster::VT_TEST5, None).map(|v| v.safe_slice())
|
||||
}
|
||||
#[inline]
|
||||
pub fn vector_of_longs(&self) -> Option<flatbuffers::Vector<'a, i64>> {
|
||||
@@ -1390,11 +1544,11 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn parent_namespace_test(&self) -> Option<super::InParentNamespace<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::InParentNamespace<'a>>>(Monster::VT_PARENT_NAMESPACE_TEST, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::InParentNamespace>>(Monster::VT_PARENT_NAMESPACE_TEST, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn vector_of_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_REFERRABLES, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable>>>>(Monster::VT_VECTOR_OF_REFERRABLES, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn single_weak_reference(&self) -> u64 {
|
||||
@@ -1406,7 +1560,7 @@ impl<'a> Monster<'a> {
|
||||
}
|
||||
#[inline]
|
||||
pub fn vector_of_strong_referrables(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable<'a>>>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<Referrable<'a>>>>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Referrable>>>>(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn co_owning_reference(&self) -> u64 {
|
||||
@@ -1550,6 +1704,84 @@ impl<'a> Monster<'a> {
|
||||
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Monster<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<Vec3>(&"pos", Self::VT_POS, false)?
|
||||
.visit_field::<i16>(&"mana", Self::VT_MANA, false)?
|
||||
.visit_field::<i16>(&"hp", Self::VT_HP, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<&str>>(&"name", Self::VT_NAME, true)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"inventory", Self::VT_INVENTORY, false)?
|
||||
.visit_field::<Color>(&"color", Self::VT_COLOR, false)?
|
||||
.visit_union::<Any, _>(&"test_type", Self::VT_TEST_TYPE, &"test", Self::VT_TEST, false, |key, v, pos| {
|
||||
match key {
|
||||
Any::Monster => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Monster>>("Any::Monster", pos),
|
||||
Any::TestSimpleTableWithEnum => v.verify_union_variant::<flatbuffers::ForwardsUOffset<TestSimpleTableWithEnum>>("Any::TestSimpleTableWithEnum", pos),
|
||||
Any::MyGame_Example2_Monster => v.verify_union_variant::<flatbuffers::ForwardsUOffset<super::example_2::Monster>>("Any::MyGame_Example2_Monster", pos),
|
||||
_ => Ok(()),
|
||||
}
|
||||
})?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Test>>>(&"test4", Self::VT_TEST4, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<&'_ str>>>>(&"testarrayofstring", Self::VT_TESTARRAYOFSTRING, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Monster>>>>(&"testarrayoftables", Self::VT_TESTARRAYOFTABLES, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<Monster>>(&"enemy", Self::VT_ENEMY, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"testnestedflatbuffer", Self::VT_TESTNESTEDFLATBUFFER, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<Stat>>(&"testempty", Self::VT_TESTEMPTY, false)?
|
||||
.visit_field::<bool>(&"testbool", Self::VT_TESTBOOL, false)?
|
||||
.visit_field::<i32>(&"testhashs32_fnv1", Self::VT_TESTHASHS32_FNV1, false)?
|
||||
.visit_field::<u32>(&"testhashu32_fnv1", Self::VT_TESTHASHU32_FNV1, false)?
|
||||
.visit_field::<i64>(&"testhashs64_fnv1", Self::VT_TESTHASHS64_FNV1, false)?
|
||||
.visit_field::<u64>(&"testhashu64_fnv1", Self::VT_TESTHASHU64_FNV1, false)?
|
||||
.visit_field::<i32>(&"testhashs32_fnv1a", Self::VT_TESTHASHS32_FNV1A, false)?
|
||||
.visit_field::<u32>(&"testhashu32_fnv1a", Self::VT_TESTHASHU32_FNV1A, false)?
|
||||
.visit_field::<i64>(&"testhashs64_fnv1a", Self::VT_TESTHASHS64_FNV1A, false)?
|
||||
.visit_field::<u64>(&"testhashu64_fnv1a", Self::VT_TESTHASHU64_FNV1A, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, bool>>>(&"testarrayofbools", Self::VT_TESTARRAYOFBOOLS, false)?
|
||||
.visit_field::<f32>(&"testf", Self::VT_TESTF, false)?
|
||||
.visit_field::<f32>(&"testf2", Self::VT_TESTF2, false)?
|
||||
.visit_field::<f32>(&"testf3", Self::VT_TESTF3, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<&'_ str>>>>(&"testarrayofstring2", Self::VT_TESTARRAYOFSTRING2, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Ability>>>(&"testarrayofsortedstruct", Self::VT_TESTARRAYOFSORTEDSTRUCT, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"flex", Self::VT_FLEX, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Test>>>(&"test5", Self::VT_TEST5, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, i64>>>(&"vector_of_longs", Self::VT_VECTOR_OF_LONGS, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, f64>>>(&"vector_of_doubles", Self::VT_VECTOR_OF_DOUBLES, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<super::InParentNamespace>>(&"parent_namespace_test", Self::VT_PARENT_NAMESPACE_TEST, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Referrable>>>>(&"vector_of_referrables", Self::VT_VECTOR_OF_REFERRABLES, false)?
|
||||
.visit_field::<u64>(&"single_weak_reference", Self::VT_SINGLE_WEAK_REFERENCE, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u64>>>(&"vector_of_weak_references", Self::VT_VECTOR_OF_WEAK_REFERENCES, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Referrable>>>>(&"vector_of_strong_referrables", Self::VT_VECTOR_OF_STRONG_REFERRABLES, false)?
|
||||
.visit_field::<u64>(&"co_owning_reference", Self::VT_CO_OWNING_REFERENCE, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u64>>>(&"vector_of_co_owning_references", Self::VT_VECTOR_OF_CO_OWNING_REFERENCES, false)?
|
||||
.visit_field::<u64>(&"non_owning_reference", Self::VT_NON_OWNING_REFERENCE, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u64>>>(&"vector_of_non_owning_references", Self::VT_VECTOR_OF_NON_OWNING_REFERENCES, false)?
|
||||
.visit_union::<AnyUniqueAliases, _>(&"any_unique_type", Self::VT_ANY_UNIQUE_TYPE, &"any_unique", Self::VT_ANY_UNIQUE, false, |key, v, pos| {
|
||||
match key {
|
||||
AnyUniqueAliases::M => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Monster>>("AnyUniqueAliases::M", pos),
|
||||
AnyUniqueAliases::TS => v.verify_union_variant::<flatbuffers::ForwardsUOffset<TestSimpleTableWithEnum>>("AnyUniqueAliases::TS", pos),
|
||||
AnyUniqueAliases::M2 => v.verify_union_variant::<flatbuffers::ForwardsUOffset<super::example_2::Monster>>("AnyUniqueAliases::M2", pos),
|
||||
_ => Ok(()),
|
||||
}
|
||||
})?
|
||||
.visit_union::<AnyAmbiguousAliases, _>(&"any_ambiguous_type", Self::VT_ANY_AMBIGUOUS_TYPE, &"any_ambiguous", Self::VT_ANY_AMBIGUOUS, false, |key, v, pos| {
|
||||
match key {
|
||||
AnyAmbiguousAliases::M1 => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Monster>>("AnyAmbiguousAliases::M1", pos),
|
||||
AnyAmbiguousAliases::M2 => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Monster>>("AnyAmbiguousAliases::M2", pos),
|
||||
AnyAmbiguousAliases::M3 => v.verify_union_variant::<flatbuffers::ForwardsUOffset<Monster>>("AnyAmbiguousAliases::M3", pos),
|
||||
_ => Ok(()),
|
||||
}
|
||||
})?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, Color>>>(&"vector_of_enums", Self::VT_VECTOR_OF_ENUMS, false)?
|
||||
.visit_field::<Race>(&"signed_enum", Self::VT_SIGNED_ENUM, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, u8>>>(&"testrequirednestedflatbuffer", Self::VT_TESTREQUIREDNESTEDFLATBUFFER, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct MonsterArgs<'a> {
|
||||
pub pos: Option<&'a Vec3>,
|
||||
pub mana: i16,
|
||||
@@ -2116,6 +2348,29 @@ impl<'a> TypeAliases<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TypeAliases<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<i8>(&"i8_", Self::VT_I8_, false)?
|
||||
.visit_field::<u8>(&"u8_", Self::VT_U8_, false)?
|
||||
.visit_field::<i16>(&"i16_", Self::VT_I16_, false)?
|
||||
.visit_field::<u16>(&"u16_", Self::VT_U16_, false)?
|
||||
.visit_field::<i32>(&"i32_", Self::VT_I32_, false)?
|
||||
.visit_field::<u32>(&"u32_", Self::VT_U32_, false)?
|
||||
.visit_field::<i64>(&"i64_", Self::VT_I64_, false)?
|
||||
.visit_field::<u64>(&"u64_", Self::VT_U64_, false)?
|
||||
.visit_field::<f32>(&"f32_", Self::VT_F32_, false)?
|
||||
.visit_field::<f64>(&"f64_", Self::VT_F64_, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, i8>>>(&"v8", Self::VT_V8, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, f64>>>(&"vf64", Self::VT_VF64, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TypeAliasesArgs<'a> {
|
||||
pub i8_: i8,
|
||||
pub u8_: u8,
|
||||
@@ -2236,15 +2491,77 @@ impl std::fmt::Debug for TypeAliases<'_> {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
flatbuffers::get_root::<Monster<'a>>(buf)
|
||||
unsafe { flatbuffers::root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_size_prefixed_root_as_monster<'a>(buf: &'a [u8]) -> Monster<'a> {
|
||||
flatbuffers::get_size_prefixed_root::<Monster<'a>>(buf)
|
||||
unsafe { flatbuffers::size_prefixed_root_unchecked::<Monster<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `Monster`
|
||||
/// and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `Monster` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `size_prefixed_root_as_monster_unchecked`.
|
||||
pub fn size_prefixed_root_as_monster(buf: &[u8]) -> Result<Monster, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `Monster` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn root_as_monster_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root_with_opts::<Monster<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `Monster` and returns
|
||||
/// it. Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_monster_unchecked`.
|
||||
pub fn size_prefixed_root_as_monster_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Monster<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root_with_opts::<Monster<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a Monster and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `Monster`.
|
||||
pub unsafe fn root_as_monster_unchecked(buf: &[u8]) -> Monster {
|
||||
flatbuffers::root_unchecked::<Monster>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Monster and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Monster`.
|
||||
pub unsafe fn size_prefixed_root_as_monster_unchecked(buf: &[u8]) -> Monster {
|
||||
flatbuffers::size_prefixed_root_unchecked::<Monster>(buf)
|
||||
}
|
||||
pub const MONSTER_IDENTIFIER: &str = "MONS";
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -77,7 +77,8 @@ impl<'a> flatbuffers::Follow<'a> for EnumInNestedNS {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,14 +93,27 @@ impl flatbuffers::Push for EnumInNestedNS {
|
||||
impl flatbuffers::EndianScalar for EnumInNestedNS {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(i8::to_le(self.0))
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(i8::from_le(self.0))
|
||||
let b = i8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for EnumInNestedNS {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for EnumInNestedNS {}
|
||||
// struct StructInNestedNS, aligned to 4
|
||||
#[repr(C, align(4))]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@@ -116,6 +130,7 @@ impl std::fmt::Debug for StructInNestedNS {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for StructInNestedNS {}
|
||||
impl flatbuffers::SafeSliceAccess for StructInNestedNS {}
|
||||
impl<'a> flatbuffers::Follow<'a> for StructInNestedNS {
|
||||
type Inner = &'a StructInNestedNS;
|
||||
@@ -153,7 +168,15 @@ impl<'b> flatbuffers::Push for &'b StructInNestedNS {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for StructInNestedNS {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl StructInNestedNS {
|
||||
pub fn new(_a: i32, _b: i32) -> Self {
|
||||
StructInNestedNS {
|
||||
@@ -217,6 +240,18 @@ impl<'a> TableInNestedNS<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TableInNestedNS<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<i32>(&"foo", Self::VT_FOO, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TableInNestedNSArgs {
|
||||
pub foo: i32,
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<'a> TableInFirstNS<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn foo_table(&self) -> Option<namespace_b::TableInNestedNS<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<namespace_b::TableInNestedNS<'a>>>(TableInFirstNS::VT_FOO_TABLE, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<namespace_b::TableInNestedNS>>(TableInFirstNS::VT_FOO_TABLE, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn foo_enum(&self) -> namespace_b::EnumInNestedNS {
|
||||
@@ -75,6 +75,20 @@ impl<'a> TableInFirstNS<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TableInFirstNS<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<namespace_b::TableInNestedNS>>(&"foo_table", Self::VT_FOO_TABLE, false)?
|
||||
.visit_field::<namespace_b::EnumInNestedNS>(&"foo_enum", Self::VT_FOO_ENUM, false)?
|
||||
.visit_field::<namespace_b::StructInNestedNS>(&"foo_struct", Self::VT_FOO_STRUCT, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TableInFirstNSArgs<'a> {
|
||||
pub foo_table: Option<flatbuffers::WIPOffset<namespace_b::TableInNestedNS<'a>>>,
|
||||
pub foo_enum: namespace_b::EnumInNestedNS,
|
||||
@@ -170,10 +184,22 @@ impl<'a> SecondTableInA<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn refer_to_c(&self) -> Option<super::namespace_c::TableInC<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_c::TableInC<'a>>>(SecondTableInA::VT_REFER_TO_C, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_c::TableInC>>(SecondTableInA::VT_REFER_TO_C, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for SecondTableInA<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<super::namespace_c::TableInC>>(&"refer_to_c", Self::VT_REFER_TO_C, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct SecondTableInAArgs<'a> {
|
||||
pub refer_to_c: Option<flatbuffers::WIPOffset<super::namespace_c::TableInC<'a>>>,
|
||||
}
|
||||
@@ -269,14 +295,27 @@ impl<'a> TableInC<'a> {
|
||||
|
||||
#[inline]
|
||||
pub fn refer_to_a1(&self) -> Option<super::namespace_a::TableInFirstNS<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::TableInFirstNS<'a>>>(TableInC::VT_REFER_TO_A1, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::TableInFirstNS>>(TableInC::VT_REFER_TO_A1, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn refer_to_a2(&self) -> Option<super::namespace_a::SecondTableInA<'a>> {
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::SecondTableInA<'a>>>(TableInC::VT_REFER_TO_A2, None)
|
||||
self._tab.get::<flatbuffers::ForwardsUOffset<super::namespace_a::SecondTableInA>>(TableInC::VT_REFER_TO_A2, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for TableInC<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<super::namespace_a::TableInFirstNS>>(&"refer_to_a1", Self::VT_REFER_TO_A1, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<super::namespace_a::SecondTableInA>>(&"refer_to_a2", Self::VT_REFER_TO_A2, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct TableInCArgs<'a> {
|
||||
pub refer_to_a1: Option<flatbuffers::WIPOffset<super::namespace_a::TableInFirstNS<'a>>>,
|
||||
pub refer_to_a2: Option<flatbuffers::WIPOffset<super::namespace_a::SecondTableInA<'a>>>,
|
||||
|
||||
@@ -69,7 +69,8 @@ impl<'a> flatbuffers::Follow<'a> for OptionalByte {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,14 +85,27 @@ impl flatbuffers::Push for OptionalByte {
|
||||
impl flatbuffers::EndianScalar for OptionalByte {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
Self(i8::to_le(self.0))
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
fn from_little_endian(self) -> Self {
|
||||
Self(i8::from_le(self.0))
|
||||
let b = i8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for OptionalByte {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for OptionalByte {}
|
||||
pub enum ScalarStuffOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
@@ -341,6 +355,53 @@ impl<'a> ScalarStuff<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for ScalarStuff<'_> {
|
||||
#[inline]
|
||||
fn run_verifier<'o, 'b>(
|
||||
v: &mut flatbuffers::Verifier<'o, 'b>, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<i8>(&"just_i8", Self::VT_JUST_I8, false)?
|
||||
.visit_field::<i8>(&"maybe_i8", Self::VT_MAYBE_I8, false)?
|
||||
.visit_field::<i8>(&"default_i8", Self::VT_DEFAULT_I8, false)?
|
||||
.visit_field::<u8>(&"just_u8", Self::VT_JUST_U8, false)?
|
||||
.visit_field::<u8>(&"maybe_u8", Self::VT_MAYBE_U8, false)?
|
||||
.visit_field::<u8>(&"default_u8", Self::VT_DEFAULT_U8, false)?
|
||||
.visit_field::<i16>(&"just_i16", Self::VT_JUST_I16, false)?
|
||||
.visit_field::<i16>(&"maybe_i16", Self::VT_MAYBE_I16, false)?
|
||||
.visit_field::<i16>(&"default_i16", Self::VT_DEFAULT_I16, false)?
|
||||
.visit_field::<u16>(&"just_u16", Self::VT_JUST_U16, false)?
|
||||
.visit_field::<u16>(&"maybe_u16", Self::VT_MAYBE_U16, false)?
|
||||
.visit_field::<u16>(&"default_u16", Self::VT_DEFAULT_U16, false)?
|
||||
.visit_field::<i32>(&"just_i32", Self::VT_JUST_I32, false)?
|
||||
.visit_field::<i32>(&"maybe_i32", Self::VT_MAYBE_I32, false)?
|
||||
.visit_field::<i32>(&"default_i32", Self::VT_DEFAULT_I32, false)?
|
||||
.visit_field::<u32>(&"just_u32", Self::VT_JUST_U32, false)?
|
||||
.visit_field::<u32>(&"maybe_u32", Self::VT_MAYBE_U32, false)?
|
||||
.visit_field::<u32>(&"default_u32", Self::VT_DEFAULT_U32, false)?
|
||||
.visit_field::<i64>(&"just_i64", Self::VT_JUST_I64, false)?
|
||||
.visit_field::<i64>(&"maybe_i64", Self::VT_MAYBE_I64, false)?
|
||||
.visit_field::<i64>(&"default_i64", Self::VT_DEFAULT_I64, false)?
|
||||
.visit_field::<u64>(&"just_u64", Self::VT_JUST_U64, false)?
|
||||
.visit_field::<u64>(&"maybe_u64", Self::VT_MAYBE_U64, false)?
|
||||
.visit_field::<u64>(&"default_u64", Self::VT_DEFAULT_U64, false)?
|
||||
.visit_field::<f32>(&"just_f32", Self::VT_JUST_F32, false)?
|
||||
.visit_field::<f32>(&"maybe_f32", Self::VT_MAYBE_F32, false)?
|
||||
.visit_field::<f32>(&"default_f32", Self::VT_DEFAULT_F32, false)?
|
||||
.visit_field::<f64>(&"just_f64", Self::VT_JUST_F64, false)?
|
||||
.visit_field::<f64>(&"maybe_f64", Self::VT_MAYBE_F64, false)?
|
||||
.visit_field::<f64>(&"default_f64", Self::VT_DEFAULT_F64, false)?
|
||||
.visit_field::<bool>(&"just_bool", Self::VT_JUST_BOOL, false)?
|
||||
.visit_field::<bool>(&"maybe_bool", Self::VT_MAYBE_BOOL, false)?
|
||||
.visit_field::<bool>(&"default_bool", Self::VT_DEFAULT_BOOL, false)?
|
||||
.visit_field::<OptionalByte>(&"just_enum", Self::VT_JUST_ENUM, false)?
|
||||
.visit_field::<OptionalByte>(&"maybe_enum", Self::VT_MAYBE_ENUM, false)?
|
||||
.visit_field::<OptionalByte>(&"default_enum", Self::VT_DEFAULT_ENUM, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ScalarStuffArgs {
|
||||
pub just_i8: i8,
|
||||
pub maybe_i8: Option<i8>,
|
||||
@@ -629,15 +690,77 @@ impl std::fmt::Debug for ScalarStuff<'_> {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_root_as_scalar_stuff<'a>(buf: &'a [u8]) -> ScalarStuff<'a> {
|
||||
flatbuffers::get_root::<ScalarStuff<'a>>(buf)
|
||||
unsafe { flatbuffers::root_unchecked::<ScalarStuff<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated(since="1.13", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_size_prefixed_root_as_scalar_stuff<'a>(buf: &'a [u8]) -> ScalarStuff<'a> {
|
||||
flatbuffers::get_size_prefixed_root::<ScalarStuff<'a>>(buf)
|
||||
unsafe { flatbuffers::size_prefixed_root_unchecked::<ScalarStuff<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `ScalarStuff`
|
||||
/// and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_scalar_stuff_unchecked`.
|
||||
pub fn root_as_scalar_stuff(buf: &[u8]) -> Result<ScalarStuff, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root::<ScalarStuff>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `ScalarStuff` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `size_prefixed_root_as_scalar_stuff_unchecked`.
|
||||
pub fn size_prefixed_root_as_scalar_stuff(buf: &[u8]) -> Result<ScalarStuff, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root::<ScalarStuff>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `ScalarStuff` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_scalar_stuff_unchecked`.
|
||||
pub fn root_as_scalar_stuff_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ScalarStuff<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root_with_opts::<ScalarStuff<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `ScalarStuff` and returns
|
||||
/// it. Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_scalar_stuff_unchecked`.
|
||||
pub fn size_prefixed_root_as_scalar_stuff_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ScalarStuff<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root_with_opts::<ScalarStuff<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a ScalarStuff and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `ScalarStuff`.
|
||||
pub unsafe fn root_as_scalar_stuff_unchecked(buf: &[u8]) -> ScalarStuff {
|
||||
flatbuffers::root_unchecked::<ScalarStuff>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed ScalarStuff and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `ScalarStuff`.
|
||||
pub unsafe fn size_prefixed_root_as_scalar_stuff_unchecked(buf: &[u8]) -> ScalarStuff {
|
||||
flatbuffers::size_prefixed_root_unchecked::<ScalarStuff>(buf)
|
||||
}
|
||||
pub const SCALAR_STUFF_IDENTIFIER: &str = "NULL";
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -131,7 +131,7 @@ fn main() {
|
||||
|
||||
// do many reads, forcing them to execute by using assert_eq:
|
||||
{
|
||||
let m = my_game::example::get_root_as_monster(buf);
|
||||
let m = unsafe { my_game::example::root_as_monster_unchecked(buf) };
|
||||
assert_eq!(80, m.hp());
|
||||
assert_eq!(150, m.mana());
|
||||
assert_eq!("MyMonster", m.name());
|
||||
|
||||
@@ -20,7 +20,7 @@ fn main() {
|
||||
let mut buf = Vec::new();
|
||||
f.read_to_end(&mut buf).expect("file reading failed");
|
||||
|
||||
let monster = my_game::example::get_root_as_monster(&buf[..]);
|
||||
let monster = my_game::example::root_as_monster(&buf[..]).unwrap();
|
||||
println!("{}", monster.hp()); // `80`
|
||||
println!("{}", monster.mana()); // default value of `150`
|
||||
println!("{:?}", monster.name()); // Some("MyMonster")
|
||||
|
||||
@@ -177,9 +177,9 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require
|
||||
}
|
||||
|
||||
let m = if size_prefixed {
|
||||
my_game::example::get_size_prefixed_root_as_monster(bytes)
|
||||
my_game::example::size_prefixed_root_as_monster(bytes).unwrap()
|
||||
} else {
|
||||
my_game::example::get_root_as_monster(bytes)
|
||||
my_game::example::root_as_monster(bytes).unwrap()
|
||||
};
|
||||
|
||||
check_eq!(m.hp(), 80)?;
|
||||
@@ -245,6 +245,106 @@ fn builder_collapses_into_vec() {
|
||||
serialized_example_is_accessible_and_correct(&backing_buf[head..], true, false).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verifier_one_byte_errors_do_not_crash() {
|
||||
let mut b = flatbuffers::FlatBufferBuilder::new();
|
||||
create_serialized_example_with_library_code(&mut b);
|
||||
let mut badbuf = b.finished_data().to_vec();
|
||||
// If the verifier says a buffer is okay then using it won't cause a crash.
|
||||
// We use write_fmt since Debug visits all the fields - but there's no need to store anything.
|
||||
struct ForgetfulWriter;
|
||||
use std::fmt::Write;
|
||||
impl Write for ForgetfulWriter {
|
||||
fn write_str(&mut self, _: &str) -> Result<(), std::fmt::Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
let mut w = ForgetfulWriter;
|
||||
for d in 1..=255u8 {
|
||||
for i in 0..badbuf.len() {
|
||||
let orig = badbuf[i];
|
||||
badbuf[i] = badbuf[i].wrapping_add(d);
|
||||
if let Ok(m) = flatbuffers::root::<my_game::example::Monster>(&badbuf) {
|
||||
w.write_fmt(format_args!("{:?}", m)).unwrap()
|
||||
}
|
||||
badbuf[i] = orig;
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn verifier_too_many_tables() {
|
||||
use my_game::example::*;
|
||||
let b = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
let r = Referrable::create(b, &ReferrableArgs { id: 42 });
|
||||
let rs = b.create_vector(&vec![r; 500]);
|
||||
let name = Some(b.create_string("foo"));
|
||||
let m = Monster::create(b, &MonsterArgs {
|
||||
vector_of_referrables: Some(rs),
|
||||
name, // required field.
|
||||
..Default::default()
|
||||
});
|
||||
b.finish(m, None);
|
||||
|
||||
let data = b.finished_data();
|
||||
let mut opts = flatbuffers::VerifierOptions::default();
|
||||
|
||||
opts.max_tables = 500;
|
||||
let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
|
||||
assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::TooManyTables);
|
||||
|
||||
opts.max_tables += 2;
|
||||
assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
|
||||
}
|
||||
#[test]
|
||||
fn verifier_apparent_size_too_large() {
|
||||
use my_game::example::*;
|
||||
let b = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
let name = Some(b.create_string("foo"));
|
||||
// String amplification attack.
|
||||
let s = b.create_string(&(std::iter::repeat("X").take(1000).collect::<String>()));
|
||||
let testarrayofstring = Some(b.create_vector(&vec![s; 1000]));
|
||||
let m = Monster::create(b, &MonsterArgs {
|
||||
testarrayofstring,
|
||||
name, // required field.
|
||||
..Default::default()
|
||||
});
|
||||
b.finish(m, None);
|
||||
let data = b.finished_data();
|
||||
assert!(data.len() < 5100); // est 4000 for the vector + 1000 for the string + 100 overhead.
|
||||
let mut opts = flatbuffers::VerifierOptions::default();
|
||||
opts.max_apparent_size = 1_000_000;
|
||||
|
||||
let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
|
||||
assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::ApparentSizeTooLarge);
|
||||
|
||||
opts.max_apparent_size += 20_000;
|
||||
assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
|
||||
}
|
||||
#[test]
|
||||
fn verifier_in_too_deep() {
|
||||
use my_game::example::*;
|
||||
let b = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
let name = Some(b.create_string("foo"));
|
||||
let mut prev_monster = None;
|
||||
for _ in 0..11 {
|
||||
prev_monster = Some(Monster::create(b, &MonsterArgs {
|
||||
enemy: prev_monster,
|
||||
name, // required field.
|
||||
..Default::default()
|
||||
}));
|
||||
};
|
||||
b.finish(prev_monster.unwrap(), None);
|
||||
let mut opts = flatbuffers::VerifierOptions::default();
|
||||
opts.max_depth = 10;
|
||||
|
||||
let data = b.finished_data();
|
||||
let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
|
||||
assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::DepthLimitReached);
|
||||
|
||||
opts.max_depth += 1;
|
||||
assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod generated_constants {
|
||||
extern crate flatbuffers;
|
||||
@@ -316,7 +416,7 @@ mod lifetime_correctness {
|
||||
let slice: &[u8] = &buf;
|
||||
let slice: &'static [u8] = unsafe { mem::transmute(slice) };
|
||||
// make sure values retrieved from the 'static buffer are themselves 'static
|
||||
let monster: my_game::example::Monster<'static> = my_game::example::get_root_as_monster(slice);
|
||||
let monster: my_game::example::Monster<'static> = my_game::example::root_as_monster(slice).unwrap();
|
||||
// this line should compile:
|
||||
let name: Option<&'static str> = monster._tab.get::<flatbuffers::ForwardsUOffset<&str>>(my_game::example::Monster::VT_NAME, None);
|
||||
assert_eq!(name, Some("MyMonster"));
|
||||
@@ -334,7 +434,7 @@ mod lifetime_correctness {
|
||||
fn table_object_self_lifetime_in_closure() {
|
||||
// This test is designed to ensure that lifetimes for temporary intermediate tables aren't inflated beyond where the need to be.
|
||||
let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
|
||||
let monster = my_game::example::get_root_as_monster(&buf);
|
||||
let monster = my_game::example::root_as_monster(&buf).unwrap();
|
||||
let enemy: Option<my_game::example::Monster> = monster.enemy();
|
||||
// This line won't compile if "self" is required to live for the lifetime of buf above as the borrow disappears at the end of the closure.
|
||||
let enemy_of_my_enemy = enemy.map(|e| {
|
||||
@@ -357,7 +457,7 @@ mod roundtrip_generated_code {
|
||||
fn build_mon<'a, 'b>(builder: &'a mut flatbuffers::FlatBufferBuilder, args: &'b my_game::example::MonsterArgs) -> my_game::example::Monster<'a> {
|
||||
let mon = my_game::example::Monster::create(builder, &args);
|
||||
my_game::example::finish_monster_buffer(builder, mon);
|
||||
my_game::example::get_root_as_monster(builder.finished_data())
|
||||
my_game::example::root_as_monster(builder.finished_data()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -437,7 +537,7 @@ mod roundtrip_generated_code {
|
||||
my_game::example::finish_monster_buffer(b, outer);
|
||||
}
|
||||
|
||||
let mon = my_game::example::get_root_as_monster(b.finished_data());
|
||||
let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
|
||||
assert_eq!(mon.name(), "bar");
|
||||
assert_eq!(mon.test_type(), my_game::example::Any::Monster);
|
||||
assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(),
|
||||
@@ -473,7 +573,7 @@ mod roundtrip_generated_code {
|
||||
my_game::example::finish_monster_buffer(b, outer);
|
||||
}
|
||||
|
||||
let mon = my_game::example::get_root_as_monster(b.finished_data());
|
||||
let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
|
||||
assert_eq!(mon.name(), "bar");
|
||||
assert_eq!(mon.enemy().unwrap().name(), "foo");
|
||||
}
|
||||
@@ -503,7 +603,7 @@ mod roundtrip_generated_code {
|
||||
my_game::example::finish_monster_buffer(b, outer);
|
||||
}
|
||||
|
||||
let mon = my_game::example::get_root_as_monster(b.finished_data());
|
||||
let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
|
||||
assert_eq!(mon.name(), "bar");
|
||||
assert_eq!(mon.testempty().unwrap().id(), Some("foo"));
|
||||
}
|
||||
@@ -540,12 +640,12 @@ mod roundtrip_generated_code {
|
||||
b1
|
||||
};
|
||||
|
||||
let m = my_game::example::get_root_as_monster(b1.finished_data());
|
||||
let m = my_game::example::root_as_monster(b1.finished_data()).unwrap();
|
||||
|
||||
assert!(m.testnestedflatbuffer().is_some());
|
||||
assert_eq!(m.testnestedflatbuffer().unwrap(), b0.finished_data());
|
||||
|
||||
let m2_a = my_game::example::get_root_as_monster(m.testnestedflatbuffer().unwrap());
|
||||
let m2_a = my_game::example::root_as_monster(m.testnestedflatbuffer().unwrap()).unwrap();
|
||||
assert_eq!(m2_a.hp(), 123);
|
||||
assert_eq!(m2_a.name(), "foobar");
|
||||
|
||||
@@ -799,7 +899,7 @@ mod generated_code_alignment_and_padding {
|
||||
my_game::example::finish_monster_buffer(b, mon);
|
||||
}
|
||||
let buf = b.finished_data();
|
||||
let mon = my_game::example::get_root_as_monster(buf);
|
||||
let mon = my_game::example::root_as_monster(buf).unwrap();
|
||||
let vec3 = mon.pos().unwrap();
|
||||
|
||||
let start_ptr = buf.as_ptr() as usize;
|
||||
@@ -835,7 +935,7 @@ mod generated_code_alignment_and_padding {
|
||||
my_game::example::finish_monster_buffer(b, mon);
|
||||
}
|
||||
let buf = b.finished_data();
|
||||
let mon = my_game::example::get_root_as_monster(buf);
|
||||
let mon = my_game::example::root_as_monster(buf).unwrap();
|
||||
let abilities = mon.testarrayofsortedstruct().unwrap();
|
||||
|
||||
let start_ptr = buf.as_ptr() as usize;
|
||||
@@ -1142,7 +1242,7 @@ mod framing_format {
|
||||
|
||||
// Access it.
|
||||
let buf = b.finished_data();
|
||||
let m = flatbuffers::get_size_prefixed_root::<my_game::example::Monster>(buf);
|
||||
let m = flatbuffers::size_prefixed_root::<my_game::example::Monster>(buf).unwrap();
|
||||
assert_eq!(m.mana(), 200);
|
||||
assert_eq!(m.hp(), 300);
|
||||
assert_eq!(m.name(), "bob");
|
||||
@@ -1538,7 +1638,7 @@ mod write_and_read_examples {
|
||||
create_serialized_example_with_generated_code(b);
|
||||
let buf = b.finished_data();
|
||||
serialized_example_is_accessible_and_correct(&buf, true, false).unwrap();
|
||||
let m = super::my_game::example::get_root_as_monster(buf);
|
||||
let m = super::my_game::example::root_as_monster(buf).unwrap();
|
||||
assert_eq!(
|
||||
format!("{:.5?}", &m),
|
||||
"Monster { pos: Some(Vec3 { x: 1.00000, y: 2.00000, z: 3.00000, \
|
||||
@@ -1728,7 +1828,7 @@ mod generated_key_comparisons {
|
||||
let builder = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
super::create_serialized_example_with_library_code(builder);
|
||||
let buf = builder.finished_data();
|
||||
let a = my_game::example::get_root_as_monster(buf);
|
||||
let a = my_game::example::root_as_monster(buf).unwrap();
|
||||
|
||||
// preconditions
|
||||
assert_eq!(a.name(), "MyMonster");
|
||||
@@ -1744,7 +1844,7 @@ mod generated_key_comparisons {
|
||||
let builder = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
super::create_serialized_example_with_library_code(builder);
|
||||
let buf = builder.finished_data();
|
||||
let a = my_game::example::get_root_as_monster(buf);
|
||||
let a = my_game::example::root_as_monster(buf).unwrap();
|
||||
let b = a.test_as_monster().unwrap();
|
||||
|
||||
// preconditions
|
||||
|
||||
@@ -27,13 +27,13 @@ macro_rules! make_test {
|
||||
);
|
||||
builder.finish(ss, None);
|
||||
|
||||
let s = flatbuffers::get_root::<ScalarStuff>(builder.finished_data());
|
||||
let s = flatbuffers::root::<ScalarStuff>(builder.finished_data()).unwrap();
|
||||
assert_eq!(s.$just(), $five);
|
||||
assert_eq!(s.$default(), $five);
|
||||
assert_eq!(s.$maybe(), Some($five));
|
||||
|
||||
// Test defaults are used when not specified.
|
||||
let s = flatbuffers::get_root::<ScalarStuff>(&[0; 8]);
|
||||
let s = flatbuffers::root::<ScalarStuff>(&[0; 8]).unwrap();
|
||||
assert_eq!(s.$just(), $zero);
|
||||
assert_eq!(s.$default(), $fortytwo);
|
||||
assert_eq!(s.$maybe(), None);
|
||||
|
||||
Reference in New Issue
Block a user