Rework enums in rust. (#6098)

* Rework enums in rust.

They're now a unit struct, rather than an enum. This is a
backwards incompatible change but the previous version had UB
and was also backwards incompatible so...

* Update and test sample rust flatbuffers

* Use bitflags crate to properly support rust enums.

Previously, the bitflags attribute was just ignored. This is a breaking change
as the bitflgs API is not like a normal rust enum (duh).

* variant_name() -> Option<_>

* repr transparent

* Reexport bitflags from flatbuffers

* Make bitflags constants CamelCase, matching normal enums

* Deprecate c-style associated enum constants

Co-authored-by: Casper Neo <cneo@google.com>
This commit is contained in:
Casper
2020-10-19 11:40:03 -07:00
committed by GitHub
parent a402b3abae
commit 9fa1d27059
13 changed files with 724 additions and 628 deletions

View File

@@ -12,3 +12,4 @@ categories = ["encoding", "data-structures", "memory-management"]
[dependencies] [dependencies]
smallvec = "1.0" smallvec = "1.0"
bitflags = "1.2"

View File

@@ -38,6 +38,7 @@ mod vector;
mod vtable; mod vtable;
mod vtable_writer; mod vtable_writer;
pub use bitflags;
pub use crate::builder::FlatBufferBuilder; pub use crate::builder::FlatBufferBuilder;
pub use crate::endian_scalar::{ pub use crate::endian_scalar::{
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar, byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use std::mem; use std::mem;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -25,39 +26,45 @@ pub mod sample {
extern crate flatbuffers; extern crate flatbuffers;
use self::flatbuffers::EndianScalar; use self::flatbuffers::EndianScalar;
#[allow(non_camel_case_types)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(i8)] pub struct Color(pub i8);
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[allow(non_upper_case_globals)]
pub enum Color { impl Color {
Red = 0, pub const ENUM_MIN: i8 = 0;
Green = 1, pub const ENUM_MAX: i8 = 2;
Blue = 2, pub const Red: Self = Self(0);
pub const Green: Self = Self(1);
pub const Blue: Self = Self(2);
pub const ENUM_VALUES: &'static [Self] = &[
Self::Red,
Self::Green,
Self::Blue,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> &'static str {
match self {
Self::Red => "Red",
Self::Green => "Green",
Self::Blue => "Blue",
_ => "",
}
}
}
impl std::fmt::Debug for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let name = self.variant_name();
if name.is_empty() {
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
} else {
f.write_str(name)
}
}
} }
pub const ENUM_MIN_COLOR: i8 = 0;
pub const ENUM_MAX_COLOR: i8 = 2;
impl<'a> flatbuffers::Follow<'a> for Color { impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for Color {
#[inline]
fn to_little_endian(self) -> Self {
let n = i8::to_le(self as i8);
let p = &n as *const i8 as *const Color;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = i8::from_le(self as i8);
let p = &n as *const i8 as *const Color;
unsafe { *p }
} }
} }
@@ -65,10 +72,21 @@ impl flatbuffers::Push for Color {
type Output = Color; type Output = Color;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<Color>(dst, *self); flatbuffers::emplace_scalar::<i8>(dst, self.0);
} }
} }
impl flatbuffers::EndianScalar for Color {
#[inline]
fn to_little_endian(self) -> Self {
Self(i8::to_le(self.0))
}
#[inline]
fn from_little_endian(self) -> Self {
Self(i8::from_le(self.0))
}
}
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub const ENUM_VALUES_COLOR: [Color; 3] = [ pub const ENUM_VALUES_COLOR: [Color; 3] = [
Color::Red, Color::Red,
@@ -76,50 +94,42 @@ pub const ENUM_VALUES_COLOR: [Color; 3] = [
Color::Blue Color::Blue
]; ];
#[allow(non_camel_case_types)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub const ENUM_NAMES_COLOR: [&str; 3] = [ pub struct Equipment(pub u8);
"Red", #[allow(non_upper_case_globals)]
"Green", impl Equipment {
"Blue" pub const ENUM_MIN: u8 = 0;
]; pub const ENUM_MAX: u8 = 1;
pub const NONE: Self = Self(0);
pub fn enum_name_color(e: Color) -> &'static str { pub const Weapon: Self = Self(1);
let index = e as i8; pub const ENUM_VALUES: &'static [Self] = &[
ENUM_NAMES_COLOR[index as usize] Self::NONE,
Self::Weapon,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> &'static str {
match self {
Self::NONE => "NONE",
Self::Weapon => "Weapon",
_ => "",
}
}
} }
impl std::fmt::Debug for Equipment {
#[allow(non_camel_case_types)] fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
#[repr(u8)] let name = self.variant_name();
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] if name.is_empty() {
pub enum Equipment { f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
NONE = 0, } else {
Weapon = 1, f.write_str(name)
}
}
} }
pub const ENUM_MIN_EQUIPMENT: u8 = 0;
pub const ENUM_MAX_EQUIPMENT: u8 = 1;
impl<'a> flatbuffers::Follow<'a> for Equipment { impl<'a> flatbuffers::Follow<'a> for Equipment {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for Equipment {
#[inline]
fn to_little_endian(self) -> Self {
let n = u8::to_le(self as u8);
let p = &n as *const u8 as *const Equipment;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = u8::from_le(self as u8);
let p = &n as *const u8 as *const Equipment;
unsafe { *p }
} }
} }
@@ -127,27 +137,27 @@ impl flatbuffers::Push for Equipment {
type Output = Equipment; type Output = Equipment;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<Equipment>(dst, *self); flatbuffers::emplace_scalar::<u8>(dst, self.0);
} }
} }
impl flatbuffers::EndianScalar for Equipment {
#[inline]
fn to_little_endian(self) -> Self {
Self(u8::to_le(self.0))
}
#[inline]
fn from_little_endian(self) -> Self {
Self(u8::from_le(self.0))
}
}
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub const ENUM_VALUES_EQUIPMENT: [Equipment; 2] = [ pub const ENUM_VALUES_EQUIPMENT: [Equipment; 2] = [
Equipment::NONE, Equipment::NONE,
Equipment::Weapon Equipment::Weapon
]; ];
#[allow(non_camel_case_types)]
pub const ENUM_NAMES_EQUIPMENT: [&str; 2] = [
"NONE",
"Weapon"
];
pub fn enum_name_equipment(e: Equipment) -> &'static str {
let index = e as u8;
ENUM_NAMES_EQUIPMENT[index as usize]
}
pub struct EquipmentUnionTableOffset {} pub struct EquipmentUnionTableOffset {}
// struct Vec3, aligned to 4 // struct Vec3, aligned to 4
#[repr(C, align(4))] #[repr(C, align(4))]

