mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 20:20:03 +00:00
Ruopt enum (#6156)
* Rust support for optional enums * make optional_scalars2 for languages that support optional enums Co-authored-by: Casper Neo <cneo@google.com>
This commit is contained in:
@@ -673,6 +673,9 @@ class RustGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
case ftUnionKey:
|
case ftUnionKey:
|
||||||
case ftEnumKey: {
|
case ftEnumKey: {
|
||||||
|
if (field.optional) {
|
||||||
|
return "None";
|
||||||
|
}
|
||||||
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,
|
||||||
@@ -724,7 +727,7 @@ class RustGenerator : public BaseGenerator {
|
|||||||
case ftEnumKey:
|
case ftEnumKey:
|
||||||
case ftUnionKey: {
|
case ftUnionKey: {
|
||||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||||
return typname;
|
return field.optional ? "Option<" + typname + ">" : typname;
|
||||||
}
|
}
|
||||||
case ftUnionValue: {
|
case ftUnionValue: {
|
||||||
return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>";
|
return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>";
|
||||||
@@ -872,7 +875,9 @@ class RustGenerator : public BaseGenerator {
|
|||||||
case ftEnumKey:
|
case ftEnumKey:
|
||||||
case ftUnionKey: {
|
case ftUnionKey: {
|
||||||
const auto underlying_typname = GetTypeBasic(type);
|
const auto underlying_typname = GetTypeBasic(type);
|
||||||
return "self.fbb_.push_slot::<" + underlying_typname + ">";
|
return (field.optional ?
|
||||||
|
"self.fbb_.push_slot_always::<" :
|
||||||
|
"self.fbb_.push_slot::<") + underlying_typname + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
case ftStruct: {
|
case ftStruct: {
|
||||||
@@ -925,7 +930,7 @@ class RustGenerator : public BaseGenerator {
|
|||||||
case ftEnumKey:
|
case ftEnumKey:
|
||||||
case ftUnionKey: {
|
case ftUnionKey: {
|
||||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||||
return typname;
|
return field.optional ? "Option<" + typname + ">" : typname;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ftUnionValue: {
|
case ftUnionValue: {
|
||||||
@@ -1027,8 +1032,12 @@ class RustGenerator : public BaseGenerator {
|
|||||||
const auto underlying_typname = GetTypeBasic(type); //<- never used
|
const auto underlying_typname = GetTypeBasic(type); //<- never used
|
||||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||||
const auto default_value = GetDefaultScalarValue(field);
|
const auto default_value = GetDefaultScalarValue(field);
|
||||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
if (field.optional) {
|
||||||
default_value + ")).unwrap()";
|
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
|
||||||
|
} else {
|
||||||
|
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||||
|
default_value + ")).unwrap()";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case ftString: {
|
case ftString: {
|
||||||
return AddUnwrapIfRequired(
|
return AddUnwrapIfRequired(
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS $TEST_JS_TS_FLAGS -o namespace
|
|||||||
../flatc --dart monster_extra.fbs
|
../flatc --dart monster_extra.fbs
|
||||||
|
|
||||||
# Generate optional scalar code for tests.
|
# Generate optional scalar code for tests.
|
||||||
../flatc --kotlin --rust --lobster optional_scalars.fbs
|
../flatc --kotlin --lobster optional_scalars.fbs # These ones have not added optional enum support.
|
||||||
|
../flatc --rust optional_scalars2.fbs
|
||||||
../flatc $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS --cpp optional_scalars.fbs
|
../flatc $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS --cpp optional_scalars.fbs
|
||||||
|
|
||||||
# Generate the schema evolution tests
|
# Generate the schema evolution tests
|
||||||
|
|||||||
59
tests/optional_scalars2.fbs
Normal file
59
tests/optional_scalars2.fbs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
namespace optional_scalars;
|
||||||
|
|
||||||
|
enum OptionalByte: byte {
|
||||||
|
None = 0,
|
||||||
|
One = 1,
|
||||||
|
Two = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// This table tests optional scalars in tables. It should be integrated with
|
||||||
|
// the main monster test once most languages support optional scalars.
|
||||||
|
table ScalarStuff {
|
||||||
|
just_i8: int8;
|
||||||
|
maybe_i8: int8 = null;
|
||||||
|
default_i8: int8 = 42;
|
||||||
|
just_u8: uint8;
|
||||||
|
maybe_u8: uint8 = null;
|
||||||
|
default_u8: uint8 = 42;
|
||||||
|
|
||||||
|
just_i16: int16;
|
||||||
|
maybe_i16: int16 = null;
|
||||||
|
default_i16: int16 = 42;
|
||||||
|
just_u16: uint16;
|
||||||
|
maybe_u16: uint16 = null;
|
||||||
|
default_u16: uint16 = 42;
|
||||||
|
|
||||||
|
just_i32: int32;
|
||||||
|
maybe_i32: int32 = null;
|
||||||
|
default_i32: int32 = 42;
|
||||||
|
just_u32: uint32;
|
||||||
|
maybe_u32: uint32 = null;
|
||||||
|
default_u32: uint32 = 42;
|
||||||
|
|
||||||
|
just_i64: int64;
|
||||||
|
maybe_i64: int64 = null;
|
||||||
|
default_i64: int64 = 42;
|
||||||
|
just_u64: uint64;
|
||||||
|
maybe_u64: uint64 = null;
|
||||||
|
default_u64: uint64 = 42;
|
||||||
|
|
||||||
|
just_f32: float32;
|
||||||
|
maybe_f32: float32 = null;
|
||||||
|
default_f32: float32 = 42;
|
||||||
|
just_f64: float64;
|
||||||
|
maybe_f64: float64 = null;
|
||||||
|
default_f64: float64 = 42;
|
||||||
|
|
||||||
|
just_bool: bool;
|
||||||
|
maybe_bool: bool = null;
|
||||||
|
default_bool: bool = true;
|
||||||
|
|
||||||
|
just_enum: OptionalByte;
|
||||||
|
maybe_enum: OptionalByte = null;
|
||||||
|
default_enum: OptionalByte = One;
|
||||||
|
}
|
||||||
|
|
||||||
|
root_type ScalarStuff;
|
||||||
|
|
||||||
|
file_identifier "NULL";
|
||||||
|
file_extension "mon";
|
||||||
@@ -23,11 +23,12 @@ pub mod optional_scalars {
|
|||||||
pub enum OptionalByte {
|
pub enum OptionalByte {
|
||||||
None = 0,
|
None = 0,
|
||||||
One = 1,
|
One = 1,
|
||||||
|
Two = 2,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ENUM_MIN_OPTIONAL_BYTE: i8 = 0;
|
pub const ENUM_MIN_OPTIONAL_BYTE: i8 = 0;
|
||||||
pub const ENUM_MAX_OPTIONAL_BYTE: i8 = 1;
|
pub const ENUM_MAX_OPTIONAL_BYTE: i8 = 2;
|
||||||
|
|
||||||
impl<'a> flatbuffers::Follow<'a> for OptionalByte {
|
impl<'a> flatbuffers::Follow<'a> for OptionalByte {
|
||||||
type Inner = Self;
|
type Inner = Self;
|
||||||
@@ -61,15 +62,17 @@ impl flatbuffers::Push for OptionalByte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 2] = [
|
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 3] = [
|
||||||
OptionalByte::None,
|
OptionalByte::None,
|
||||||
OptionalByte::One
|
OptionalByte::One,
|
||||||
|
OptionalByte::Two
|
||||||
];
|
];
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub const ENUM_NAMES_OPTIONAL_BYTE: [&str; 2] = [
|
pub const ENUM_NAMES_OPTIONAL_BYTE: [&str; 3] = [
|
||||||
"None",
|
"None",
|
||||||
"One"
|
"One",
|
||||||
|
"Two"
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn enum_name_optional_byte(e: OptionalByte) -> &'static str {
|
pub fn enum_name_optional_byte(e: OptionalByte) -> &'static str {
|
||||||
@@ -129,6 +132,7 @@ impl<'a> ScalarStuff<'a> {
|
|||||||
if let Some(x) = args.maybe_i16 { builder.add_maybe_i16(x); }
|
if let Some(x) = args.maybe_i16 { builder.add_maybe_i16(x); }
|
||||||
builder.add_just_i16(args.just_i16);
|
builder.add_just_i16(args.just_i16);
|
||||||
builder.add_default_enum(args.default_enum);
|
builder.add_default_enum(args.default_enum);
|
||||||
|
if let Some(x) = args.maybe_enum { builder.add_maybe_enum(x); }
|
||||||
builder.add_just_enum(args.just_enum);
|
builder.add_just_enum(args.just_enum);
|
||||||
builder.add_default_bool(args.default_bool);
|
builder.add_default_bool(args.default_bool);
|
||||||
if let Some(x) = args.maybe_bool { builder.add_maybe_bool(x); }
|
if let Some(x) = args.maybe_bool { builder.add_maybe_bool(x); }
|
||||||
@@ -176,7 +180,8 @@ impl<'a> ScalarStuff<'a> {
|
|||||||
pub const VT_MAYBE_BOOL: flatbuffers::VOffsetT = 66;
|
pub const VT_MAYBE_BOOL: flatbuffers::VOffsetT = 66;
|
||||||
pub const VT_DEFAULT_BOOL: flatbuffers::VOffsetT = 68;
|
pub const VT_DEFAULT_BOOL: flatbuffers::VOffsetT = 68;
|
||||||
pub const VT_JUST_ENUM: flatbuffers::VOffsetT = 70;
|
pub const VT_JUST_ENUM: flatbuffers::VOffsetT = 70;
|
||||||
pub const VT_DEFAULT_ENUM: flatbuffers::VOffsetT = 72;
|
pub const VT_MAYBE_ENUM: flatbuffers::VOffsetT = 72;
|
||||||
|
pub const VT_DEFAULT_ENUM: flatbuffers::VOffsetT = 74;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn just_i8(&self) -> i8 {
|
pub fn just_i8(&self) -> i8 {
|
||||||
@@ -315,6 +320,10 @@ impl<'a> ScalarStuff<'a> {
|
|||||||
self._tab.get::<OptionalByte>(ScalarStuff::VT_JUST_ENUM, Some(OptionalByte::None)).unwrap()
|
self._tab.get::<OptionalByte>(ScalarStuff::VT_JUST_ENUM, Some(OptionalByte::None)).unwrap()
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn maybe_enum(&self) -> Option<OptionalByte> {
|
||||||
|
self._tab.get::<OptionalByte>(ScalarStuff::VT_MAYBE_ENUM, None)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
pub fn default_enum(&self) -> OptionalByte {
|
pub fn default_enum(&self) -> OptionalByte {
|
||||||
self._tab.get::<OptionalByte>(ScalarStuff::VT_DEFAULT_ENUM, Some(OptionalByte::One)).unwrap()
|
self._tab.get::<OptionalByte>(ScalarStuff::VT_DEFAULT_ENUM, Some(OptionalByte::One)).unwrap()
|
||||||
}
|
}
|
||||||
@@ -355,6 +364,7 @@ pub struct ScalarStuffArgs {
|
|||||||
pub maybe_bool: Option<bool>,
|
pub maybe_bool: Option<bool>,
|
||||||
pub default_bool: bool,
|
pub default_bool: bool,
|
||||||
pub just_enum: OptionalByte,
|
pub just_enum: OptionalByte,
|
||||||
|
pub maybe_enum: Option<OptionalByte>,
|
||||||
pub default_enum: OptionalByte,
|
pub default_enum: OptionalByte,
|
||||||
}
|
}
|
||||||
impl<'a> Default for ScalarStuffArgs {
|
impl<'a> Default for ScalarStuffArgs {
|
||||||
@@ -395,6 +405,7 @@ impl<'a> Default for ScalarStuffArgs {
|
|||||||
maybe_bool: None,
|
maybe_bool: None,
|
||||||
default_bool: true,
|
default_bool: true,
|
||||||
just_enum: OptionalByte::None,
|
just_enum: OptionalByte::None,
|
||||||
|
maybe_enum: None,
|
||||||
default_enum: OptionalByte::One,
|
default_enum: OptionalByte::One,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,6 +552,10 @@ impl<'a: 'b, 'b> ScalarStuffBuilder<'a, 'b> {
|
|||||||
self.fbb_.push_slot::<OptionalByte>(ScalarStuff::VT_JUST_ENUM, just_enum, OptionalByte::None);
|
self.fbb_.push_slot::<OptionalByte>(ScalarStuff::VT_JUST_ENUM, just_enum, OptionalByte::None);
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn add_maybe_enum(&mut self, maybe_enum: OptionalByte) {
|
||||||
|
self.fbb_.push_slot_always::<OptionalByte>(ScalarStuff::VT_MAYBE_ENUM, maybe_enum);
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
pub fn add_default_enum(&mut self, default_enum: OptionalByte) {
|
pub fn add_default_enum(&mut self, default_enum: OptionalByte) {
|
||||||
self.fbb_.push_slot::<OptionalByte>(ScalarStuff::VT_DEFAULT_ENUM, default_enum, OptionalByte::One);
|
self.fbb_.push_slot::<OptionalByte>(ScalarStuff::VT_DEFAULT_ENUM, default_enum, OptionalByte::One);
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ mod monster_test_generated;
|
|||||||
pub use monster_test_generated::my_game;
|
pub use monster_test_generated::my_game;
|
||||||
|
|
||||||
#[allow(dead_code, unused_imports)]
|
#[allow(dead_code, unused_imports)]
|
||||||
#[path = "../../optional_scalars_generated.rs"]
|
#[path = "../../optional_scalars2_generated.rs"]
|
||||||
mod optional_scalars_generated;
|
mod optional_scalars_generated;
|
||||||
|
|
||||||
#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
|
#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#[allow(dead_code, unused_imports)]
|
#[allow(dead_code, unused_imports)]
|
||||||
#[path = "../../optional_scalars_generated.rs"]
|
#[path = "../../optional_scalars2_generated.rs"]
|
||||||
mod optional_scalars_generated;
|
mod optional_scalars_generated;
|
||||||
use crate::optional_scalars_generated::optional_scalars::*;
|
use crate::optional_scalars_generated::optional_scalars::*;
|
||||||
|
|
||||||
@@ -16,12 +16,15 @@ macro_rules! make_test {
|
|||||||
fn $test_name() {
|
fn $test_name() {
|
||||||
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
// Test five makes sense when specified.
|
// Test five makes sense when specified.
|
||||||
let ss = ScalarStuff::create(&mut builder, &ScalarStuffArgs {
|
let ss = ScalarStuff::create(
|
||||||
$just: $five,
|
&mut builder,
|
||||||
$default: $five,
|
&ScalarStuffArgs {
|
||||||
$maybe: Some($five),
|
$just: $five,
|
||||||
..Default::default()
|
$default: $five,
|
||||||
});
|
$maybe: Some($five),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
builder.finish(ss, None);
|
builder.finish(ss, None);
|
||||||
|
|
||||||
let s = flatbuffers::get_root::<ScalarStuff>(builder.finished_data());
|
let s = flatbuffers::get_root::<ScalarStuff>(builder.finished_data());
|
||||||
@@ -35,7 +38,6 @@ macro_rules! make_test {
|
|||||||
assert_eq!(s.$default(), $fortytwo);
|
assert_eq!(s.$default(), $fortytwo);
|
||||||
assert_eq!(s.$maybe(), None);
|
assert_eq!(s.$maybe(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +49,39 @@ make_test!(optional_i32, just_i32, default_i32, maybe_i32, 5, 0, 42);
|
|||||||
make_test!(optional_u32, just_u32, default_u32, maybe_u32, 5, 0, 42);
|
make_test!(optional_u32, just_u32, default_u32, maybe_u32, 5, 0, 42);
|
||||||
make_test!(optional_i64, just_i64, default_i64, maybe_i64, 5, 0, 42);
|
make_test!(optional_i64, just_i64, default_i64, maybe_i64, 5, 0, 42);
|
||||||
make_test!(optional_u64, just_u64, default_u64, maybe_u64, 5, 0, 42);
|
make_test!(optional_u64, just_u64, default_u64, maybe_u64, 5, 0, 42);
|
||||||
make_test!(optional_f32, just_f32, default_f32, maybe_f32, 5.0, 0.0, 42.0);
|
make_test!(
|
||||||
make_test!(optional_f64, just_f64, default_f64, maybe_f64, 5.0, 0.0, 42.0);
|
optional_f32,
|
||||||
make_test!(optional_bool, just_bool, default_bool, maybe_bool, true, false, true);
|
just_f32,
|
||||||
|
default_f32,
|
||||||
|
maybe_f32,
|
||||||
|
5.0,
|
||||||
|
0.0,
|
||||||
|
42.0
|
||||||
|
);
|
||||||
|
make_test!(
|
||||||
|
optional_f64,
|
||||||
|
just_f64,
|
||||||
|
default_f64,
|
||||||
|
maybe_f64,
|
||||||
|
5.0,
|
||||||
|
0.0,
|
||||||
|
42.0
|
||||||
|
);
|
||||||
|
make_test!(
|
||||||
|
optional_bool,
|
||||||
|
just_bool,
|
||||||
|
default_bool,
|
||||||
|
maybe_bool,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
make_test!(
|
||||||
|
optional_enum,
|
||||||
|
just_enum,
|
||||||
|
default_enum,
|
||||||
|
maybe_enum,
|
||||||
|
OptionalByte::Two,
|
||||||
|
OptionalByte::None,
|
||||||
|
OptionalByte::One
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user