mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
[Rust] Add support for fixed size arrays (#6548)
* Add support for fixed size arrays * clang-format * Update rust image to 1.51 to support const generics * Handle correctly big endian * Add fuzz tests and clean code * Add struct fuzz test and optimize struct arrays for api * Bump flatbuffers crate version
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "flatbuffers"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
edition = "2018"
|
||||
authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
|
||||
license = "Apache-2.0"
|
||||
|
||||
136
rust/flatbuffers/src/array.rs
Normal file
136
rust/flatbuffers/src/array.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2021 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::Follow;
|
||||
use crate::{
|
||||
vector::{SafeSliceAccess, VectorIter},
|
||||
EndianScalar,
|
||||
};
|
||||
use std::fmt::{Debug, Formatter, Result};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::size_of;
|
||||
use std::slice::from_raw_parts;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Array<'a, T: 'a, const N: usize>(&'a [u8], PhantomData<T>);
|
||||
|
||||
impl<'a, T: 'a, const N: usize> Debug for Array<'a, T, N>
|
||||
where
|
||||
T: 'a + Follow<'a>,
|
||||
<T as Follow<'a>>::Inner: Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
|
||||
#[inline(always)]
|
||||
pub fn new(buf: &'a [u8]) -> Self {
|
||||
debug_assert!(size_of::<T>() * N == buf.len());
|
||||
|
||||
Array {
|
||||
0: buf,
|
||||
1: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn len(&self) -> usize {
|
||||
N
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Follow<'a> + 'a, const N: usize> Array<'a, T, N> {
|
||||
#[inline(always)]
|
||||
pub fn get(&self, idx: usize) -> T::Inner {
|
||||
debug_assert!(idx < N);
|
||||
let sz = size_of::<T>();
|
||||
T::follow(self.0, sz * idx)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> VectorIter<'a, T> {
|
||||
VectorIter::from_slice(self.0, self.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Follow<'a> + Debug, const N: usize> Into<[T::Inner; N]> for Array<'a, T, N> {
|
||||
#[inline(always)]
|
||||
fn into(self) -> [T::Inner; N] {
|
||||
array_init(|i| self.get(i))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: SafeSliceAccess + 'a, const N: usize> Array<'a, T, N> {
|
||||
pub fn safe_slice(self) -> &'a [T] {
|
||||
let sz = size_of::<T>();
|
||||
debug_assert!(sz > 0);
|
||||
let ptr = self.0.as_ptr() as *const T;
|
||||
unsafe { from_raw_parts(ptr, N) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement Follow for all possible Arrays that have Follow-able elements.
|
||||
impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
|
||||
type Inner = Array<'a, T, N>;
|
||||
#[inline(always)]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Array::new(&buf[loc..loc + N * size_of::<T>()])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emplace_scalar_array<T: EndianScalar, const N: usize>(
|
||||
buf: &mut [u8],
|
||||
loc: usize,
|
||||
src: &[T; N],
|
||||
) {
|
||||
let mut buf_ptr = buf[loc..].as_mut_ptr() as *mut T;
|
||||
for item in src.iter() {
|
||||
let item_le = item.to_little_endian();
|
||||
unsafe {
|
||||
buf_ptr.write(item_le);
|
||||
buf_ptr = buf_ptr.add(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Follow<'a> + 'a, const N: usize> IntoIterator for Array<'a, T, N> {
|
||||
type Item = T::Inner;
|
||||
type IntoIter = VectorIter<'a, T>;
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn array_init<F, T, const N: usize>(mut initializer: F) -> [T; N]
|
||||
where
|
||||
F: FnMut(usize) -> T,
|
||||
{
|
||||
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
|
||||
let mut ptr_i = array.as_mut_ptr() as *mut T;
|
||||
|
||||
unsafe {
|
||||
for i in 0..N {
|
||||
let value_i = initializer(i);
|
||||
ptr_i.write(value_i);
|
||||
ptr_i = ptr_i.add(1);
|
||||
}
|
||||
array.assume_init()
|
||||
}
|
||||
}
|
||||
@@ -253,12 +253,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
||||
// Gets The pointer to the size of the string
|
||||
let str_memory = &buf[buf.len() - ptr..];
|
||||
// Gets the size of the written string from buffer
|
||||
let size = u32::from_le_bytes([
|
||||
str_memory[0],
|
||||
str_memory[1],
|
||||
str_memory[2],
|
||||
str_memory[3],
|
||||
]) as usize;
|
||||
let size =
|
||||
u32::from_le_bytes([str_memory[0], str_memory[1], str_memory[2], str_memory[3]])
|
||||
as usize;
|
||||
// Size of the string size
|
||||
let string_size: usize = 4;
|
||||
// Fetches actual string bytes from index of string after string size
|
||||
@@ -728,23 +725,21 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
||||
// could be empty (e.g. for empty tables, or for all-default values).
|
||||
debug_assert!(
|
||||
self.nested,
|
||||
format!(
|
||||
"incorrect FlatBufferBuilder usage: {} must be called while in a nested state",
|
||||
fn_name
|
||||
)
|
||||
"incorrect FlatBufferBuilder usage: {} must be called while in a nested state",
|
||||
fn_name
|
||||
);
|
||||
}
|
||||
#[inline]
|
||||
fn assert_not_nested(&self, msg: &'static str) {
|
||||
debug_assert!(!self.nested, msg);
|
||||
debug_assert!(!self.nested, "{}", msg);
|
||||
}
|
||||
#[inline]
|
||||
fn assert_finished(&self, msg: &'static str) {
|
||||
debug_assert!(self.finished, msg);
|
||||
debug_assert!(self.finished, "{}", msg);
|
||||
}
|
||||
#[inline]
|
||||
fn assert_not_finished(&self, msg: &'static str) {
|
||||
debug_assert!(!self.finished, msg);
|
||||
debug_assert!(!self.finished, "{}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ pub fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const T as *const u8,
|
||||
s.as_mut_ptr() as *mut u8,
|
||||
size_of::<T>()
|
||||
size_of::<T>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -174,11 +174,7 @@ pub fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
|
||||
let mut mem = core::mem::MaybeUninit::<T>::uninit();
|
||||
// Since [u8] has alignment 1, we copy it into T which may have higher alignment.
|
||||
let x = unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
s.as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
size_of::<T>()
|
||||
);
|
||||
core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size_of::<T>());
|
||||
mem.assume_init()
|
||||
};
|
||||
x.from_little_endian()
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
//! 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 array;
|
||||
mod builder;
|
||||
mod endian_scalar;
|
||||
mod follow;
|
||||
@@ -40,6 +41,7 @@ mod verifier;
|
||||
mod vtable;
|
||||
mod vtable_writer;
|
||||
|
||||
pub use crate::array::{array_init, emplace_scalar_array, Array};
|
||||
pub use crate::builder::FlatBufferBuilder;
|
||||
pub use crate::endian_scalar::{
|
||||
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
|
||||
|
||||
@@ -29,11 +29,15 @@ use crate::primitives::*;
|
||||
|
||||
pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
|
||||
|
||||
impl<'a, T:'a> Default for Vector<'a, T> {
|
||||
impl<'a, T: 'a> Default for Vector<'a, T> {
|
||||
fn default() -> Self {
|
||||
// Static, length 0 vector.
|
||||
// Note that derived default causes UB due to issues in read_scalar_at /facepalm.
|
||||
Self(&[0; core::mem::size_of::<UOffsetT>()], 0, Default::default())
|
||||
Self(
|
||||
&[0; core::mem::size_of::<UOffsetT>()],
|
||||
0,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +92,7 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> VectorIter<'a, T> {
|
||||
VectorIter::new(*self)
|
||||
VectorIter::from_vector(*self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +189,7 @@ pub struct VectorIter<'a, T: 'a> {
|
||||
|
||||
impl<'a, T: 'a> VectorIter<'a, T> {
|
||||
#[inline]
|
||||
pub fn new(inner: Vector<'a, T>) -> Self {
|
||||
pub fn from_vector(inner: Vector<'a, T>) -> Self {
|
||||
VectorIter {
|
||||
buf: inner.0,
|
||||
// inner.1 is the location of the data for the vector.
|
||||
@@ -196,6 +200,16 @@ impl<'a, T: 'a> VectorIter<'a, T> {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
|
||||
VectorIter {
|
||||
buf,
|
||||
loc: 0,
|
||||
remaining: items_num,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Follow<'a> + 'a> Clone for VectorIter<'a, T> {
|
||||
|
||||
@@ -39,8 +39,10 @@ pub enum InvalidFlatbuffer {
|
||||
required: &'static str,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Union exactly one of union discriminant (`{field_type}`) and value \
|
||||
(`{field}`) are present.\n{error_trace}")]
|
||||
#[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,
|
||||
@@ -70,8 +72,10 @@ pub enum InvalidFlatbuffer {
|
||||
range: Range<usize>,
|
||||
error_trace: ErrorTrace,
|
||||
},
|
||||
#[error("Signed offset at position {position} has value {soffset} which points out of bounds.\
|
||||
\n{error_trace}")]
|
||||
#[error(
|
||||
"Signed offset at position {position} has value {soffset} which points out of bounds.\
|
||||
\n{error_trace}"
|
||||
)]
|
||||
SignedOffsetOutOfBounds {
|
||||
soffset: SOffsetT,
|
||||
position: usize,
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod my_game {
|
||||
@@ -15,7 +15,7 @@ pub mod my_game {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod sample {
|
||||
|
||||
@@ -23,7 +23,7 @@ pub mod sample {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_COLOR: i8 = 0;
|
||||
@@ -313,7 +313,7 @@ impl<'a> flatbuffers::Verifiable for Vec3 {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Vec3 {
|
||||
impl<'a> Vec3 {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
x: f32,
|
||||
|
||||
@@ -81,6 +81,10 @@ enum FullType {
|
||||
ftVectorOfTable = 14,
|
||||
ftVectorOfString = 15,
|
||||
ftVectorOfUnionValue = 16,
|
||||
|
||||
ftArrayOfBuiltin = 17,
|
||||
ftArrayOfEnum = 18,
|
||||
ftArrayOfStruct = 19,
|
||||
};
|
||||
|
||||
// Convert a Type to a FullType (exhaustive).
|
||||
@@ -127,6 +131,23 @@ FullType GetFullType(const Type &type) {
|
||||
FLATBUFFERS_ASSERT(false && "vector of vectors are unsupported");
|
||||
}
|
||||
}
|
||||
} else if (IsArray(type)) {
|
||||
switch (GetFullType(type.VectorType())) {
|
||||
case ftInteger:
|
||||
case ftFloat:
|
||||
case ftBool: {
|
||||
return ftArrayOfBuiltin;
|
||||
}
|
||||
case ftStruct: {
|
||||
return ftArrayOfStruct;
|
||||
}
|
||||
case ftEnumKey: {
|
||||
return ftArrayOfEnum;
|
||||
}
|
||||
default: {
|
||||
FLATBUFFERS_ASSERT(false && "Unsupported type for fixed array");
|
||||
}
|
||||
}
|
||||
} else if (type.enum_def != nullptr) {
|
||||
if (type.enum_def->is_union) {
|
||||
if (type.base_type == BASE_TYPE_UNION) {
|
||||
@@ -567,6 +588,12 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftUnionKey: {
|
||||
return GetTypeBasic(type);
|
||||
}
|
||||
case ftArrayOfBuiltin:
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct: {
|
||||
return "[" + GetTypeGet(type.VectorType()) + "; " +
|
||||
NumToString(type.fixed_length) + "]";
|
||||
}
|
||||
case ftTable: {
|
||||
return WrapInNameSpace(type.struct_def->defined_namespace,
|
||||
type.struct_def->name) +
|
||||
@@ -937,6 +964,9 @@ class RustGenerator : public BaseGenerator {
|
||||
return "INVALID_CODE_GENERATION";
|
||||
}
|
||||
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfBuiltin:
|
||||
case ftVectorOfBool:
|
||||
case ftVectorOfFloat:
|
||||
case ftVectorOfInteger:
|
||||
@@ -1035,6 +1065,12 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftVectorOfUnionValue: {
|
||||
return WrapUOffsetsVector("flatbuffers::Table<" + lifetime + ">");
|
||||
}
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfBuiltin: {
|
||||
FLATBUFFERS_ASSERT(false && "arrays are not supported within tables");
|
||||
return "ARRAYS_NOT_SUPPORTED_IN_TABLES";
|
||||
}
|
||||
}
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
@@ -1101,6 +1137,21 @@ class RustGenerator : public BaseGenerator {
|
||||
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
|
||||
return "INVALID_CODE_GENERATION"; // OH NO!
|
||||
}
|
||||
case ftArrayOfEnum: {
|
||||
ty = "[" + WrapInNameSpace(*type.VectorType().enum_def) + "; " +
|
||||
NumToString(type.fixed_length) + "]";
|
||||
break;
|
||||
}
|
||||
case ftArrayOfStruct: {
|
||||
ty = "[" + NamespacedNativeName(*type.VectorType().struct_def) + "; " +
|
||||
NumToString(type.fixed_length) + "]";
|
||||
break;
|
||||
}
|
||||
case ftArrayOfBuiltin: {
|
||||
ty = "[" + GetTypeBasic(type.VectorType()) + "; " +
|
||||
NumToString(type.fixed_length) + "]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (in_a_table && !IsUnion(type) && field.IsOptional()) {
|
||||
return "Option<" + ty + ">";
|
||||
@@ -1170,6 +1221,21 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftUnionValue: {
|
||||
return "flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>";
|
||||
}
|
||||
case ftArrayOfBuiltin: {
|
||||
const auto typname = GetTypeBasic(type.VectorType());
|
||||
return "flatbuffers::Array<" + lifetime + ", " + typname + ", " +
|
||||
NumToString(type.fixed_length) + ">";
|
||||
}
|
||||
case ftArrayOfEnum: {
|
||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||
return "flatbuffers::Array<" + lifetime + ", " + typname + ", " +
|
||||
NumToString(type.fixed_length) + ">";
|
||||
}
|
||||
case ftArrayOfStruct: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return "flatbuffers::Array<" + lifetime + ", " + typname + ", " +
|
||||
NumToString(type.fixed_length) + ">";
|
||||
}
|
||||
}
|
||||
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
@@ -1217,6 +1283,12 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftVectorOfUnionValue: {
|
||||
return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>";
|
||||
}
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfBuiltin: {
|
||||
FLATBUFFERS_ASSERT(false && "arrays are not supported within tables");
|
||||
return "ARRAYS_NOT_SUPPORTED_IN_TABLES";
|
||||
}
|
||||
}
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
@@ -1289,6 +1361,12 @@ class RustGenerator : public BaseGenerator {
|
||||
// Into trait to convert tables to typesafe union values.
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfBuiltin: {
|
||||
FLATBUFFERS_ASSERT(false && "arrays are not supported within tables");
|
||||
return "ARRAYS_NOT_SUPPORTED_IN_TABLES";
|
||||
}
|
||||
}
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
@@ -1302,6 +1380,10 @@ class RustGenerator : public BaseGenerator {
|
||||
const auto WrapVector = [&](std::string ty) -> std::string {
|
||||
return "flatbuffers::Vector<" + lifetime + ", " + ty + ">";
|
||||
};
|
||||
const auto WrapArray = [&](std::string ty, uint16_t length) -> std::string {
|
||||
return "flatbuffers::Array<" + lifetime + ", " + ty + ", " +
|
||||
NumToString(length) + ">";
|
||||
};
|
||||
switch (GetFullType(type)) {
|
||||
case ftInteger:
|
||||
case ftFloat:
|
||||
@@ -1351,6 +1433,18 @@ class RustGenerator : public BaseGenerator {
|
||||
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
case ftArrayOfEnum: {
|
||||
const auto typname = WrapInNameSpace(*type.VectorType().enum_def);
|
||||
return WrapArray(typname, type.fixed_length);
|
||||
}
|
||||
case ftArrayOfStruct: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
return WrapArray(typname, type.fixed_length);
|
||||
}
|
||||
case ftArrayOfBuiltin: {
|
||||
const auto typname = GetTypeBasic(type.VectorType());
|
||||
return WrapArray(typname, type.fixed_length);
|
||||
}
|
||||
}
|
||||
return "INVALID_CODE_GENERATION"; // for return analysis
|
||||
}
|
||||
@@ -1595,6 +1689,13 @@ class RustGenerator : public BaseGenerator {
|
||||
FLATBUFFERS_ASSERT(false && "vectors of unions not yet supported");
|
||||
return;
|
||||
}
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfBuiltin: {
|
||||
FLATBUFFERS_ASSERT(false &&
|
||||
"arrays are not supported within tables");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (field.IsOptional()) {
|
||||
code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}}().map(|x| {";
|
||||
@@ -2037,6 +2138,12 @@ class RustGenerator : public BaseGenerator {
|
||||
FLATBUFFERS_ASSERT(false && "vectors of unions not yet supported");
|
||||
return;
|
||||
}
|
||||
case ftArrayOfEnum:
|
||||
case ftArrayOfStruct:
|
||||
case ftArrayOfBuiltin: {
|
||||
FLATBUFFERS_ASSERT(false && "arrays are not supported within tables");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
code_ += " {{STRUCT_NAME}}::create(_fbb, &{{STRUCT_NAME}}Args{";
|
||||
@@ -2317,11 +2424,11 @@ class RustGenerator : public BaseGenerator {
|
||||
code_.SetValue("FIELD_OBJECT_TYPE", ObjectFieldType(field, false));
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
code_.SetValue("FIELD_OFFSET", NumToString(offset_to_field));
|
||||
code_.SetValue("REF", IsStruct(field.value.type) ? "&" : "");
|
||||
code_.SetValue(
|
||||
"REF",
|
||||
IsStruct(field.value.type) || IsArray(field.value.type) ? "&" : "");
|
||||
cb(field);
|
||||
const size_t size = IsStruct(field.value.type)
|
||||
? field.value.type.struct_def->bytesize
|
||||
: SizeOf(field.value.type.base_type);
|
||||
const size_t size = InlineSize(field.value.type);
|
||||
offset_to_field += size + field.padding;
|
||||
}
|
||||
}
|
||||
@@ -2425,7 +2532,7 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += "}";
|
||||
|
||||
// Generate a constructor that takes all fields as arguments.
|
||||
code_ += "impl {{STRUCT_NAME}} {";
|
||||
code_ += "impl<'a> {{STRUCT_NAME}} {";
|
||||
code_ += " #[allow(clippy::too_many_arguments)]";
|
||||
code_ += " pub fn new(";
|
||||
ForAllStructFields(struct_def, [&](const FieldDef &unused) {
|
||||
@@ -2456,6 +2563,14 @@ class RustGenerator : public BaseGenerator {
|
||||
" unsafe {"
|
||||
" &*(self.0[{{FIELD_OFFSET}}..].as_ptr() as *const"
|
||||
" {{FIELD_TYPE}}) }";
|
||||
} else if (IsArray(field.value.type)) {
|
||||
code_.SetValue("ARRAY_SIZE",
|
||||
NumToString(field.value.type.fixed_length));
|
||||
code_.SetValue("ARRAY_ITEM", GetTypeGet(field.value.type.VectorType()));
|
||||
code_ +=
|
||||
" pub fn {{FIELD_NAME}}(&'a self) -> "
|
||||
"flatbuffers::Array<'a, {{ARRAY_ITEM}}, {{ARRAY_SIZE}}> {";
|
||||
code_ += " flatbuffers::Array::follow(&self.0, {{FIELD_OFFSET}})";
|
||||
} else {
|
||||
code_ += " pub fn {{FIELD_NAME}}(&self) -> {{FIELD_TYPE}} {";
|
||||
code_ +=
|
||||
@@ -2473,12 +2588,37 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += " }\n";
|
||||
// Setter.
|
||||
if (IsStruct(field.value.type)) {
|
||||
code_.SetValue("FIELD_SIZE",
|
||||
NumToString(field.value.type.struct_def->bytesize));
|
||||
code_.SetValue("FIELD_SIZE", NumToString(InlineSize(field.value.type)));
|
||||
code_ += " pub fn set_{{FIELD_NAME}}(&mut self, x: &{{FIELD_TYPE}}) {";
|
||||
code_ +=
|
||||
" self.0[{{FIELD_OFFSET}}..{{FIELD_OFFSET}}+{{FIELD_SIZE}}]"
|
||||
".copy_from_slice(&x.0)";
|
||||
} else if (IsArray(field.value.type)) {
|
||||
if (GetFullType(field.value.type) == ftArrayOfBuiltin) {
|
||||
code_.SetValue("ARRAY_ITEM",
|
||||
GetTypeGet(field.value.type.VectorType()));
|
||||
code_.SetValue(
|
||||
"ARRAY_ITEM_SIZE",
|
||||
NumToString(InlineSize(field.value.type.VectorType())));
|
||||
code_ +=
|
||||
" pub fn set_{{FIELD_NAME}}(&mut self, items: &{{FIELD_TYPE}}) "
|
||||
"{";
|
||||
code_ +=
|
||||
" flatbuffers::emplace_scalar_array(&mut self.0, "
|
||||
"{{FIELD_OFFSET}}, items);";
|
||||
} else {
|
||||
code_.SetValue("FIELD_SIZE",
|
||||
NumToString(InlineSize(field.value.type)));
|
||||
code_ +=
|
||||
" pub fn set_{{FIELD_NAME}}(&mut self, x: &{{FIELD_TYPE}}) {";
|
||||
code_ += " unsafe {";
|
||||
code_ += " std::ptr::copy(";
|
||||
code_ += " x.as_ptr() as *const u8,";
|
||||
code_ += " self.0.as_mut_ptr().add({{FIELD_OFFSET}}),";
|
||||
code_ += " {{FIELD_SIZE}},";
|
||||
code_ += " );";
|
||||
code_ += " }";
|
||||
}
|
||||
} else {
|
||||
code_ += " pub fn set_{{FIELD_NAME}}(&mut self, x: {{FIELD_TYPE}}) {";
|
||||
code_ += " let x_le = x.to_little_endian();";
|
||||
@@ -2502,8 +2642,19 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += " pub fn unpack(&self) -> {{NATIVE_STRUCT_NAME}} {";
|
||||
code_ += " {{NATIVE_STRUCT_NAME}} {";
|
||||
ForAllStructFields(struct_def, [&](const FieldDef &field) {
|
||||
std::string unpack = IsStruct(field.value.type) ? ".unpack()" : "";
|
||||
code_ += " {{FIELD_NAME}}: self.{{FIELD_NAME}}()" + unpack + ",";
|
||||
if (IsArray(field.value.type)) {
|
||||
if (GetFullType(field.value.type) == ftArrayOfStruct) {
|
||||
code_ +=
|
||||
" {{FIELD_NAME}}: { let {{FIELD_NAME}} = "
|
||||
"self.{{FIELD_NAME}}(); flatbuffers::array_init(|i| "
|
||||
"{{FIELD_NAME}}.get(i).unpack()) },";
|
||||
} else {
|
||||
code_ += " {{FIELD_NAME}}: self.{{FIELD_NAME}}().into(),";
|
||||
}
|
||||
} else {
|
||||
std::string unpack = IsStruct(field.value.type) ? ".unpack()" : "";
|
||||
code_ += " {{FIELD_NAME}}: self.{{FIELD_NAME}}()" + unpack + ",";
|
||||
}
|
||||
});
|
||||
code_ += " }";
|
||||
code_ += " }";
|
||||
@@ -2530,6 +2681,14 @@ class RustGenerator : public BaseGenerator {
|
||||
ForAllStructFields(struct_def, [&](const FieldDef &field) {
|
||||
if (IsStruct(field.value.type)) {
|
||||
code_ += " &self.{{FIELD_NAME}}.pack(),";
|
||||
} else if (IsArray(field.value.type)) {
|
||||
if (GetFullType(field.value.type) == ftArrayOfStruct) {
|
||||
code_ +=
|
||||
" &flatbuffers::array_init(|i| "
|
||||
"self.{{FIELD_NAME}}[i].pack()),";
|
||||
} else {
|
||||
code_ += " &self.{{FIELD_NAME}},";
|
||||
}
|
||||
} else {
|
||||
code_ += " self.{{FIELD_NAME}},";
|
||||
}
|
||||
@@ -2570,7 +2729,7 @@ class RustGenerator : public BaseGenerator {
|
||||
code_ += indent + "use std::cmp::Ordering;";
|
||||
code_ += "";
|
||||
code_ += indent + "extern crate flatbuffers;";
|
||||
code_ += indent + "use self::flatbuffers::EndianScalar;";
|
||||
code_ += indent + "use self::flatbuffers::{EndianScalar, Follow};";
|
||||
}
|
||||
|
||||
// Set up the correct namespace. This opens a namespace if the current
|
||||
|
||||
@@ -2467,7 +2467,7 @@ bool Parser::SupportsAdvancedArrayFeatures() const {
|
||||
return (opts.lang_to_generate &
|
||||
~(IDLOptions::kCpp | IDLOptions::kPython | IDLOptions::kJava |
|
||||
IDLOptions::kCSharp | IDLOptions::kJsonSchema | IDLOptions::kJson |
|
||||
IDLOptions::kBinary)) == 0;
|
||||
IDLOptions::kBinary | IDLOptions::kRust)) == 0;
|
||||
}
|
||||
|
||||
Namespace *Parser::UniqueNamespace(Namespace *ns) {
|
||||
|
||||
725
tests/arrays_test_generated.rs
Normal file
725
tests/arrays_test_generated.rs
Normal file
@@ -0,0 +1,725 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
|
||||
use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod my_game {
|
||||
|
||||
use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod example {
|
||||
|
||||
use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_TEST_ENUM: i8 = 0;
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MAX_TEST_ENUM: i8 = 2;
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub const ENUM_VALUES_TEST_ENUM: [TestEnum; 3] = [
|
||||
TestEnum::A,
|
||||
TestEnum::B,
|
||||
TestEnum::C,
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct TestEnum(pub i8);
|
||||
#[allow(non_upper_case_globals)]
|
||||
impl TestEnum {
|
||||
pub const A: Self = Self(0);
|
||||
pub const B: Self = Self(1);
|
||||
pub const C: Self = Self(2);
|
||||
|
||||
pub const ENUM_MIN: i8 = 0;
|
||||
pub const ENUM_MAX: i8 = 2;
|
||||
pub const ENUM_VALUES: &'static [Self] = &[
|
||||
Self::A,
|
||||
Self::B,
|
||||
Self::C,
|
||||
];
|
||||
/// Returns the variant's name or "" if unknown.
|
||||
pub fn variant_name(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Self::A => Some("A"),
|
||||
Self::B => Some("B"),
|
||||
Self::C => Some("C"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for TestEnum {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
if let Some(name) = self.variant_name() {
|
||||
f.write_str(name)
|
||||
} else {
|
||||
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> flatbuffers::Follow<'a> for TestEnum {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Push for TestEnum {
|
||||
type Output = TestEnum;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
flatbuffers::emplace_scalar::<i8>(dst, self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::EndianScalar for TestEnum {
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> Self {
|
||||
let b = i8::to_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
#[inline]
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn from_little_endian(self) -> Self {
|
||||
let b = i8::from_le(self.0);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for TestEnum {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for TestEnum {}
|
||||
// struct NestedStruct, aligned to 8
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct NestedStruct(pub [u8; 32]);
|
||||
impl Default for NestedStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 32])
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for NestedStruct {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_struct("NestedStruct")
|
||||
.field("a", &self.a())
|
||||
.field("b", &self.b())
|
||||
.field("c", &self.c())
|
||||
.field("d", &self.d())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for NestedStruct {}
|
||||
impl flatbuffers::SafeSliceAccess for NestedStruct {}
|
||||
impl<'a> flatbuffers::Follow<'a> for NestedStruct {
|
||||
type Inner = &'a NestedStruct;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
<&'a NestedStruct>::follow(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'a> flatbuffers::Follow<'a> for &'a NestedStruct {
|
||||
type Inner = &'a NestedStruct;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
flatbuffers::follow_cast_ref::<NestedStruct>(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for NestedStruct {
|
||||
type Output = NestedStruct;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::std::slice::from_raw_parts(self as *const NestedStruct as *const u8, Self::size())
|
||||
};
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for &'b NestedStruct {
|
||||
type Output = NestedStruct;
|
||||
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::std::slice::from_raw_parts(*self as *const NestedStruct as *const u8, Self::size())
|
||||
};
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for NestedStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl<'a> NestedStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: &[i32; 2],
|
||||
b: TestEnum,
|
||||
c: &[TestEnum; 2],
|
||||
d: &[i64; 2],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 32]);
|
||||
s.set_a(&a);
|
||||
s.set_b(b);
|
||||
s.set_c(&c);
|
||||
s.set_d(&d);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn a(&'a self) -> flatbuffers::Array<'a, i32, 2> {
|
||||
flatbuffers::Array::follow(&self.0, 0)
|
||||
}
|
||||
|
||||
pub fn set_a(&mut self, items: &[i32; 2]) {
|
||||
flatbuffers::emplace_scalar_array(&mut self.0, 0, items);
|
||||
}
|
||||
|
||||
pub fn b(&self) -> TestEnum {
|
||||
let mut mem = core::mem::MaybeUninit::<TestEnum>::uninit();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[8..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<TestEnum>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
}
|
||||
|
||||
pub fn set_b(&mut self, x: TestEnum) {
|
||||
let x_le = x.to_little_endian();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const TestEnum as *const u8,
|
||||
self.0[8..].as_mut_ptr(),
|
||||
core::mem::size_of::<TestEnum>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn c(&'a self) -> flatbuffers::Array<'a, TestEnum, 2> {
|
||||
flatbuffers::Array::follow(&self.0, 9)
|
||||
}
|
||||
|
||||
pub fn set_c(&mut self, x: &[TestEnum; 2]) {
|
||||
unsafe {
|
||||
std::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(9),
|
||||
2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> flatbuffers::Array<'a, i64, 2> {
|
||||
flatbuffers::Array::follow(&self.0, 16)
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, items: &[i64; 2]) {
|
||||
flatbuffers::emplace_scalar_array(&mut self.0, 16, items);
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> NestedStructT {
|
||||
NestedStructT {
|
||||
a: self.a().into(),
|
||||
b: self.b(),
|
||||
c: self.c().into(),
|
||||
d: self.d().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct NestedStructT {
|
||||
pub a: [i32; 2],
|
||||
pub b: TestEnum,
|
||||
pub c: [TestEnum; 2],
|
||||
pub d: [i64; 2],
|
||||
}
|
||||
impl NestedStructT {
|
||||
pub fn pack(&self) -> NestedStruct {
|
||||
NestedStruct::new(
|
||||
&self.a,
|
||||
self.b,
|
||||
&self.c,
|
||||
&self.d,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// struct ArrayStruct, aligned to 8
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct ArrayStruct(pub [u8; 160]);
|
||||
impl Default for ArrayStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 160])
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for ArrayStruct {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_struct("ArrayStruct")
|
||||
.field("a", &self.a())
|
||||
.field("b", &self.b())
|
||||
.field("c", &self.c())
|
||||
.field("d", &self.d())
|
||||
.field("e", &self.e())
|
||||
.field("f", &self.f())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::SimpleToVerifyInSlice for ArrayStruct {}
|
||||
impl flatbuffers::SafeSliceAccess for ArrayStruct {}
|
||||
impl<'a> flatbuffers::Follow<'a> for ArrayStruct {
|
||||
type Inner = &'a ArrayStruct;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
<&'a ArrayStruct>::follow(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'a> flatbuffers::Follow<'a> for &'a ArrayStruct {
|
||||
type Inner = &'a ArrayStruct;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
flatbuffers::follow_cast_ref::<ArrayStruct>(buf, loc)
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for ArrayStruct {
|
||||
type Output = ArrayStruct;
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::std::slice::from_raw_parts(self as *const ArrayStruct as *const u8, Self::size())
|
||||
};
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
impl<'b> flatbuffers::Push for &'b ArrayStruct {
|
||||
type Output = ArrayStruct;
|
||||
|
||||
#[inline]
|
||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
||||
let src = unsafe {
|
||||
::std::slice::from_raw_parts(*self as *const ArrayStruct as *const u8, Self::size())
|
||||
};
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Verifiable for ArrayStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl<'a> ArrayStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: f32,
|
||||
b: &[i32; 15],
|
||||
c: i8,
|
||||
d: &[NestedStruct; 2],
|
||||
e: i32,
|
||||
f: &[i64; 2],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 160]);
|
||||
s.set_a(a);
|
||||
s.set_b(&b);
|
||||
s.set_c(c);
|
||||
s.set_d(&d);
|
||||
s.set_e(e);
|
||||
s.set_f(&f);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn a(&self) -> f32 {
|
||||
let mut mem = core::mem::MaybeUninit::<f32>::uninit();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[0..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<f32>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
}
|
||||
|
||||
pub fn set_a(&mut self, x: f32) {
|
||||
let x_le = x.to_little_endian();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const f32 as *const u8,
|
||||
self.0[0..].as_mut_ptr(),
|
||||
core::mem::size_of::<f32>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn b(&'a self) -> flatbuffers::Array<'a, i32, 15> {
|
||||
flatbuffers::Array::follow(&self.0, 4)
|
||||
}
|
||||
|
||||
pub fn set_b(&mut self, items: &[i32; 15]) {
|
||||
flatbuffers::emplace_scalar_array(&mut self.0, 4, items);
|
||||
}
|
||||
|
||||
pub fn c(&self) -> i8 {
|
||||
let mut mem = core::mem::MaybeUninit::<i8>::uninit();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[64..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<i8>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
}
|
||||
|
||||
pub fn set_c(&mut self, x: i8) {
|
||||
let x_le = x.to_little_endian();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const i8 as *const u8,
|
||||
self.0[64..].as_mut_ptr(),
|
||||
core::mem::size_of::<i8>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> flatbuffers::Array<'a, NestedStruct, 2> {
|
||||
flatbuffers::Array::follow(&self.0, 72)
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, x: &[NestedStruct; 2]) {
|
||||
unsafe {
|
||||
std::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(72),
|
||||
64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn e(&self) -> i32 {
|
||||
let mut mem = core::mem::MaybeUninit::<i32>::uninit();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
self.0[136..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
core::mem::size_of::<i32>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
}.from_little_endian()
|
||||
}
|
||||
|
||||
pub fn set_e(&mut self, x: i32) {
|
||||
let x_le = x.to_little_endian();
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const i32 as *const u8,
|
||||
self.0[136..].as_mut_ptr(),
|
||||
core::mem::size_of::<i32>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f(&'a self) -> flatbuffers::Array<'a, i64, 2> {
|
||||
flatbuffers::Array::follow(&self.0, 144)
|
||||
}
|
||||
|
||||
pub fn set_f(&mut self, items: &[i64; 2]) {
|
||||
flatbuffers::emplace_scalar_array(&mut self.0, 144, items);
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> ArrayStructT {
|
||||
ArrayStructT {
|
||||
a: self.a(),
|
||||
b: self.b().into(),
|
||||
c: self.c(),
|
||||
d: { let d = self.d(); flatbuffers::array_init(|i| d.get(i).unpack()) },
|
||||
e: self.e(),
|
||||
f: self.f().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct ArrayStructT {
|
||||
pub a: f32,
|
||||
pub b: [i32; 15],
|
||||
pub c: i8,
|
||||
pub d: [NestedStructT; 2],
|
||||
pub e: i32,
|
||||
pub f: [i64; 2],
|
||||
}
|
||||
impl ArrayStructT {
|
||||
pub fn pack(&self) -> ArrayStruct {
|
||||
ArrayStruct::new(
|
||||
self.a,
|
||||
&self.b,
|
||||
self.c,
|
||||
&flatbuffers::array_init(|i| self.d[i].pack()),
|
||||
self.e,
|
||||
&self.f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ArrayTableOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct ArrayTable<'a> {
|
||||
pub _tab: flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Follow<'a> for ArrayTable<'a> {
|
||||
type Inner = ArrayTable<'a>;
|
||||
#[inline]
|
||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table { buf, loc } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrayTable<'a> {
|
||||
#[inline]
|
||||
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
ArrayTable { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
|
||||
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
|
||||
args: &'args ArrayTableArgs<'args>) -> flatbuffers::WIPOffset<ArrayTable<'bldr>> {
|
||||
let mut builder = ArrayTableBuilder::new(_fbb);
|
||||
if let Some(x) = args.a { builder.add_a(x); }
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> ArrayTableT {
|
||||
let a = self.a().map(|x| {
|
||||
x.unpack()
|
||||
});
|
||||
ArrayTableT {
|
||||
a,
|
||||
}
|
||||
}
|
||||
pub const VT_A: flatbuffers::VOffsetT = 4;
|
||||
|
||||
#[inline]
|
||||
pub fn a(&self) -> Option<&'a ArrayStruct> {
|
||||
self._tab.get::<ArrayStruct>(ArrayTable::VT_A, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for ArrayTable<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<ArrayStruct>(&"a", Self::VT_A, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ArrayTableArgs<'a> {
|
||||
pub a: Option<&'a ArrayStruct>,
|
||||
}
|
||||
impl<'a> Default for ArrayTableArgs<'a> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
ArrayTableArgs {
|
||||
a: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct ArrayTableBuilder<'a: 'b, 'b> {
|
||||
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b> ArrayTableBuilder<'a, 'b> {
|
||||
#[inline]
|
||||
pub fn add_a(&mut self, a: &ArrayStruct) {
|
||||
self.fbb_.push_slot_always::<&ArrayStruct>(ArrayTable::VT_A, a);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> ArrayTableBuilder<'a, 'b> {
|
||||
let start = _fbb.start_table();
|
||||
ArrayTableBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> flatbuffers::WIPOffset<ArrayTable<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ArrayTable<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut ds = f.debug_struct("ArrayTable");
|
||||
ds.field("a", &self.a());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ArrayTableT {
|
||||
pub a: Option<ArrayStructT>,
|
||||
}
|
||||
impl Default for ArrayTableT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ArrayTableT {
|
||||
pub fn pack<'b>(
|
||||
&self,
|
||||
_fbb: &mut flatbuffers::FlatBufferBuilder<'b>
|
||||
) -> flatbuffers::WIPOffset<ArrayTable<'b>> {
|
||||
let a_tmp = self.a.as_ref().map(|x| x.pack());
|
||||
let a = a_tmp.as_ref();
|
||||
ArrayTable::create(_fbb, &ArrayTableArgs{
|
||||
a,
|
||||
})
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_root_as_array_table<'a>(buf: &'a [u8]) -> ArrayTable<'a> {
|
||||
unsafe { flatbuffers::root_unchecked::<ArrayTable<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")]
|
||||
pub fn get_size_prefixed_root_as_array_table<'a>(buf: &'a [u8]) -> ArrayTable<'a> {
|
||||
unsafe { flatbuffers::size_prefixed_root_unchecked::<ArrayTable<'a>>(buf) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `ArrayTable`
|
||||
/// 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_array_table_unchecked`.
|
||||
pub fn root_as_array_table(buf: &[u8]) -> Result<ArrayTable, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root::<ArrayTable>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `ArrayTable` 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_array_table_unchecked`.
|
||||
pub fn size_prefixed_root_as_array_table(buf: &[u8]) -> Result<ArrayTable, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root::<ArrayTable>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `ArrayTable` 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_array_table_unchecked`.
|
||||
pub fn root_as_array_table_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ArrayTable<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root_with_opts::<ArrayTable<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `ArrayTable` 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_array_table_unchecked`.
|
||||
pub fn size_prefixed_root_as_array_table_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ArrayTable<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root_with_opts::<ArrayTable<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a ArrayTable and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `ArrayTable`.
|
||||
pub unsafe fn root_as_array_table_unchecked(buf: &[u8]) -> ArrayTable {
|
||||
flatbuffers::root_unchecked::<ArrayTable>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed ArrayTable and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `ArrayTable`.
|
||||
pub unsafe fn size_prefixed_root_as_array_table_unchecked(buf: &[u8]) -> ArrayTable {
|
||||
flatbuffers::size_prefixed_root_unchecked::<ArrayTable>(buf)
|
||||
}
|
||||
pub const ARRAY_TABLE_IDENTIFIER: &str = "ARRT";
|
||||
|
||||
#[inline]
|
||||
pub fn array_table_buffer_has_identifier(buf: &[u8]) -> bool {
|
||||
flatbuffers::buffer_has_identifier(buf, ARRAY_TABLE_IDENTIFIER, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn array_table_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool {
|
||||
flatbuffers::buffer_has_identifier(buf, ARRAY_TABLE_IDENTIFIER, true)
|
||||
}
|
||||
|
||||
pub const ARRAY_TABLE_EXTENSION: &str = "mon";
|
||||
|
||||
#[inline]
|
||||
pub fn finish_array_table_buffer<'a, 'b>(
|
||||
fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
root: flatbuffers::WIPOffset<ArrayTable<'a>>) {
|
||||
fbb.finish(root, Some(ARRAY_TABLE_IDENTIFIER));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn finish_size_prefixed_array_table_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<ArrayTable<'a>>) {
|
||||
fbb.finish_size_prefixed(root, Some(ARRAY_TABLE_IDENTIFIER));
|
||||
}
|
||||
} // pub mod Example
|
||||
} // pub mod MyGame
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM rust:1.40.0-slim-stretch as base
|
||||
FROM rust:1.51.0-slim as base
|
||||
WORKDIR /code
|
||||
ADD . .
|
||||
RUN cp flatc_debian_stretch flatc
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM rust:1.40.0-slim-stretch as base
|
||||
FROM rust:1.51.0-slim as base
|
||||
RUN apt -qq update -y && apt -qq install -y \
|
||||
gcc-mips-linux-gnu \
|
||||
libexpat1 \
|
||||
@@ -57,7 +57,7 @@ set TEST_NOINCL_FLAGS=%TEST_BASE_FLAGS% --no-includes
|
||||
..\%buildtype%\flatc.exe --cpp --bfbs-comments --bfbs-builtins --bfbs-gen-embed %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% -I include_test monster_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --jsonschema %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% --scoped-enums arrays_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --jsonschema --rust %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% --scoped-enums arrays_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% arrays_test.fbs || goto FAIL
|
||||
..\%buildtype%\flatc.exe --cpp %TEST_BASE_FLAGS% --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS $TEST_TS_FLAGS -o namespace_te
|
||||
../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
|
||||
../flatc --jsonschema --schema -I include_test monster_test.fbs
|
||||
../flatc --cpp --java --kotlin --csharp --python $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS monster_extra.fbs monsterdata_extra.json
|
||||
../flatc --cpp --java --csharp --jsonschema $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS --scoped-enums arrays_test.fbs
|
||||
../flatc --cpp --java --csharp --jsonschema --rust $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS --scoped-enums arrays_test.fbs
|
||||
../flatc --python $TEST_BASE_FLAGS arrays_test.fbs
|
||||
../flatc --dart monster_extra.fbs
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
pub enum TableAOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod my_game {
|
||||
@@ -17,7 +17,7 @@ pub mod my_game {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod other_name_space {
|
||||
|
||||
@@ -26,7 +26,7 @@ pub mod other_name_space {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_FROM_INCLUDE: i64 = 0;
|
||||
@@ -173,7 +173,7 @@ impl<'a> flatbuffers::Verifiable for Unused {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Unused {
|
||||
impl<'a> Unused {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: i32,
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod my_game {
|
||||
@@ -19,7 +19,7 @@ pub mod my_game {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
pub enum InParentNamespaceOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@@ -133,7 +133,7 @@ pub mod example_2 {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
pub enum MonsterOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@@ -249,7 +249,7 @@ pub mod example {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
mod bitflags_color {
|
||||
@@ -1035,7 +1035,7 @@ impl<'a> flatbuffers::Verifiable for Test {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Test {
|
||||
impl<'a> Test {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: i16,
|
||||
@@ -1188,7 +1188,7 @@ impl<'a> flatbuffers::Verifiable for Vec3 {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Vec3 {
|
||||
impl<'a> Vec3 {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
x: f32,
|
||||
@@ -1434,7 +1434,7 @@ impl<'a> flatbuffers::Verifiable for Ability {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl Ability {
|
||||
impl<'a> Ability {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
id: u32,
|
||||
@@ -1594,7 +1594,7 @@ impl<'a> flatbuffers::Verifiable for StructOfStructs {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl StructOfStructs {
|
||||
impl<'a> StructOfStructs {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: &Ability,
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_ABC: i32 = 0;
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod namespace_a {
|
||||
@@ -15,7 +15,7 @@ pub mod namespace_a {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod namespace_b {
|
||||
|
||||
@@ -23,7 +23,7 @@ pub mod namespace_b {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_UNION_IN_NESTED_NS: u8 = 0;
|
||||
@@ -312,7 +312,7 @@ impl<'a> flatbuffers::Verifiable for StructInNestedNS {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl StructInNestedNS {
|
||||
impl<'a> StructInNestedNS {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: i32,
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod namespace_a {
|
||||
@@ -15,7 +15,7 @@ pub mod namespace_a {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod namespace_b {
|
||||
|
||||
@@ -23,7 +23,7 @@ pub mod namespace_b {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_UNION_IN_NESTED_NS: u8 = 0;
|
||||
@@ -312,7 +312,7 @@ impl<'a> flatbuffers::Verifiable for StructInNestedNS {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
impl StructInNestedNS {
|
||||
impl<'a> StructInNestedNS {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: i32,
|
||||
@@ -900,7 +900,7 @@ pub mod namespace_c {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
pub enum TableInCOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::mem;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod optional_scalars {
|
||||
@@ -15,7 +15,7 @@ pub mod optional_scalars {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::EndianScalar;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_OPTIONAL_BYTE: i8 = 0;
|
||||
|
||||
@@ -43,6 +43,7 @@ bencher = "0.1.5"
|
||||
static_assertions = "1.0.0"
|
||||
rand = "*"
|
||||
quickcheck_derive = "*"
|
||||
array-init = "2.0"
|
||||
|
||||
[[bench]]
|
||||
# setup for bencher
|
||||
|
||||
330
tests/rust_usage_test/tests/arrays_test.rs
Normal file
330
tests/rust_usage_test/tests/arrays_test.rs
Normal file
@@ -0,0 +1,330 @@
|
||||
extern crate array_init;
|
||||
#[allow(dead_code, unused_imports)]
|
||||
#[path = "../../arrays_test_generated.rs"]
|
||||
mod arrays_test_generated;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::arrays_test_generated::my_game::example::*;
|
||||
extern crate quickcheck;
|
||||
use array_init::array_init;
|
||||
use std::mem::size_of;
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
|
||||
let nested_struct1 = NestedStruct::new(
|
||||
&[-1, 2],
|
||||
TestEnum::A,
|
||||
&[TestEnum::C, TestEnum::B],
|
||||
&[0x1122334455667788, -0x1122334455667788],
|
||||
);
|
||||
let nested_struct2 = NestedStruct::new(
|
||||
&[3, -4],
|
||||
TestEnum::B,
|
||||
&[TestEnum::B, TestEnum::A],
|
||||
&[-0x1122334455667788, 0x1122334455667788],
|
||||
);
|
||||
let array_struct = ArrayStruct::new(
|
||||
12.34,
|
||||
&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF],
|
||||
-127,
|
||||
&[nested_struct1, nested_struct2],
|
||||
1,
|
||||
&[-0x8000000000000000, 0x7FFFFFFFFFFFFFFF],
|
||||
);
|
||||
// Test five makes sense when specified.
|
||||
let ss = ArrayTable::create(
|
||||
builder,
|
||||
&ArrayTableArgs {
|
||||
a: Some(&array_struct),
|
||||
},
|
||||
);
|
||||
finish_array_table_buffer(builder, ss);
|
||||
}
|
||||
|
||||
fn serialized_example_is_accessible_and_correct(
|
||||
bytes: &[u8],
|
||||
identifier_required: bool,
|
||||
size_prefixed: bool,
|
||||
) {
|
||||
if identifier_required {
|
||||
let correct = if size_prefixed {
|
||||
array_table_size_prefixed_buffer_has_identifier(bytes)
|
||||
} else {
|
||||
array_table_buffer_has_identifier(bytes)
|
||||
};
|
||||
assert_eq!(correct, true);
|
||||
}
|
||||
|
||||
let array_table = if size_prefixed {
|
||||
size_prefixed_root_as_array_table(bytes).unwrap()
|
||||
} else {
|
||||
root_as_array_table(bytes).unwrap()
|
||||
};
|
||||
|
||||
let array_struct = array_table.a().unwrap();
|
||||
assert_eq!(array_struct.a(), 12.34);
|
||||
assert_eq!(array_struct.b().len(), 0xF);
|
||||
assert_eq!(array_struct.b().iter().sum::<i32>(), 120);
|
||||
assert_eq!(array_struct.c(), -127);
|
||||
|
||||
assert_eq!(array_struct.d().len(), 2);
|
||||
let nested_struct1 = array_struct.d().get(0);
|
||||
assert_eq!(nested_struct1.a().len(), 2);
|
||||
assert_eq!(nested_struct1.a().iter().sum::<i32>(), 1);
|
||||
assert_eq!(nested_struct1.b(), TestEnum::A);
|
||||
assert_eq!(nested_struct1.c().len(), 2);
|
||||
assert_eq!(nested_struct1.c().get(0), TestEnum::C);
|
||||
assert_eq!(nested_struct1.c().get(1), TestEnum::B);
|
||||
assert_eq!(nested_struct1.d().len(), 2);
|
||||
assert_eq!(
|
||||
[nested_struct1.d().get(0), nested_struct1.d().get(1)],
|
||||
[0x1122334455667788, -0x1122334455667788]
|
||||
);
|
||||
let nested_struct2 = array_struct.d().get(1);
|
||||
assert_eq!(nested_struct2.a().len(), 2);
|
||||
assert_eq!(nested_struct2.a().iter().sum::<i32>(), -1);
|
||||
assert_eq!(nested_struct2.b(), TestEnum::B);
|
||||
assert_eq!(nested_struct2.c().len(), 2);
|
||||
assert_eq!(nested_struct2.c().get(0), TestEnum::B);
|
||||
assert_eq!(nested_struct2.c().get(1), TestEnum::A);
|
||||
assert_eq!(nested_struct2.d().len(), 2);
|
||||
let arr: [i64; 2] = nested_struct2.d().into();
|
||||
assert_eq!(
|
||||
arr,
|
||||
[-0x1122334455667788, 0x1122334455667788]
|
||||
);
|
||||
|
||||
assert_eq!(array_struct.e(), 1);
|
||||
assert_eq!(array_struct.f().len(), 2);
|
||||
assert_eq!(array_struct.f().get(0), -0x8000000000000000);
|
||||
assert_eq!(array_struct.f().get(1), 0x7FFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_code_creates_correct_example() {
|
||||
let mut b = flatbuffers::FlatBufferBuilder::new();
|
||||
create_serialized_example_with_generated_code(&mut b);
|
||||
let buf = b.finished_data();
|
||||
serialized_example_is_accessible_and_correct(&buf[..], true, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_netsted_struct_is_32_bytes() {
|
||||
assert_eq!(32, ::std::mem::size_of::<NestedStruct>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_array_struct_is_160_bytes() {
|
||||
assert_eq!(160, ::std::mem::size_of::<ArrayStruct>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_object_api_reads_correctly() {
|
||||
let mut b = flatbuffers::FlatBufferBuilder::new();
|
||||
create_serialized_example_with_generated_code(&mut b);
|
||||
|
||||
let array_table = root_as_array_table(b.finished_data()).unwrap().unpack();
|
||||
|
||||
let array_struct = array_table.a.unwrap();
|
||||
assert_eq!(array_struct.a, 12.34);
|
||||
assert_eq!(array_struct.b.len(), 0xF);
|
||||
assert_eq!(array_struct.b.iter().sum::<i32>(), 120);
|
||||
assert_eq!(array_struct.c, -127);
|
||||
|
||||
assert_eq!(array_struct.d.len(), 2);
|
||||
let nested_struct1 = &array_struct.d[0];
|
||||
assert_eq!(nested_struct1.a.len(), 2);
|
||||
assert_eq!(nested_struct1.a.iter().sum::<i32>(), 1);
|
||||
assert_eq!(nested_struct1.b, TestEnum::A);
|
||||
assert_eq!(nested_struct1.c.len(), 2);
|
||||
assert_eq!(nested_struct1.c[0], TestEnum::C);
|
||||
assert_eq!(nested_struct1.c[1], TestEnum::B);
|
||||
assert_eq!(nested_struct1.d.len(), 2);
|
||||
assert_eq!(nested_struct1.d, [0x1122334455667788, -0x1122334455667788]);
|
||||
let nested_struct2 = &array_struct.d[1];
|
||||
assert_eq!(nested_struct2.a.len(), 2);
|
||||
assert_eq!(nested_struct2.a.iter().sum::<i32>(), -1);
|
||||
assert_eq!(nested_struct2.b, TestEnum::B);
|
||||
assert_eq!(nested_struct2.c.len(), 2);
|
||||
assert_eq!(nested_struct2.c[0], TestEnum::B);
|
||||
assert_eq!(nested_struct2.c[1], TestEnum::A);
|
||||
assert_eq!(nested_struct2.d.len(), 2);
|
||||
assert_eq!(nested_struct2.d, [-0x1122334455667788, 0x1122334455667788]);
|
||||
|
||||
assert_eq!(array_struct.e, 1);
|
||||
assert_eq!(array_struct.f.len(), 2);
|
||||
assert_eq!(array_struct.f[0], -0x8000000000000000);
|
||||
assert_eq!(array_struct.f[1], 0x7FFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_api_defaults() {
|
||||
use arrays_test_generated::my_game::example::*;
|
||||
|
||||
assert_eq!(
|
||||
NestedStructT::default(),
|
||||
NestedStructT {
|
||||
a: [0, 0],
|
||||
b: TestEnum::default(),
|
||||
c: [TestEnum::default(), TestEnum::default()],
|
||||
d: [0, 0]
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ArrayStructT::default(),
|
||||
ArrayStructT {
|
||||
a: 0.0,
|
||||
b: [0; 0xF],
|
||||
c: 0,
|
||||
d: [NestedStructT::default(), NestedStructT::default()],
|
||||
e: 0,
|
||||
f: [0, 0]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_code_debug_prints_correctly() {
|
||||
let b = &mut flatbuffers::FlatBufferBuilder::new();
|
||||
create_serialized_example_with_generated_code(b);
|
||||
let buf = b.finished_data();
|
||||
let array_table = root_as_array_table(buf).unwrap();
|
||||
assert_eq!(
|
||||
format!("{:.5?}", &array_table),
|
||||
"ArrayTable { a: Some(ArrayStruct { a: 12.34000, \
|
||||
b: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], \
|
||||
c: -127, d: [NestedStruct { a: [-1, 2], b: A, c: [C, B], \
|
||||
d: [1234605616436508552, -1234605616436508552] }, \
|
||||
NestedStruct { a: [3, -4], b: B, c: [B, A], d: [-1234605616436508552, 1234605616436508552] }], \
|
||||
e: 1, f: [-9223372036854775808, 9223372036854775807] }) }"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn assert_on_too_small_array_buf() {
|
||||
let a = [0u8; 19];
|
||||
flatbuffers::Array::<i32, 5>::new(&a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn assert_on_too_big_array_buf() {
|
||||
let a = [0u8; 21];
|
||||
flatbuffers::Array::<i32, 5>::new(&a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_endian = "little")]
|
||||
fn verify_struct_array_alignment() {
|
||||
let mut b = flatbuffers::FlatBufferBuilder::new();
|
||||
create_serialized_example_with_generated_code(&mut b);
|
||||
let buf = b.finished_data();
|
||||
let array_table = root_as_array_table(buf).unwrap();
|
||||
let array_struct = array_table.a().unwrap();
|
||||
let struct_start_ptr = array_struct.0.as_ptr() as usize;
|
||||
let b_start_ptr = array_struct.b().safe_slice().as_ptr() as usize;
|
||||
let d_start_ptr = array_struct.d().safe_slice().as_ptr() as usize;
|
||||
// The T type of b
|
||||
let b_aln = ::std::mem::align_of::<i32>();
|
||||
assert_eq!((b_start_ptr - struct_start_ptr) % b_aln, 0);
|
||||
assert_eq!((d_start_ptr - b_start_ptr) % b_aln, 0);
|
||||
assert_eq!((d_start_ptr - struct_start_ptr) % 8, 0);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct FakeArray<T, const N: usize>([T; N]);
|
||||
|
||||
impl<T: Arbitrary + Debug + PartialEq, const N: usize> Arbitrary for FakeArray<T, N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> FakeArray<T, N> {
|
||||
let x: [T; N] = array_init(|_| {
|
||||
loop {
|
||||
let generated_scalar = T::arbitrary(g);
|
||||
// Verify that generated scalar is not Nan, which is not equals to itself,
|
||||
// therefore we can't use it to validate input == output
|
||||
if generated_scalar == generated_scalar { return generated_scalar }
|
||||
}
|
||||
});
|
||||
FakeArray{0: x}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod array_fuzz {
|
||||
#[cfg(not(miri))] // slow.
|
||||
extern crate quickcheck;
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::{Follow, Push};
|
||||
use super::*;
|
||||
|
||||
const MAX_TESTS: u64 = 20;
|
||||
const ARRAY_SIZE: usize = 29;
|
||||
|
||||
// This uses a macro because lifetimes for the trait-bounded function get too
|
||||
// complicated.
|
||||
macro_rules! impl_prop {
|
||||
($test_name:ident, $fn_name:ident, $ty:ident) => (
|
||||
fn $fn_name(xs: FakeArray<$ty, ARRAY_SIZE>) {
|
||||
let mut test_buf = [0 as u8; 1024];
|
||||
flatbuffers::emplace_scalar_array(&mut test_buf, 0, &xs.0);
|
||||
let arr: flatbuffers::Array<$ty, ARRAY_SIZE> = flatbuffers::Array::follow(&test_buf, 0);
|
||||
let got: [$ty; ARRAY_SIZE] = arr.into();
|
||||
assert_eq!(got, xs.0);
|
||||
#[cfg(target_endian = "little")]
|
||||
assert_eq!(arr.safe_slice(), xs.0);
|
||||
}
|
||||
#[test]
|
||||
fn $test_name() {
|
||||
quickcheck::QuickCheck::new().max_tests(MAX_TESTS).quickcheck($fn_name as fn(FakeArray<$ty, ARRAY_SIZE>));
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
impl_prop!(test_bool, prop_bool, bool);
|
||||
impl_prop!(test_u8, prop_u8, u8);
|
||||
impl_prop!(test_i8, prop_i8, i8);
|
||||
impl_prop!(test_u16, prop_u16, u16);
|
||||
impl_prop!(test_u32, prop_u32, u32);
|
||||
impl_prop!(test_u64, prop_u64, u64);
|
||||
impl_prop!(test_i16, prop_i16, i16);
|
||||
impl_prop!(test_i32, prop_i32, i32);
|
||||
impl_prop!(test_i64, prop_i64, i64);
|
||||
impl_prop!(test_f32, prop_f32, f32);
|
||||
impl_prop!(test_f64, prop_f64, f64);
|
||||
|
||||
const NESTED_STRUCT_SIZE: usize = size_of::<NestedStruct>();
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct NestedStructWrapper(NestedStruct);
|
||||
|
||||
impl Arbitrary for NestedStructWrapper {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> NestedStructWrapper {
|
||||
let mut x = NestedStruct::default();
|
||||
x.0 = FakeArray::<u8, NESTED_STRUCT_SIZE>::arbitrary(g).0;
|
||||
NestedStructWrapper{0: x}
|
||||
}
|
||||
}
|
||||
|
||||
fn prop_struct(xs: FakeArray<NestedStructWrapper, ARRAY_SIZE>) {
|
||||
let mut test_buf = [0 as u8; 1024];
|
||||
let native_struct_array: [&NestedStruct; ARRAY_SIZE] = array_init::from_iter(xs.0.iter().map(|x| &x.0)).unwrap();
|
||||
for i in 0..ARRAY_SIZE {
|
||||
let offset = i * NESTED_STRUCT_SIZE;
|
||||
native_struct_array[i].push(&mut test_buf[offset..offset + NESTED_STRUCT_SIZE], &[]);
|
||||
}
|
||||
let arr: flatbuffers::Array<NestedStruct, ARRAY_SIZE> = flatbuffers::Array::follow(&test_buf, 0);
|
||||
let got: [&NestedStruct; ARRAY_SIZE] = arr.into();
|
||||
assert_eq!(got, native_struct_array);
|
||||
let arr_slice = arr.safe_slice();
|
||||
for i in 0..ARRAY_SIZE {
|
||||
assert_eq!(arr_slice[i], *native_struct_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_struct() {
|
||||
quickcheck::QuickCheck::new().max_tests(MAX_TESTS).quickcheck(prop_struct as fn(FakeArray<NestedStructWrapper, ARRAY_SIZE>));
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#[macro_use]
|
||||
#[cfg(not(miri))] // slow.
|
||||
#[cfg(not(miri))] // slow.
|
||||
extern crate quickcheck;
|
||||
extern crate flatbuffers;
|
||||
extern crate flexbuffers;
|
||||
@@ -24,13 +24,13 @@ extern crate rand;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(not(miri))] // slow.
|
||||
#[cfg(not(miri))] // slow.
|
||||
#[macro_use]
|
||||
extern crate quickcheck_derive;
|
||||
|
||||
mod flexbuffers_tests;
|
||||
mod optional_scalars_test;
|
||||
mod more_defaults_test;
|
||||
mod optional_scalars_test;
|
||||
|
||||
#[allow(dead_code, unused_imports)]
|
||||
#[path = "../../include_test/include_test1_generated.rs"]
|
||||
@@ -57,6 +57,10 @@ pub use monster_test_generated::my_game;
|
||||
#[path = "../../optional_scalars_generated.rs"]
|
||||
mod optional_scalars_generated;
|
||||
|
||||
#[allow(dead_code, unused_imports)]
|
||||
#[path = "../../arrays_test_generated.rs"]
|
||||
mod arrays_test_generated;
|
||||
|
||||
#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
|
||||
#[allow(dead_code)]
|
||||
mod flatbuffers_tests {
|
||||
@@ -1509,8 +1513,7 @@ mod roundtrip_table {
|
||||
assert!(values_generated > 0);
|
||||
assert!(min_tests_per_choice > 0);
|
||||
for i in 0..test_value_types_max as u64 {
|
||||
assert!(stats[&i] >= min_tests_per_choice,
|
||||
format!("inadequately-tested fuzz case: {}", i));
|
||||
assert!(stats[&i] >= min_tests_per_choice, "inadequately-tested fuzz case: {}", i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user