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

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