View File

@@ -153,3 +153,9 @@ fn main() {
println!("The FlatBuffer was successfully created and accessed!"); println!("The FlatBuffer was successfully created and accessed!");
} }
#[cfg(test)]
#[test]
fn test_main() {
main()
}

View File

@@ -175,6 +175,14 @@ std::string AddUnwrapIfRequired(std::string s, bool required) {
} }
} }
bool IsBitFlagsEnum(const EnumDef &enum_def) {
return enum_def.attributes.Lookup("bit_flags") != nullptr;
}
bool IsBitFlagsEnum(const FieldDef &field) {
EnumDef* ed = field.value.type.enum_def;
return ed && IsBitFlagsEnum(*ed);
}
namespace rust { namespace rust {
class RustGenerator : public BaseGenerator { class RustGenerator : public BaseGenerator {
@@ -215,7 +223,10 @@ class RustGenerator : public BaseGenerator {
// the future. as a result, we proactively block these out as reserved // the future. as a result, we proactively block these out as reserved
// words. // words.
"follow", "push", "size", "alignment", "to_little_endian", "follow", "push", "size", "alignment", "to_little_endian",
"from_little_endian", nullptr "from_little_endian", nullptr,
// used by Enum constants
"ENUM_MAX", "ENUM_MIN", "ENUM_VALUES",
}; };
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
} }
@@ -508,11 +519,28 @@ class RustGenerator : public BaseGenerator {
} }
} }
std::string GetEnumValUse(const EnumDef &enum_def, std::string GetEnumValue(const EnumDef &enum_def,
const EnumVal &enum_val) const { const EnumVal &enum_val) const {
return Name(enum_def) + "::" + Name(enum_val); return Name(enum_def) + "::" + Name(enum_val);
} }
// 1 suffix since old C++ can't figure out the overload.
void ForAllEnumValues1(const EnumDef &enum_def,
std::function<void(const EnumVal&)> cb) {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
code_.SetValue("VARIANT", Name(ev));
code_.SetValue("VALUE", enum_def.ToString(ev));
cb(ev);
}
}
void ForAllEnumValues(const EnumDef &enum_def, std::function<void()> cb) {
std::function<void(const EnumVal&)> wrapped = [&](const EnumVal& unused) {
(void) unused;
cb();
};
ForAllEnumValues1(enum_def, wrapped);
}
// Generate an enum declaration, // Generate an enum declaration,
// an enum string lookup table, // an enum string lookup table,
// an enum match function, // an enum match function,
@@ -520,62 +548,139 @@ class RustGenerator : public BaseGenerator {
void GenEnum(const EnumDef &enum_def) { void GenEnum(const EnumDef &enum_def) {
code_.SetValue("ENUM_NAME", Name(enum_def)); code_.SetValue("ENUM_NAME", Name(enum_def));
code_.SetValue("BASE_TYPE", GetEnumTypeForDecl(enum_def.underlying_type)); code_.SetValue("BASE_TYPE", GetEnumTypeForDecl(enum_def.underlying_type));
code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def)));
GenComment(enum_def.doc_comment); code_.SetValue("ENUM_NAME_CAPS", MakeUpper(MakeSnakeCase(Name(enum_def))));
code_ += "#[allow(non_camel_case_types)]";
code_ += "#[repr({{BASE_TYPE}})]";
code_ +=
"#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]";
code_ += "pub enum " + Name(enum_def) + " {";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
GenComment(ev.doc_comment, " ");
code_.SetValue("KEY", Name(ev));
code_.SetValue("VALUE", enum_def.ToString(ev));
code_ += " {{KEY}} = {{VALUE}},";
}
const EnumVal *minv = enum_def.MinValue(); const EnumVal *minv = enum_def.MinValue();
const EnumVal *maxv = enum_def.MaxValue(); const EnumVal *maxv = enum_def.MaxValue();
FLATBUFFERS_ASSERT(minv && maxv); FLATBUFFERS_ASSERT(minv && maxv);
code_ += "";
code_ += "}";
code_ += "";
code_.SetValue("ENUM_NAME", Name(enum_def));
code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def)));
code_.SetValue("ENUM_NAME_CAPS", MakeUpper(MakeSnakeCase(Name(enum_def))));
code_.SetValue("ENUM_MIN_BASE_VALUE", enum_def.ToString(*minv)); code_.SetValue("ENUM_MIN_BASE_VALUE", enum_def.ToString(*minv));
code_.SetValue("ENUM_MAX_BASE_VALUE", enum_def.ToString(*maxv)); code_.SetValue("ENUM_MAX_BASE_VALUE", enum_def.ToString(*maxv));
// Generate enum constants, and impls for Follow, EndianScalar, and Push. if (IsBitFlagsEnum(enum_def)) {
code_ += "pub const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\"; // Defer to the convenient and canonical bitflags crate. We declare it in a
code_ += "{{ENUM_MIN_BASE_VALUE}};"; // module to #allow camel case constants in a smaller scope. This matches
code_ += "pub const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\"; // Flatbuffers c-modeled enums where variants are associated constants but
code_ += "{{ENUM_MAX_BASE_VALUE}};"; // in camel case.
code_ += "#[allow(non_upper_case_globals)]";
code_ += "mod bitflags_{{ENUM_NAME_SNAKE}} {";
code_ += " flatbuffers::bitflags::bitflags! {";
GenComment(enum_def.doc_comment, " ");
code_ += " pub struct {{ENUM_NAME}}: {{BASE_TYPE}} {";
ForAllEnumValues1(enum_def, [&](const EnumVal &ev){
this->GenComment(ev.doc_comment, " ");
code_ += " const {{VARIANT}} = {{VALUE}};";
});
code_ += " }";
code_ += " }";
code_ += "}";
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_ += "";
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());";
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;
}
// 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_ += ""; 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_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
code_ += " type Inner = Self;"; code_ += " type Inner = Self;";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " flatbuffers::read_scalar_at::<Self>(buf, loc)"; code_ += " Self(flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc))";
code_ += " }";
code_ += "}";
code_ += "";
code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {";
code_ += " #[inline]";
code_ += " fn to_little_endian(self) -> Self {";
code_ += " let n = {{BASE_TYPE}}::to_le(self as {{BASE_TYPE}});";
code_ += " let p = &n as *const {{BASE_TYPE}} as *const {{ENUM_NAME}};";
code_ += " unsafe { *p }";
code_ += " }";
code_ += " #[inline]";
code_ += " fn from_little_endian(self) -> Self {";
code_ += " let n = {{BASE_TYPE}}::from_le(self as {{BASE_TYPE}});";
code_ += " let p = &n as *const {{BASE_TYPE}} as *const {{ENUM_NAME}};";
code_ += " unsafe { *p }";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -583,70 +688,23 @@ class RustGenerator : public BaseGenerator {
code_ += " type Output = {{ENUM_NAME}};"; code_ += " type Output = {{ENUM_NAME}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += code_ += " flatbuffers::emplace_scalar::<{{BASE_TYPE}}>"
" flatbuffers::emplace_scalar::<{{ENUM_NAME}}>" "(dst, self.0);";
"(dst, *self);";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {";
// Generate an array of all enumeration values. code_ += " #[inline]";
auto num_fields = NumToString(enum_def.size()); code_ += " fn to_little_endian(self) -> Self {";
code_ += "#[allow(non_camel_case_types)]"; code_ += " Self({{BASE_TYPE}}::to_le(self.0))";
code_ += "pub const ENUM_VALUES_{{ENUM_NAME_CAPS}}: [{{ENUM_NAME}}; " + code_ += " }";
num_fields + "] = ["; code_ += " #[inline]";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { code_ += " fn from_little_endian(self) -> Self {";
const auto &ev = **it; code_ += " Self({{BASE_TYPE}}::from_le(self.0))";
auto value = GetEnumValUse(enum_def, ev); code_ += " }";
auto suffix = *it != enum_def.Vals().back() ? "," : ""; code_ += "}";
code_ += " " + value + suffix;
}
code_ += "];";
code_ += ""; code_ += "";
// Generate a string table for enum values.
// Problem is, if values are very sparse that could generate really big
// tables. Ideally in that case we generate a map lookup instead, but for
// the moment we simply don't output a table at all.
auto range = enum_def.Distance();
// Average distance between values above which we consider a table
// "too sparse". Change at will.
static const uint64_t kMaxSparseness = 5;
if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
code_ += "#[allow(non_camel_case_types)]";
code_ += "pub const ENUM_NAMES_{{ENUM_NAME_CAPS}}: [&str; " +
NumToString(range + 1) + "] = [";
auto val = enum_def.Vals().front();
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) {
auto ev = *it;
for (auto k = enum_def.Distance(val, ev); k > 1; --k) {
code_ += " \"\",";
}
val = ev;
auto suffix = *it != enum_def.Vals().back() ? "," : "";
code_ += " \"" + Name(*ev) + "\"" + suffix;
}
code_ += "];";
code_ += "";
code_ +=
"pub fn enum_name_{{ENUM_NAME_SNAKE}}(e: {{ENUM_NAME}}) -> "
"&'static str {";
code_ += " let index = e as {{BASE_TYPE}}\\";
if (enum_def.MinValue()->IsNonZero()) {
auto vals = GetEnumValUse(enum_def, *enum_def.MinValue());
code_ += " - " + vals + " as {{BASE_TYPE}}\\";
}
code_ += ";";
code_ += " ENUM_NAMES_{{ENUM_NAME_CAPS}}[index as usize]";
code_ += "}";
code_ += "";
}
if (enum_def.is_union) { if (enum_def.is_union) {
// Generate tyoesafe offset(s) for unions // Generate tyoesafe offset(s) for unions
code_.SetValue("NAME", Name(enum_def)); code_.SetValue("NAME", Name(enum_def));
@@ -677,7 +735,7 @@ class RustGenerator : public BaseGenerator {
auto ev = field.value.type.enum_def->FindByValue(field.value.constant); auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
assert(ev); assert(ev);
return WrapInNameSpace(field.value.type.enum_def->defined_namespace, return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
GetEnumValUse(*field.value.type.enum_def, *ev)); GetEnumValue(*field.value.type.enum_def, *ev));
} }
// All pointer-ish types have a default value of None, because they are // All pointer-ish types have a default value of None, because they are
@@ -1027,9 +1085,8 @@ class RustGenerator : public BaseGenerator {
} }
case ftUnionKey: case ftUnionKey:
case ftEnumKey: { case ftEnumKey: {
const auto underlying_typname = GetTypeBasic(type); //<- never used const std::string typname = WrapInNameSpace(*type.enum_def);
const auto typname = WrapInNameSpace(*type.enum_def); const std::string default_value = GetDefaultScalarValue(field);
const auto default_value = GetDefaultScalarValue(field);
if (field.optional) { if (field.optional) {
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)"; return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
} else { } else {
@@ -1302,7 +1359,7 @@ class RustGenerator : public BaseGenerator {
code_.SetValue( code_.SetValue(
"U_ELEMENT_ENUM_TYPE", "U_ELEMENT_ENUM_TYPE",
WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev))); WrapInNameSpace(u->defined_namespace, GetEnumValue(*u, ev)));
code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type); code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type);
code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev))); code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev)));
@@ -1763,6 +1820,9 @@ class RustGenerator : public BaseGenerator {
} }
void GenNamespaceImports(const int white_spaces) { void GenNamespaceImports(const int white_spaces) {
if (white_spaces == 0) {
code_ += "#![allow(unused_imports, dead_code)]";
}
std::string indent = std::string(white_spaces, ' '); std::string indent = std::string(white_spaces, ' ');
code_ += ""; code_ += "";
if (!parser_.opts.generate_all) { if (!parser_.opts.generate_all) {

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use crate::include_test2_generated::*; use crate::include_test2_generated::*;
use std::mem; use std::mem;

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use crate::include_test1_generated::*; use crate::include_test1_generated::*;
use std::mem; use std::mem;
@@ -28,37 +29,50 @@ pub mod other_name_space {
extern crate flatbuffers; extern crate flatbuffers;
use self::flatbuffers::EndianScalar; use self::flatbuffers::EndianScalar;
#[allow(non_camel_case_types)] #[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[repr(i64)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum FromInclude {
IncludeVal = 0,
}
pub const ENUM_MIN_FROM_INCLUDE: i64 = 0; pub const ENUM_MIN_FROM_INCLUDE: i64 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MAX_FROM_INCLUDE: i64 = 0; pub const ENUM_MAX_FROM_INCLUDE: i64 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_FROM_INCLUDE: [FromInclude; 1] = [
FromInclude::IncludeVal,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct FromInclude(pub i64);
#[allow(non_upper_case_globals)]
impl FromInclude {
pub const IncludeVal: Self = Self(0);
pub const ENUM_MIN: i64 = 0;
pub const ENUM_MAX: i64 = 0;
pub const ENUM_VALUES: &'static [Self] = &[
Self::IncludeVal,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::IncludeVal => Some("IncludeVal"),
_ => None,
}
}
}
impl std::fmt::Debug for FromInclude {
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 FromInclude { impl<'a> flatbuffers::Follow<'a> for FromInclude {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<i64>(buf, loc))
}
}
impl flatbuffers::EndianScalar for FromInclude {
#[inline]
fn to_little_endian(self) -> Self {
let n = i64::to_le(self as i64);
let p = &n as *const i64 as *const FromInclude;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = i64::from_le(self as i64);
let p = &n as *const i64 as *const FromInclude;
unsafe { *p }
} }
} }
@@ -66,23 +80,19 @@ impl flatbuffers::Push for FromInclude {
type Output = FromInclude; type Output = FromInclude;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<FromInclude>(dst, *self); flatbuffers::emplace_scalar::<i64>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for FromInclude {
pub const ENUM_VALUES_FROM_INCLUDE: [FromInclude; 1] = [ #[inline]
FromInclude::IncludeVal fn to_little_endian(self) -> Self {
]; Self(i64::to_le(self.0))
}
#[allow(non_camel_case_types)] #[inline]
pub const ENUM_NAMES_FROM_INCLUDE: [&str; 1] = [ fn from_little_endian(self) -> Self {
"IncludeVal" Self(i64::from_le(self.0))
]; }
pub fn enum_name_from_include(e: FromInclude) -> &'static str {
let index = e as i64;
ENUM_NAMES_FROM_INCLUDE[index as usize]
} }
// struct Unused, aligned to 4 // struct Unused, aligned to 4

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use crate::include_test1_generated::*; use crate::include_test1_generated::*;
use crate::include_test2_generated::*; use crate::include_test2_generated::*;
@@ -175,43 +176,28 @@ pub mod example {
extern crate flatbuffers; extern crate flatbuffers;
use self::flatbuffers::EndianScalar; use self::flatbuffers::EndianScalar;
/// Composite components of Monster color. #[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)] mod bitflags_color {
#[repr(u8)] flatbuffers::bitflags::bitflags! {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] /// Composite components of Monster color.
pub enum Color { pub struct Color: u8 {
Red = 1, const Red = 1;
/// \brief color Green /// \brief color Green
/// Green is bit_flag with value (1u << 1) /// Green is bit_flag with value (1u << 1)
Green = 2, const Green = 2;
/// \brief color Blue (1u << 3) /// \brief color Blue (1u << 3)
Blue = 8, const Blue = 8;
}
}
} }
pub use self::bitflags_color::Color;
pub const ENUM_MIN_COLOR: u8 = 1;
pub const ENUM_MAX_COLOR: u8 = 8;
impl<'a> flatbuffers::Follow<'a> for Color { impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) let bits = flatbuffers::read_scalar_at::<u8>(buf, loc);
} unsafe { Self::from_bits_unchecked(bits) }
}
impl flatbuffers::EndianScalar for Color {
#[inline]
fn to_little_endian(self) -> Self {
let n = u8::to_le(self as u8);
let p = &n as *const u8 as *const Color;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = u8::from_le(self as u8);
let p = &n as *const u8 as *const Color;
unsafe { *p }
} }
} }
@@ -219,68 +205,79 @@ impl flatbuffers::Push for Color {
type Output = Color; type Output = Color;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<Color>(dst, *self); flatbuffers::emplace_scalar::<u8>(dst, self.bits());
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for Color {
pub const ENUM_VALUES_COLOR: [Color; 3] = [ #[inline]
Color::Red, fn to_little_endian(self) -> Self {
Color::Green, let bits = u8::to_le(self.bits());
Color::Blue unsafe { Self::from_bits_unchecked(bits) }
]; }
#[inline]
#[allow(non_camel_case_types)] fn from_little_endian(self) -> Self {
pub const ENUM_NAMES_COLOR: [&str; 8] = [ let bits = u8::from_le(self.bits());
"Red", unsafe { Self::from_bits_unchecked(bits) }
"Green", }
"",
"",
"",
"",
"",
"Blue"
];
pub fn enum_name_color(e: Color) -> &'static str {
let index = e as u8 - Color::Red as u8;
ENUM_NAMES_COLOR[index as usize]
}
#[allow(non_camel_case_types)]
#[repr(i8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Race {
None = -1,
Human = 0,
Dwarf = 1,
Elf = 2,
} }
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MIN_RACE: i8 = -1; pub const ENUM_MIN_RACE: i8 = -1;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MAX_RACE: i8 = 2; pub const ENUM_MAX_RACE: i8 = 2;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_RACE: [Race; 4] = [
Race::None,
Race::Human,
Race::Dwarf,
Race::Elf,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Race(pub i8);
#[allow(non_upper_case_globals)]
impl Race {
pub const None: Self = Self(-1);
pub const Human: Self = Self(0);
pub const Dwarf: Self = Self(1);
pub const Elf: Self = Self(2);
pub const ENUM_MIN: i8 = -1;
pub const ENUM_MAX: i8 = 2;
pub const ENUM_VALUES: &'static [Self] = &[
Self::None,
Self::Human,
Self::Dwarf,
Self::Elf,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::None => Some("None"),
Self::Human => Some("Human"),
Self::Dwarf => Some("Dwarf"),
Self::Elf => Some("Elf"),
_ => None,
}
}
}
impl std::fmt::Debug for Race {
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 Race { impl<'a> flatbuffers::Follow<'a> for Race {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for Race {
#[inline]
fn to_little_endian(self) -> Self {
let n = i8::to_le(self as i8);
let p = &n as *const i8 as *const Race;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = i8::from_le(self as i8);
let p = &n as *const i8 as *const Race;
unsafe { *p }
} }
} }
@@ -288,65 +285,77 @@ impl flatbuffers::Push for Race {
type Output = Race; type Output = Race;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<Race>(dst, *self); flatbuffers::emplace_scalar::<i8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for Race {
pub const ENUM_VALUES_RACE: [Race; 4] = [ #[inline]
Race::None, fn to_little_endian(self) -> Self {
Race::Human, Self(i8::to_le(self.0))
Race::Dwarf, }
Race::Elf #[inline]
]; fn from_little_endian(self) -> Self {
Self(i8::from_le(self.0))
#[allow(non_camel_case_types)] }
pub const ENUM_NAMES_RACE: [&str; 4] = [
"None",
"Human",
"Dwarf",
"Elf"
];
pub fn enum_name_race(e: Race) -> &'static str {
let index = e as i8 - Race::None as i8;
ENUM_NAMES_RACE[index as usize]
}
#[allow(non_camel_case_types)]
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Any {
NONE = 0,
Monster = 1,
TestSimpleTableWithEnum = 2,
MyGame_Example2_Monster = 3,
} }
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MIN_ANY: u8 = 0; pub const ENUM_MIN_ANY: u8 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MAX_ANY: u8 = 3; pub const ENUM_MAX_ANY: u8 = 3;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_ANY: [Any; 4] = [
Any::NONE,
Any::Monster,
Any::TestSimpleTableWithEnum,
Any::MyGame_Example2_Monster,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Any(pub u8);
#[allow(non_upper_case_globals)]
impl Any {
pub const NONE: Self = Self(0);
pub const Monster: Self = Self(1);
pub const TestSimpleTableWithEnum: Self = Self(2);
pub const MyGame_Example2_Monster: Self = Self(3);
pub const ENUM_MIN: u8 = 0;
pub const ENUM_MAX: u8 = 3;
pub const ENUM_VALUES: &'static [Self] = &[
Self::NONE,
Self::Monster,
Self::TestSimpleTableWithEnum,
Self::MyGame_Example2_Monster,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::NONE => Some("NONE"),
Self::Monster => Some("Monster"),
Self::TestSimpleTableWithEnum => Some("TestSimpleTableWithEnum"),
Self::MyGame_Example2_Monster => Some("MyGame_Example2_Monster"),
_ => None,
}
}
}
impl std::fmt::Debug for Any {
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 Any { impl<'a> flatbuffers::Follow<'a> for Any {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for Any {
#[inline]
fn to_little_endian(self) -> Self {
let n = u8::to_le(self as u8);
let p = &n as *const u8 as *const Any;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = u8::from_le(self as u8);
let p = &n as *const u8 as *const Any;
unsafe { *p }
} }
} }
@@ -354,66 +363,78 @@ impl flatbuffers::Push for Any {
type Output = Any; type Output = Any;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<Any>(dst, *self); flatbuffers::emplace_scalar::<u8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for Any {
pub const ENUM_VALUES_ANY: [Any; 4] = [ #[inline]
Any::NONE, fn to_little_endian(self) -> Self {
Any::Monster, Self(u8::to_le(self.0))
Any::TestSimpleTableWithEnum, }
Any::MyGame_Example2_Monster #[inline]
]; fn from_little_endian(self) -> Self {
Self(u8::from_le(self.0))
#[allow(non_camel_case_types)] }
pub const ENUM_NAMES_ANY: [&str; 4] = [
"NONE",
"Monster",
"TestSimpleTableWithEnum",
"MyGame_Example2_Monster"
];
pub fn enum_name_any(e: Any) -> &'static str {
let index = e as u8;
ENUM_NAMES_ANY[index as usize]
} }
pub struct AnyUnionTableOffset {} pub struct AnyUnionTableOffset {}
#[allow(non_camel_case_types)] #[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum AnyUniqueAliases {
NONE = 0,
M = 1,
TS = 2,
M2 = 3,
}
pub const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0; 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.")]
pub const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3; pub const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_ANY_UNIQUE_ALIASES: [AnyUniqueAliases; 4] = [
AnyUniqueAliases::NONE,
AnyUniqueAliases::M,
AnyUniqueAliases::TS,
AnyUniqueAliases::M2,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct AnyUniqueAliases(pub u8);
#[allow(non_upper_case_globals)]
impl AnyUniqueAliases {
pub const NONE: Self = Self(0);
pub const M: Self = Self(1);
pub const TS: Self = Self(2);
pub const M2: Self = Self(3);
pub const ENUM_MIN: u8 = 0;
pub const ENUM_MAX: u8 = 3;
pub const ENUM_VALUES: &'static [Self] = &[
Self::NONE,
Self::M,
Self::TS,
Self::M2,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::NONE => Some("NONE"),
Self::M => Some("M"),
Self::TS => Some("TS"),
Self::M2 => Some("M2"),
_ => None,
}
}
}
impl std::fmt::Debug for AnyUniqueAliases {
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 AnyUniqueAliases { impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for AnyUniqueAliases {
#[inline]
fn to_little_endian(self) -> Self {
let n = u8::to_le(self as u8);
let p = &n as *const u8 as *const AnyUniqueAliases;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = u8::from_le(self as u8);
let p = &n as *const u8 as *const AnyUniqueAliases;
unsafe { *p }
} }
} }
@@ -421,66 +442,78 @@ impl flatbuffers::Push for AnyUniqueAliases {
type Output = AnyUniqueAliases; type Output = AnyUniqueAliases;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<AnyUniqueAliases>(dst, *self); flatbuffers::emplace_scalar::<u8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for AnyUniqueAliases {
pub const ENUM_VALUES_ANY_UNIQUE_ALIASES: [AnyUniqueAliases; 4] = [ #[inline]
AnyUniqueAliases::NONE, fn to_little_endian(self) -> Self {
AnyUniqueAliases::M, Self(u8::to_le(self.0))
AnyUniqueAliases::TS, }
AnyUniqueAliases::M2 #[inline]
]; fn from_little_endian(self) -> Self {
Self(u8::from_le(self.0))
#[allow(non_camel_case_types)] }
pub const ENUM_NAMES_ANY_UNIQUE_ALIASES: [&str; 4] = [
"NONE",
"M",
"TS",
"M2"
];
pub fn enum_name_any_unique_aliases(e: AnyUniqueAliases) -> &'static str {
let index = e as u8;
ENUM_NAMES_ANY_UNIQUE_ALIASES[index as usize]
} }
pub struct AnyUniqueAliasesUnionTableOffset {} pub struct AnyUniqueAliasesUnionTableOffset {}
#[allow(non_camel_case_types)] #[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum AnyAmbiguousAliases {
NONE = 0,
M1 = 1,
M2 = 2,
M3 = 3,
}
pub const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0; 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.")]
pub const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3; pub const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES: [AnyAmbiguousAliases; 4] = [
AnyAmbiguousAliases::NONE,
AnyAmbiguousAliases::M1,
AnyAmbiguousAliases::M2,
AnyAmbiguousAliases::M3,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct AnyAmbiguousAliases(pub u8);
#[allow(non_upper_case_globals)]
impl AnyAmbiguousAliases {
pub const NONE: Self = Self(0);
pub const M1: Self = Self(1);
pub const M2: Self = Self(2);
pub const M3: Self = Self(3);
pub const ENUM_MIN: u8 = 0;
pub const ENUM_MAX: u8 = 3;
pub const ENUM_VALUES: &'static [Self] = &[
Self::NONE,
Self::M1,
Self::M2,
Self::M3,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::NONE => Some("NONE"),
Self::M1 => Some("M1"),
Self::M2 => Some("M2"),
Self::M3 => Some("M3"),
_ => None,
}
}
}
impl std::fmt::Debug for AnyAmbiguousAliases {
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 AnyAmbiguousAliases { impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<u8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for AnyAmbiguousAliases {
#[inline]
fn to_little_endian(self) -> Self {
let n = u8::to_le(self as u8);
let p = &n as *const u8 as *const AnyAmbiguousAliases;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = u8::from_le(self as u8);
let p = &n as *const u8 as *const AnyAmbiguousAliases;
unsafe { *p }
} }
} }
@@ -488,29 +521,19 @@ impl flatbuffers::Push for AnyAmbiguousAliases {
type Output = AnyAmbiguousAliases; type Output = AnyAmbiguousAliases;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<AnyAmbiguousAliases>(dst, *self); flatbuffers::emplace_scalar::<u8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for AnyAmbiguousAliases {
pub const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES: [AnyAmbiguousAliases; 4] = [ #[inline]
AnyAmbiguousAliases::NONE, fn to_little_endian(self) -> Self {
AnyAmbiguousAliases::M1, Self(u8::to_le(self.0))
AnyAmbiguousAliases::M2, }
AnyAmbiguousAliases::M3 #[inline]
]; fn from_little_endian(self) -> Self {
Self(u8::from_le(self.0))
#[allow(non_camel_case_types)] }
pub const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES: [&str; 4] = [
"NONE",
"M1",
"M2",
"M3"
];
pub fn enum_name_any_ambiguous_aliases(e: AnyAmbiguousAliases) -> &'static str {
let index = e as u8;
ENUM_NAMES_ANY_AMBIGUOUS_ALIASES[index as usize]
} }
pub struct AnyAmbiguousAliasesUnionTableOffset {} pub struct AnyAmbiguousAliasesUnionTableOffset {}

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use std::mem; use std::mem;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -25,39 +26,58 @@ pub mod namespace_b {
extern crate flatbuffers; extern crate flatbuffers;
use self::flatbuffers::EndianScalar; use self::flatbuffers::EndianScalar;
#[allow(non_camel_case_types)] #[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[repr(i8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum EnumInNestedNS {
A = 0,
B = 1,
C = 2,
}
pub const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0; pub const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2; pub const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_ENUM_IN_NESTED_NS: [EnumInNestedNS; 3] = [
EnumInNestedNS::A,
EnumInNestedNS::B,
EnumInNestedNS::C,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct EnumInNestedNS(pub i8);
#[allow(non_upper_case_globals)]
impl EnumInNestedNS {
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 EnumInNestedNS {
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 EnumInNestedNS { impl<'a> flatbuffers::Follow<'a> for EnumInNestedNS {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for EnumInNestedNS {
#[inline]
fn to_little_endian(self) -> Self {
let n = i8::to_le(self as i8);
let p = &n as *const i8 as *const EnumInNestedNS;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = i8::from_le(self as i8);
let p = &n as *const i8 as *const EnumInNestedNS;
unsafe { *p }
} }
} }
@@ -65,27 +85,19 @@ impl flatbuffers::Push for EnumInNestedNS {
type Output = EnumInNestedNS; type Output = EnumInNestedNS;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<EnumInNestedNS>(dst, *self); flatbuffers::emplace_scalar::<i8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for EnumInNestedNS {
pub const ENUM_VALUES_ENUM_IN_NESTED_NS: [EnumInNestedNS; 3] = [ #[inline]
EnumInNestedNS::A, fn to_little_endian(self) -> Self {
EnumInNestedNS::B, Self(i8::to_le(self.0))
EnumInNestedNS::C }
]; #[inline]
fn from_little_endian(self) -> Self {
#[allow(non_camel_case_types)] Self(i8::from_le(self.0))
pub const ENUM_NAMES_ENUM_IN_NESTED_NS: [&str; 3] = [ }
"A",
"B",
"C"
];
pub fn enum_name_enum_in_nested_ns(e: EnumInNestedNS) -> &'static str {
let index = e as i8;
ENUM_NAMES_ENUM_IN_NESTED_NS[index as usize]
} }
// struct StructInNestedNS, aligned to 4 // struct StructInNestedNS, aligned to 4

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use crate::namespace_test1_generated::*; use crate::namespace_test1_generated::*;
use std::mem; use std::mem;

View File

@@ -1,6 +1,7 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#![allow(unused_imports, dead_code)]
use std::mem; use std::mem;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -17,39 +18,58 @@ pub mod optional_scalars {
extern crate flatbuffers; extern crate flatbuffers;
use self::flatbuffers::EndianScalar; use self::flatbuffers::EndianScalar;
#[allow(non_camel_case_types)] #[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[repr(i8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum OptionalByte {
None = 0,
One = 1,
Two = 2,
}
pub const ENUM_MIN_OPTIONAL_BYTE: i8 = 0; pub const ENUM_MIN_OPTIONAL_BYTE: i8 = 0;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
pub const ENUM_MAX_OPTIONAL_BYTE: i8 = 2; pub const ENUM_MAX_OPTIONAL_BYTE: i8 = 2;
#[deprecated(since = "1.13", note = "Use associated constants instead. This will no longer be generated in 2021.")]
#[allow(non_camel_case_types)]
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 3] = [
OptionalByte::None,
OptionalByte::One,
OptionalByte::Two,
];
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct OptionalByte(pub i8);
#[allow(non_upper_case_globals)]
impl OptionalByte {
pub const None: Self = Self(0);
pub const One: Self = Self(1);
pub const Two: Self = Self(2);
pub const ENUM_MIN: i8 = 0;
pub const ENUM_MAX: i8 = 2;
pub const ENUM_VALUES: &'static [Self] = &[
Self::None,
Self::One,
Self::Two,
];
/// Returns the variant's name or "" if unknown.
pub fn variant_name(self) -> Option<&'static str> {
match self {
Self::None => Some("None"),
Self::One => Some("One"),
Self::Two => Some("Two"),
_ => None,
}
}
}
impl std::fmt::Debug for OptionalByte {
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 OptionalByte { impl<'a> flatbuffers::Follow<'a> for OptionalByte {
type Inner = Self; type Inner = Self;
#[inline] #[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::read_scalar_at::<Self>(buf, loc) Self(flatbuffers::read_scalar_at::<i8>(buf, loc))
}
}
impl flatbuffers::EndianScalar for OptionalByte {
#[inline]
fn to_little_endian(self) -> Self {
let n = i8::to_le(self as i8);
let p = &n as *const i8 as *const OptionalByte;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
let n = i8::from_le(self as i8);
let p = &n as *const i8 as *const OptionalByte;
unsafe { *p }
} }
} }
@@ -57,27 +77,19 @@ impl flatbuffers::Push for OptionalByte {
type Output = OptionalByte; type Output = OptionalByte;
#[inline] #[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) { fn push(&self, dst: &mut [u8], _rest: &[u8]) {
flatbuffers::emplace_scalar::<OptionalByte>(dst, *self); flatbuffers::emplace_scalar::<i8>(dst, self.0);
} }
} }
#[allow(non_camel_case_types)] impl flatbuffers::EndianScalar for OptionalByte {
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 3] = [ #[inline]
OptionalByte::None, fn to_little_endian(self) -> Self {
OptionalByte::One, Self(i8::to_le(self.0))
OptionalByte::Two }
]; #[inline]
fn from_little_endian(self) -> Self {
#[allow(non_camel_case_types)] Self(i8::from_le(self.0))
pub const ENUM_NAMES_OPTIONAL_BYTE: [&str; 3] = [ }
"None",
"One",
"Two"
];
pub fn enum_name_optional_byte(e: OptionalByte) -> &'static str {
let index = e as i8;
ENUM_NAMES_OPTIONAL_BYTE[index as usize]
} }
pub enum ScalarStuffOffset {} pub enum ScalarStuffOffset {}

