mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-06 13:37:25 +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 ftEnumKey: {
|
||||
if (field.optional) {
|
||||
return "None";
|
||||
}
|
||||
auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
|
||||
assert(ev);
|
||||
return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
|
||||
@@ -724,7 +727,7 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftEnumKey:
|
||||
case ftUnionKey: {
|
||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||
return typname;
|
||||
return field.optional ? "Option<" + typname + ">" : typname;
|
||||
}
|
||||
case ftUnionValue: {
|
||||
return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>";
|
||||
@@ -872,7 +875,9 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftEnumKey:
|
||||
case ftUnionKey: {
|
||||
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: {
|
||||
@@ -925,7 +930,7 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftEnumKey:
|
||||
case ftUnionKey: {
|
||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||
return typname;
|
||||
return field.optional ? "Option<" + typname + ">" : typname;
|
||||
}
|
||||
|
||||
case ftUnionValue: {
|
||||
@@ -1027,8 +1032,12 @@ class RustGenerator : public BaseGenerator {
|
||||
const auto underlying_typname = GetTypeBasic(type); //<- never used
|
||||
const auto typname = WrapInNameSpace(*type.enum_def);
|
||||
const auto default_value = GetDefaultScalarValue(field);
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||
default_value + ")).unwrap()";
|
||||
if (field.optional) {
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
|
||||
} else {
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||
default_value + ")).unwrap()";
|
||||
}
|
||||
}
|
||||
case ftString: {
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# 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 {
|
||||
None = 0,
|
||||
One = 1,
|
||||
Two = 2,
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
type Inner = Self;
|
||||
@@ -61,15 +62,17 @@ impl flatbuffers::Push for OptionalByte {
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 2] = [
|
||||
pub const ENUM_VALUES_OPTIONAL_BYTE: [OptionalByte; 3] = [
|
||||
OptionalByte::None,
|
||||
OptionalByte::One
|
||||
OptionalByte::One,
|
||||
OptionalByte::Two
|
||||
];
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub const ENUM_NAMES_OPTIONAL_BYTE: [&str; 2] = [
|
||||
pub const ENUM_NAMES_OPTIONAL_BYTE: [&str; 3] = [
|
||||
"None",
|
||||
"One"
|
||||
"One",
|
||||
"Two"
|
||||
];
|
||||
|
||||
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); }
|
||||
builder.add_just_i16(args.just_i16);
|
||||
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_default_bool(args.default_bool);
|
||||
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_DEFAULT_BOOL: flatbuffers::VOffsetT = 68;
|
||||
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]
|
||||
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()
|
||||
}
|
||||
#[inline]
|
||||
pub fn maybe_enum(&self) -> Option<OptionalByte> {
|
||||
self._tab.get::<OptionalByte>(ScalarStuff::VT_MAYBE_ENUM, None)
|
||||
}
|
||||
#[inline]
|
||||
pub fn default_enum(&self) -> OptionalByte {
|
||||
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 default_bool: bool,
|
||||
pub just_enum: OptionalByte,
|
||||
pub maybe_enum: Option<OptionalByte>,
|
||||
pub default_enum: OptionalByte,
|
||||
}
|
||||
impl<'a> Default for ScalarStuffArgs {
|
||||
@@ -395,6 +405,7 @@ impl<'a> Default for ScalarStuffArgs {
|
||||
maybe_bool: None,
|
||||
default_bool: true,
|
||||
just_enum: OptionalByte::None,
|
||||
maybe_enum: None,
|
||||
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);
|
||||
}
|
||||
#[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) {
|
||||
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;
|
||||
|
||||
#[allow(dead_code, unused_imports)]
|
||||
#[path = "../../optional_scalars_generated.rs"]
|
||||
#[path = "../../optional_scalars2_generated.rs"]
|
||||
mod optional_scalars_generated;
|
||||
|
||||
#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#[allow(dead_code, unused_imports)]
|
||||
#[path = "../../optional_scalars_generated.rs"]
|
||||
#[path = "../../optional_scalars2_generated.rs"]
|
||||
mod optional_scalars_generated;
|
||||
use crate::optional_scalars_generated::optional_scalars::*;
|
||||
|
||||
@@ -16,12 +16,15 @@ macro_rules! make_test {
|
||||
fn $test_name() {
|
||||
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||
// Test five makes sense when specified.
|
||||
let ss = ScalarStuff::create(&mut builder, &ScalarStuffArgs {
|
||||
$just: $five,
|
||||
$default: $five,
|
||||
$maybe: Some($five),
|
||||
..Default::default()
|
||||
});
|
||||
let ss = ScalarStuff::create(
|
||||
&mut builder,
|
||||
&ScalarStuffArgs {
|
||||
$just: $five,
|
||||
$default: $five,
|
||||
$maybe: Some($five),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
builder.finish(ss, None);
|
||||
|
||||
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.$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_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_f32, 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_f32,
|
||||
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