View File

@@ -32,6 +32,11 @@ path = "../../samples/sample_flexbuffers.rs"
name = "sample_flexbuffers_serde" name = "sample_flexbuffers_serde"
path = "../../samples/sample_flexbuffers_serde.rs" path = "../../samples/sample_flexbuffers_serde.rs"
[[bin]]
name = "sample_flatbuffers"
path = "../../samples/sample_binary.rs"
[dev-dependencies] [dev-dependencies]
quickcheck = "0.6" quickcheck = "0.6"
# TODO(rw): look into moving to criterion.rs # TODO(rw): look into moving to criterion.rs

View File

@@ -29,15 +29,12 @@ extern crate quickcheck_derive;
mod flexbuffers_tests; mod flexbuffers_tests;
mod optional_scalars_test; mod optional_scalars_test;
#[allow(dead_code, unused_imports)]
#[path = "../../include_test/include_test1_generated.rs"] #[path = "../../include_test/include_test1_generated.rs"]
pub mod include_test1_generated; pub mod include_test1_generated;
#[allow(dead_code, unused_imports)]
#[path = "../../include_test/sub/include_test2_generated.rs"] #[path = "../../include_test/sub/include_test2_generated.rs"]
pub mod include_test2_generated; pub mod include_test2_generated;
#[allow(dead_code, unused_imports)]
#[path = "../../monster_test_generated.rs"] #[path = "../../monster_test_generated.rs"]
mod monster_test_generated; mod monster_test_generated;
pub use monster_test_generated::my_game; pub use monster_test_generated::my_game;
@@ -265,83 +262,41 @@ mod generated_constants {
#[test] #[test]
fn enum_constants_are_public() { fn enum_constants_are_public() {
assert_eq!(1, my_game::example::ENUM_MIN_COLOR); assert_eq!(-1, my_game::example::Race::ENUM_MIN);
assert_eq!(8, my_game::example::ENUM_MAX_COLOR); assert_eq!(2, my_game::example::Race::ENUM_MAX);
assert_eq!(my_game::example::ENUM_VALUES_COLOR, [ assert_eq!(my_game::example::Race::ENUM_VALUES, [
my_game::example::Color::Red,
my_game::example::Color::Green,
my_game::example::Color::Blue,
]);
assert_eq!(my_game::example::ENUM_NAMES_COLOR, [
"Red",
"Green",
"",
"",
"",
"",
"",
"Blue"
]);
assert_eq!(-1, my_game::example::ENUM_MIN_RACE);
assert_eq!(2, my_game::example::ENUM_MAX_RACE);
assert_eq!(my_game::example::ENUM_VALUES_RACE, [
my_game::example::Race::None, my_game::example::Race::None,
my_game::example::Race::Human, my_game::example::Race::Human,
my_game::example::Race::Dwarf, my_game::example::Race::Dwarf,
my_game::example::Race::Elf, my_game::example::Race::Elf,
]); ]);
assert_eq!(my_game::example::ENUM_NAMES_RACE, [
"None",
"Human",
"Dwarf",
"Elf"
]);
assert_eq!(0, my_game::example::ENUM_MIN_ANY); assert_eq!(0, my_game::example::Any::ENUM_MIN);
assert_eq!(3, my_game::example::ENUM_MAX_ANY); assert_eq!(3, my_game::example::Any::ENUM_MAX);
assert_eq!(my_game::example::ENUM_VALUES_ANY, [ assert_eq!(my_game::example::Any::ENUM_VALUES, [
my_game::example::Any::NONE, my_game::example::Any::NONE,
my_game::example::Any::Monster, my_game::example::Any::Monster,
my_game::example::Any::TestSimpleTableWithEnum, my_game::example::Any::TestSimpleTableWithEnum,
my_game::example::Any::MyGame_Example2_Monster, my_game::example::Any::MyGame_Example2_Monster,
]); ]);
assert_eq!(my_game::example::ENUM_NAMES_ANY, [
"NONE",
"Monster",
"TestSimpleTableWithEnum",
"MyGame_Example2_Monster"
]);
assert_eq!(0, my_game::example::ENUM_MIN_ANY_UNIQUE_ALIASES); assert_eq!(0, my_game::example::AnyUniqueAliases::ENUM_MIN);
assert_eq!(3, my_game::example::ENUM_MAX_ANY_UNIQUE_ALIASES); assert_eq!(3, my_game::example::AnyUniqueAliases::ENUM_MAX);
assert_eq!(my_game::example::ENUM_VALUES_ANY_UNIQUE_ALIASES, [ assert_eq!(my_game::example::AnyUniqueAliases::ENUM_VALUES, [
my_game::example::AnyUniqueAliases::NONE, my_game::example::AnyUniqueAliases::NONE,
my_game::example::AnyUniqueAliases::M, my_game::example::AnyUniqueAliases::M,
my_game::example::AnyUniqueAliases::TS, my_game::example::AnyUniqueAliases::TS,
my_game::example::AnyUniqueAliases::M2, my_game::example::AnyUniqueAliases::M2,
]); ]);
assert_eq!(my_game::example::ENUM_NAMES_ANY_UNIQUE_ALIASES, [
"NONE",
"M",
"TS",
"M2"
]);
assert_eq!(0, my_game::example::ENUM_MIN_ANY_AMBIGUOUS_ALIASES); assert_eq!(0, my_game::example::AnyAmbiguousAliases::ENUM_MIN);
assert_eq!(3, my_game::example::ENUM_MAX_ANY_AMBIGUOUS_ALIASES); assert_eq!(3, my_game::example::AnyAmbiguousAliases::ENUM_MAX);
assert_eq!(my_game::example::ENUM_VALUES_ANY_AMBIGUOUS_ALIASES, [ assert_eq!(my_game::example::AnyAmbiguousAliases::ENUM_VALUES, [
my_game::example::AnyAmbiguousAliases::NONE, my_game::example::AnyAmbiguousAliases::NONE,
my_game::example::AnyAmbiguousAliases::M1, my_game::example::AnyAmbiguousAliases::M1,
my_game::example::AnyAmbiguousAliases::M2, my_game::example::AnyAmbiguousAliases::M2,
my_game::example::AnyAmbiguousAliases::M3, my_game::example::AnyAmbiguousAliases::M3,
]); ]);
assert_eq!(my_game::example::ENUM_NAMES_ANY_AMBIGUOUS_ALIASES, [
"NONE",
"M1",
"M2",
"M3"
]);
} }
} }
@@ -732,19 +687,18 @@ mod roundtrip_generated_code {
test4: Some(v), ..Default::default()}); test4: Some(v), ..Default::default()});
assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123), my_game::example::Test::new(100, 101)][..]); assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123), my_game::example::Test::new(100, 101)][..]);
} }
// TODO(rw) this passes, but I don't want to change the monster test schema right now #[test]
// #[test] fn vector_of_enums_store() {
// fn vector_of_enum_store() { let mut b = flatbuffers::FlatBufferBuilder::new();
// let mut b = flatbuffers::FlatBufferBuilder::new(); let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
// let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]); let name = b.create_string("foo");
// let name = b.create_string("foo"); let m = build_mon(&mut b, &my_game::example::MonsterArgs{
// let m = build_mon(&mut b, &my_game::example::MonsterArgs{ name: Some(name),
// name: Some(name), vector_of_enums: Some(v), ..Default::default()});
// vector_of_enum: Some(v), ..Default::default()}); assert_eq!(m.vector_of_enums().unwrap().len(), 2);
// assert_eq!(m.vector_of_enum().unwrap().len(), 2); assert_eq!(m.vector_of_enums().unwrap().get(0), my_game::example::Color::Red);
// assert_eq!(m.vector_of_enum().unwrap().get(0), my_game::example::Color::Red); assert_eq!(m.vector_of_enums().unwrap().get(1), my_game::example::Color::Green);
// assert_eq!(m.vector_of_enum().unwrap().get(1), my_game::example::Color::Green); }
// }
#[test] #[test]
fn vector_of_table_store() { fn vector_of_table_store() {
let b = &mut flatbuffers::FlatBufferBuilder::new(); let b = &mut flatbuffers::FlatBufferBuilder::new();