summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/flexbuffers/src/lib.rs1
-rw-r--r--src/idl_gen_rust.cpp86
-rw-r--r--src/idl_parser.cpp2
-rw-r--r--tests/generate_code.bat3
-rwxr-xr-xtests/generate_code.sh3
-rw-r--r--tests/monster_test_generated.rs2
-rw-r--r--tests/optional_scalars.fbs44
-rw-r--r--tests/optional_scalars_generated.rs481
-rw-r--r--tests/rust_usage_test/Cargo.toml4
-rw-r--r--tests/rust_usage_test/tests/integration_test.rs5
-rw-r--r--tests/rust_usage_test/tests/optional_scalars_test.rs52
-rw-r--r--tests/test.cpp2
12 files changed, 626 insertions, 59 deletions
diff --git a/rust/flexbuffers/src/lib.rs b/rust/flexbuffers/src/lib.rs
index 482e15cd..20983b79 100644
--- a/rust/flexbuffers/src/lib.rs
+++ b/rust/flexbuffers/src/lib.rs
@@ -33,7 +33,6 @@ extern crate bitflags;
extern crate byteorder;
#[macro_use]
extern crate serde_derive;
-#[macro_use]
extern crate num_enum;
extern crate serde;
diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp
index 45d5faff..8cdf647f 100644
--- a/src/idl_gen_rust.cpp
+++ b/src/idl_gen_rust.cpp
@@ -661,22 +661,15 @@ class RustGenerator : public BaseGenerator {
return "VT_" + MakeUpper(Name(field));
}
- std::string GetDefaultConstant(const FieldDef &field) {
- return field.value.type.base_type == BASE_TYPE_FLOAT
- ? field.value.constant + ""
- : field.value.constant;
- }
-
std::string GetDefaultScalarValue(const FieldDef &field) {
switch (GetFullType(field.value.type)) {
- case ftInteger: {
- return GetDefaultConstant(field);
- }
+ case ftInteger:
case ftFloat: {
- return GetDefaultConstant(field);
+ return field.nullable ? "None" : field.value.constant;
}
case ftBool: {
- return field.value.constant == "0" ? "false" : "true";
+ return field.nullable ? "None" :
+ field.value.constant == "0" ? "false" : "true";
}
case ftUnionKey:
case ftEnumKey: {
@@ -714,7 +707,7 @@ class RustGenerator : public BaseGenerator {
case ftFloat:
case ftBool: {
const auto typname = GetTypeBasic(type);
- return typname;
+ return field.nullable ? "Option<" + typname + ">" : typname;
}
case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
@@ -738,14 +731,12 @@ class RustGenerator : public BaseGenerator {
}
case ftVectorOfInteger:
+ case ftVectorOfBool:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", " + typname + ">>>";
- }
- case ftVectorOfBool: {
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
- ", bool>>>";
+ // TODO(cneo): Fix whitespace in generated code.
}
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
@@ -815,15 +806,12 @@ class RustGenerator : public BaseGenerator {
">>>>";
}
case ftVectorOfInteger:
+ case ftVectorOfBool:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
typname + ">>";
}
- case ftVectorOfBool: {
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
- ", bool>>";
- }
case ftVectorOfString: {
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>";
@@ -851,12 +839,9 @@ class RustGenerator : public BaseGenerator {
return "flatbuffers::WIPOffset<" + typname + "<" + lifetime + ">>";
}
case ftInteger:
+ case ftBool:
case ftFloat: {
- const auto typname = GetTypeBasic(type);
- return typname;
- }
- case ftBool: {
- return "bool";
+ return GetTypeBasic(type);
}
case ftString: {
return "flatbuffers::WIPOffset<&" + lifetime + " str>";
@@ -878,14 +863,13 @@ class RustGenerator : public BaseGenerator {
switch (GetFullType(field.value.type)) {
case ftInteger:
+ case ftBool:
case ftFloat: {
const auto typname = GetTypeBasic(field.value.type);
- return "self.fbb_.push_slot::<" + typname + ">";
+ return (field.nullable ?
+ "self.fbb_.push_slot_always::<" :
+ "self.fbb_.push_slot::<") + typname + ">";
}
- case ftBool: {
- return "self.fbb_.push_slot::<bool>";
- }
-
case ftEnumKey:
case ftUnionKey: {
const auto underlying_typname = GetTypeBasic(type);
@@ -924,12 +908,10 @@ class RustGenerator : public BaseGenerator {
switch (GetFullType(field.value.type)) {
case ftInteger:
- case ftFloat: {
- const auto typname = GetTypeBasic(type);
- return typname;
- }
+ case ftFloat:
case ftBool: {
- return "bool";
+ const auto typname = GetTypeBasic(type);
+ return field.nullable ? "Option<" + typname + ">" : typname;
}
case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
@@ -956,6 +938,7 @@ class RustGenerator : public BaseGenerator {
field.required);
}
case ftVectorOfInteger:
+ case ftVectorOfBool:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
if (IsOneByte(type.VectorType().base_type)) {
@@ -966,10 +949,6 @@ class RustGenerator : public BaseGenerator {
"flatbuffers::Vector<" + lifetime + ", " + typname + ">",
field.required);
}
- case ftVectorOfBool: {
- return WrapInOptionIfNotRequired("&" + lifetime + " [bool]",
- field.required);
- }
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
return WrapInOptionIfNotRequired(
@@ -1016,9 +995,13 @@ class RustGenerator : public BaseGenerator {
case ftFloat:
case ftBool: {
const auto typname = GetTypeBasic(type);
- const auto default_value = GetDefaultScalarValue(field);
- return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
- default_value + ")).unwrap()";
+ if (field.nullable) {
+ return "self._tab.get::<" + typname + ">(" + offset_name + ", None)";
+ } else {
+ const auto default_value = GetDefaultScalarValue(field);
+ return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
+ default_value + ")).unwrap()";
+ }
}
case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
@@ -1056,6 +1039,7 @@ class RustGenerator : public BaseGenerator {
}
case ftVectorOfInteger:
+ case ftVectorOfBool:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
std::string s =
@@ -1068,14 +1052,6 @@ class RustGenerator : public BaseGenerator {
}
return AddUnwrapIfRequired(s, field.required);
}
- case ftVectorOfBool: {
- return AddUnwrapIfRequired(
- "self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<" +
- lifetime + ", bool>>>(" + offset_name +
- ", None).map(|v| v.safe_slice())",
- field.required);
- }
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
return AddUnwrapIfRequired(
@@ -1116,8 +1092,9 @@ class RustGenerator : public BaseGenerator {
return "INVALID_CODE_GENERATION"; // for return analysis
}
- bool TableFieldReturnsOption(const Type &type) {
- switch (GetFullType(type)) {
+ bool TableFieldReturnsOption(const FieldDef &field) {
+ if (field.nullable) return true;
+ switch (GetFullType(field.value.type)) {
case ftInteger:
case ftFloat:
case ftBool:
@@ -1205,7 +1182,7 @@ class RustGenerator : public BaseGenerator {
if (!field.deprecated && (!struct_def.sortbysize ||
size == SizeOf(field.value.type.base_type))) {
code_.SetValue("FIELD_NAME", Name(field));
- if (TableFieldReturnsOption(field.value.type)) {
+ if (TableFieldReturnsOption(field)) {
code_ +=
" if let Some(x) = args.{{FIELD_NAME}} "
"{ builder.add_{{FIELD_NAME}}(x); }";
@@ -1421,7 +1398,6 @@ class RustGenerator : public BaseGenerator {
const auto &field = **it;
if (!field.deprecated) {
const bool is_scalar = IsScalar(field.value.type.base_type);
-
std::string offset = GetFieldOffsetName(field);
// Generate functions to add data, which take one of two forms.
@@ -1443,7 +1419,7 @@ class RustGenerator : public BaseGenerator {
code_ +=
" pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: "
"{{FIELD_TYPE}}) {";
- if (is_scalar) {
+ if (is_scalar && !field.nullable) {
code_.SetValue("FIELD_DEFAULT_VALUE",
TableBuilderAddFuncDefaultValue(field));
code_ +=
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 5ccd690d..eabf783c 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -2258,7 +2258,7 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsNullableScalars() const {
- return opts.lang_to_generate == 0; // No support yet.
+ return !(opts.lang_to_generate & ~IDLOptions::kRust);
}
bool Parser::SupportsAdvancedUnionFeatures() const {
diff --git a/tests/generate_code.bat b/tests/generate_code.bat
index 6954c6b7..05c58ba4 100644
--- a/tests/generate_code.bat
+++ b/tests/generate_code.bat
@@ -53,6 +53,9 @@ set TEST_NOINCL_FLAGS=%TEST_BASE_FLAGS% --no-includes --no-fb-import
..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% arrays_test.fbs || goto FAIL
..\%buildtype%\flatc.exe --cpp %TEST_BASE_FLAGS% --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
+@rem Generate the optional scalar code for tests.
+..\%buildtype%\flatc.exe --rust optional_scalars.fbs || goto FAIL
+
@rem Generate the schema evolution tests
..\%buildtype%\flatc.exe --cpp --scoped-enums %TEST_CPP_FLAGS% -o evolution_test ./evolution_test/evolution_v1.fbs ./evolution_test/evolution_v2.fbs || goto FAIL
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index 0b3e1343..df583c3e 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -51,6 +51,9 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o namespace_test namespace_te
../flatc --python $TEST_BASE_FLAGS arrays_test.fbs
../flatc --dart monster_extra.fbs
+# Generate optional scalar code for tests.
+../flatc --rust optional_scalars.fbs
+
# Generate the schema evolution tests
../flatc --cpp --scoped-enums $TEST_CPP_FLAGS -o evolution_test ./evolution_test/evolution_v*.fbs
diff --git a/tests/monster_test_generated.rs b/tests/monster_test_generated.rs
index 528505c3..43fe7278 100644
--- a/tests/monster_test_generated.rs
+++ b/tests/monster_test_generated.rs
@@ -1488,7 +1488,7 @@ pub struct MonsterArgs<'a> {
pub testhashu32_fnv1a: u32,
pub testhashs64_fnv1a: i64,
pub testhashu64_fnv1a: u64,
- pub testarrayofbools: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , bool>>>,
+ pub testarrayofbools: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , bool>>>,
pub testf: f32,
pub testf2: f32,
pub testf3: f32,
diff --git a/tests/optional_scalars.fbs b/tests/optional_scalars.fbs
new file mode 100644
index 00000000..051bae31
--- /dev/null
+++ b/tests/optional_scalars.fbs
@@ -0,0 +1,44 @@
+namespace optional_scalars;
+
+// 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;
+}
diff --git a/tests/optional_scalars_generated.rs b/tests/optional_scalars_generated.rs
new file mode 100644
index 00000000..78ee8560
--- /dev/null
+++ b/tests/optional_scalars_generated.rs
@@ -0,0 +1,481 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod optional_scalars {
+
+ use std::mem;
+ use std::cmp::Ordering;
+
+ extern crate flatbuffers;
+ use self::flatbuffers::EndianScalar;
+
+pub enum ScalarStuffOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct ScalarStuff<'a> {
+ pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for ScalarStuff<'a> {
+ type Inner = ScalarStuff<'a>;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ Self {
+ _tab: flatbuffers::Table { buf: buf, loc: loc },
+ }
+ }
+}
+
+impl<'a> ScalarStuff<'a> {
+ #[inline]
+ pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+ ScalarStuff {
+ _tab: table,
+ }
+ }
+ #[allow(unused_mut)]
+ pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+ _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+ args: &'args ScalarStuffArgs) -> flatbuffers::WIPOffset<ScalarStuff<'bldr>> {
+ let mut builder = ScalarStuffBuilder::new(_fbb);
+ builder.add_default_f64(args.default_f64);
+ if let Some(x) = args.maybe_f64 { builder.add_maybe_f64(x); }
+ builder.add_just_f64(args.just_f64);
+ builder.add_default_u64(args.default_u64);
+ if let Some(x) = args.maybe_u64 { builder.add_maybe_u64(x); }
+ builder.add_just_u64(args.just_u64);
+ builder.add_default_i64(args.default_i64);
+ if let Some(x) = args.maybe_i64 { builder.add_maybe_i64(x); }
+ builder.add_just_i64(args.just_i64);
+ builder.add_default_f32(args.default_f32);
+ if let Some(x) = args.maybe_f32 { builder.add_maybe_f32(x); }
+ builder.add_just_f32(args.just_f32);
+ builder.add_default_u32(args.default_u32);
+ if let Some(x) = args.maybe_u32 { builder.add_maybe_u32(x); }
+ builder.add_just_u32(args.just_u32);
+ builder.add_default_i32(args.default_i32);
+ if let Some(x) = args.maybe_i32 { builder.add_maybe_i32(x); }
+ builder.add_just_i32(args.just_i32);
+ builder.add_default_u16(args.default_u16);
+ if let Some(x) = args.maybe_u16 { builder.add_maybe_u16(x); }
+ builder.add_just_u16(args.just_u16);
+ builder.add_default_i16(args.default_i16);
+ if let Some(x) = args.maybe_i16 { builder.add_maybe_i16(x); }
+ builder.add_just_i16(args.just_i16);
+ builder.add_default_bool(args.default_bool);
+ if let Some(x) = args.maybe_bool { builder.add_maybe_bool(x); }
+ builder.add_just_bool(args.just_bool);
+ builder.add_default_u8(args.default_u8);
+ if let Some(x) = args.maybe_u8 { builder.add_maybe_u8(x); }
+ builder.add_just_u8(args.just_u8);
+ builder.add_default_i8(args.default_i8);
+ if let Some(x) = args.maybe_i8 { builder.add_maybe_i8(x); }
+ builder.add_just_i8(args.just_i8);
+ builder.finish()
+ }
+
+ pub const VT_JUST_I8: flatbuffers::VOffsetT = 4;
+ pub const VT_MAYBE_I8: flatbuffers::VOffsetT = 6;
+ pub const VT_DEFAULT_I8: flatbuffers::VOffsetT = 8;
+ pub const VT_JUST_U8: flatbuffers::VOffsetT = 10;
+ pub const VT_MAYBE_U8: flatbuffers::VOffsetT = 12;
+ pub const VT_DEFAULT_U8: flatbuffers::VOffsetT = 14;
+ pub const VT_JUST_I16: flatbuffers::VOffsetT = 16;
+ pub const VT_MAYBE_I16: flatbuffers::VOffsetT = 18;
+ pub const VT_DEFAULT_I16: flatbuffers::VOffsetT = 20;
+ pub const VT_JUST_U16: flatbuffers::VOffsetT = 22;
+ pub const VT_MAYBE_U16: flatbuffers::VOffsetT = 24;
+ pub const VT_DEFAULT_U16: flatbuffers::VOffsetT = 26;
+ pub const VT_JUST_I32: flatbuffers::VOffsetT = 28;
+ pub const VT_MAYBE_I32: flatbuffers::VOffsetT = 30;
+ pub const VT_DEFAULT_I32: flatbuffers::VOffsetT = 32;
+ pub const VT_JUST_U32: flatbuffers::VOffsetT = 34;
+ pub const VT_MAYBE_U32: flatbuffers::VOffsetT = 36;
+ pub const VT_DEFAULT_U32: flatbuffers::VOffsetT = 38;
+ pub const VT_JUST_I64: flatbuffers::VOffsetT = 40;
+ pub const VT_MAYBE_I64: flatbuffers::VOffsetT = 42;
+ pub const VT_DEFAULT_I64: flatbuffers::VOffsetT = 44;
+ pub const VT_JUST_U64: flatbuffers::VOffsetT = 46;
+ pub const VT_MAYBE_U64: flatbuffers::VOffsetT = 48;
+ pub const VT_DEFAULT_U64: flatbuffers::VOffsetT = 50;
+ pub const VT_JUST_F32: flatbuffers::VOffsetT = 52;
+ pub const VT_MAYBE_F32: flatbuffers::VOffsetT = 54;
+ pub const VT_DEFAULT_F32: flatbuffers::VOffsetT = 56;
+ pub const VT_JUST_F64: flatbuffers::VOffsetT = 58;
+ pub const VT_MAYBE_F64: flatbuffers::VOffsetT = 60;
+ pub const VT_DEFAULT_F64: flatbuffers::VOffsetT = 62;
+ pub const VT_JUST_BOOL: flatbuffers::VOffsetT = 64;
+ pub const VT_MAYBE_BOOL: flatbuffers::VOffsetT = 66;
+ pub const VT_DEFAULT_BOOL: flatbuffers::VOffsetT = 68;
+
+ #[inline]
+ pub fn just_i8(&self) -> i8 {
+ self._tab.get::<i8>(ScalarStuff::VT_JUST_I8, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_i8(&self) -> Option<i8> {
+ self._tab.get::<i8>(ScalarStuff::VT_MAYBE_I8, None)
+ }
+ #[inline]
+ pub fn default_i8(&self) -> i8 {
+ self._tab.get::<i8>(ScalarStuff::VT_DEFAULT_I8, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_u8(&self) -> u8 {
+ self._tab.get::<u8>(ScalarStuff::VT_JUST_U8, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_u8(&self) -> Option<u8> {
+ self._tab.get::<u8>(ScalarStuff::VT_MAYBE_U8, None)
+ }
+ #[inline]
+ pub fn default_u8(&self) -> u8 {
+ self._tab.get::<u8>(ScalarStuff::VT_DEFAULT_U8, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_i16(&self) -> i16 {
+ self._tab.get::<i16>(ScalarStuff::VT_JUST_I16, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_i16(&self) -> Option<i16> {
+ self._tab.get::<i16>(ScalarStuff::VT_MAYBE_I16, None)
+ }
+ #[inline]
+ pub fn default_i16(&self) -> i16 {
+ self._tab.get::<i16>(ScalarStuff::VT_DEFAULT_I16, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_u16(&self) -> u16 {
+ self._tab.get::<u16>(ScalarStuff::VT_JUST_U16, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_u16(&self) -> Option<u16> {
+ self._tab.get::<u16>(ScalarStuff::VT_MAYBE_U16, None)
+ }
+ #[inline]
+ pub fn default_u16(&self) -> u16 {
+ self._tab.get::<u16>(ScalarStuff::VT_DEFAULT_U16, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_i32(&self) -> i32 {
+ self._tab.get::<i32>(ScalarStuff::VT_JUST_I32, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_i32(&self) -> Option<i32> {
+ self._tab.get::<i32>(ScalarStuff::VT_MAYBE_I32, None)
+ }
+ #[inline]
+ pub fn default_i32(&self) -> i32 {
+ self._tab.get::<i32>(ScalarStuff::VT_DEFAULT_I32, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_u32(&self) -> u32 {
+ self._tab.get::<u32>(ScalarStuff::VT_JUST_U32, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_u32(&self) -> Option<u32> {
+ self._tab.get::<u32>(ScalarStuff::VT_MAYBE_U32, None)
+ }
+ #[inline]
+ pub fn default_u32(&self) -> u32 {
+ self._tab.get::<u32>(ScalarStuff::VT_DEFAULT_U32, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_i64(&self) -> i64 {
+ self._tab.get::<i64>(ScalarStuff::VT_JUST_I64, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_i64(&self) -> Option<i64> {
+ self._tab.get::<i64>(ScalarStuff::VT_MAYBE_I64, None)
+ }
+ #[inline]
+ pub fn default_i64(&self) -> i64 {
+ self._tab.get::<i64>(ScalarStuff::VT_DEFAULT_I64, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_u64(&self) -> u64 {
+ self._tab.get::<u64>(ScalarStuff::VT_JUST_U64, Some(0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_u64(&self) -> Option<u64> {
+ self._tab.get::<u64>(ScalarStuff::VT_MAYBE_U64, None)
+ }
+ #[inline]
+ pub fn default_u64(&self) -> u64 {
+ self._tab.get::<u64>(ScalarStuff::VT_DEFAULT_U64, Some(42)).unwrap()
+ }
+ #[inline]
+ pub fn just_f32(&self) -> f32 {
+ self._tab.get::<f32>(ScalarStuff::VT_JUST_F32, Some(0.0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_f32(&self) -> Option<f32> {
+ self._tab.get::<f32>(ScalarStuff::VT_MAYBE_F32, None)
+ }
+ #[inline]
+ pub fn default_f32(&self) -> f32 {
+ self._tab.get::<f32>(ScalarStuff::VT_DEFAULT_F32, Some(42.0)).unwrap()
+ }
+ #[inline]
+ pub fn just_f64(&self) -> f64 {
+ self._tab.get::<f64>(ScalarStuff::VT_JUST_F64, Some(0.0)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_f64(&self) -> Option<f64> {
+ self._tab.get::<f64>(ScalarStuff::VT_MAYBE_F64, None)
+ }
+ #[inline]
+ pub fn default_f64(&self) -> f64 {
+ self._tab.get::<f64>(ScalarStuff::VT_DEFAULT_F64, Some(42.0)).unwrap()
+ }
+ #[inline]
+ pub fn just_bool(&self) -> bool {
+ self._tab.get::<bool>(ScalarStuff::VT_JUST_BOOL, Some(false)).unwrap()
+ }
+ #[inline]
+ pub fn maybe_bool(&self) -> Option<bool> {
+ self._tab.get::<bool>(ScalarStuff::VT_MAYBE_BOOL, None)
+ }
+ #[inline]
+ pub fn default_bool(&self) -> bool {
+ self._tab.get::<bool>(ScalarStuff::VT_DEFAULT_BOOL, Some(true)).unwrap()
+ }
+}
+
+pub struct ScalarStuffArgs {
+ pub just_i8: i8,
+ pub maybe_i8: Option<i8>,
+ pub default_i8: i8,
+ pub just_u8: u8,
+ pub maybe_u8: Option<u8>,
+ pub default_u8: u8,
+ pub just_i16: i16,
+ pub maybe_i16: Option<i16>,
+ pub default_i16: i16,
+ pub just_u16: u16,
+ pub maybe_u16: Option<u16>,
+ pub default_u16: u16,
+ pub just_i32: i32,
+ pub maybe_i32: Option<i32>,
+ pub default_i32: i32,
+ pub just_u32: u32,
+ pub maybe_u32: Option<u32>,
+ pub default_u32: u32,
+ pub just_i64: i64,
+ pub maybe_i64: Option<i64>,
+ pub default_i64: i64,
+ pub just_u64: u64,
+ pub maybe_u64: Option<u64>,
+ pub default_u64: u64,
+ pub just_f32: f32,
+ pub maybe_f32: Option<f32>,
+ pub default_f32: f32,
+ pub just_f64: f64,
+ pub maybe_f64: Option<f64>,
+ pub default_f64: f64,
+ pub just_bool: bool,
+ pub maybe_bool: Option<bool>,
+ pub default_bool: bool,
+}
+impl<'a> Default for ScalarStuffArgs {
+ #[inline]
+ fn default() -> Self {
+ ScalarStuffArgs {
+ just_i8: 0,
+ maybe_i8: None,
+ default_i8: 42,
+ just_u8: 0,
+ maybe_u8: None,
+ default_u8: 42,
+ just_i16: 0,
+ maybe_i16: None,
+ default_i16: 42,
+ just_u16: 0,
+ maybe_u16: None,
+ default_u16: 42,
+ just_i32: 0,
+ maybe_i32: None,
+ default_i32: 42,
+ just_u32: 0,
+ maybe_u32: None,
+ default_u32: 42,
+ just_i64: 0,
+ maybe_i64: None,
+ default_i64: 42,
+ just_u64: 0,
+ maybe_u64: None,
+ default_u64: 42,
+ just_f32: 0.0,
+ maybe_f32: None,
+ default_f32: 42.0,
+ just_f64: 0.0,
+ maybe_f64: None,
+ default_f64: 42.0,
+ just_bool: false,
+ maybe_bool: None,
+ default_bool: true,
+ }
+ }
+}
+pub struct ScalarStuffBuilder<'a: 'b, 'b> {
+ fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+ start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> ScalarStuffBuilder<'a, 'b> {
+ #[inline]
+ pub fn add_just_i8(&mut self, just_i8: i8) {
+ self.fbb_.push_slot::<i8>(ScalarStuff::VT_JUST_I8, just_i8, 0);
+ }
+ #[inline]
+ pub fn add_maybe_i8(&mut self, maybe_i8: i8) {
+ self.fbb_.push_slot_always::<i8>(ScalarStuff::VT_MAYBE_I8, maybe_i8);
+ }
+ #[inline]
+ pub fn add_default_i8(&mut self, default_i8: i8) {
+ self.fbb_.push_slot::<i8>(ScalarStuff::VT_DEFAULT_I8, default_i8, 42);
+ }
+ #[inline]
+ pub fn add_just_u8(&mut self, just_u8: u8) {
+ self.fbb_.push_slot::<u8>(ScalarStuff::VT_JUST_U8, just_u8, 0);
+ }
+ #[inline]
+ pub fn add_maybe_u8(&mut self, maybe_u8: u8) {
+ self.fbb_.push_slot_always::<u8>(ScalarStuff::VT_MAYBE_U8, maybe_u8);
+ }
+ #[inline]
+ pub fn add_default_u8(&mut self, default_u8: u8) {
+ self.fbb_.push_slot::<u8>(ScalarStuff::VT_DEFAULT_U8, default_u8, 42);
+ }
+ #[inline]
+ pub fn add_just_i16(&mut self, just_i16: i16) {
+ self.fbb_.push_slot::<i16>(ScalarStuff::VT_JUST_I16, just_i16, 0);
+ }
+ #[inline]
+ pub fn add_maybe_i16(&mut self, maybe_i16: i16) {
+ self.fbb_.push_slot_always::<i16>(ScalarStuff::VT_MAYBE_I16, maybe_i16);
+ }
+ #[inline]
+ pub fn add_default_i16(&mut self, default_i16: i16) {
+ self.fbb_.push_slot::<i16>(ScalarStuff::VT_DEFAULT_I16, default_i16, 42);
+ }
+ #[inline]
+ pub fn add_just_u16(&mut self, just_u16: u16) {
+ self.fbb_.push_slot::<u16>(ScalarStuff::VT_JUST_U16, just_u16, 0);
+ }
+ #[inline]
+ pub fn add_maybe_u16(&mut self, maybe_u16: u16) {
+ self.fbb_.push_slot_always::<u16>(ScalarStuff::VT_MAYBE_U16, maybe_u16);
+ }
+ #[inline]
+ pub fn add_default_u16(&mut self, default_u16: u16) {
+ self.fbb_.push_slot::<u16>(ScalarStuff::VT_DEFAULT_U16, default_u16, 42);
+ }
+ #[inline]
+ pub fn add_just_i32(&mut self, just_i32: i32) {
+ self.fbb_.push_slot::<i32>(ScalarStuff::VT_JUST_I32, just_i32, 0);
+ }
+ #[inline]
+ pub fn add_maybe_i32(&mut self, maybe_i32: i32) {
+ self.fbb_.push_slot_always::<i32>(ScalarStuff::VT_MAYBE_I32, maybe_i32);
+ }
+ #[inline]
+ pub fn add_default_i32(&mut self, default_i32: i32) {
+ self.fbb_.push_slot::<i32>(ScalarStuff::VT_DEFAULT_I32, default_i32, 42);
+ }
+ #[inline]
+ pub fn add_just_u32(&mut self, just_u32: u32) {
+ self.fbb_.push_slot::<u32>(ScalarStuff::VT_JUST_U32, just_u32, 0);
+ }
+ #[inline]
+ pub fn add_maybe_u32(&mut self, maybe_u32: u32) {
+ self.fbb_.push_slot_always::<u32>(ScalarStuff::VT_MAYBE_U32, maybe_u32);
+ }
+ #[inline]
+ pub fn add_default_u32(&mut self, default_u32: u32) {
+ self.fbb_.push_slot::<u32>(ScalarStuff::VT_DEFAULT_U32, default_u32, 42);
+ }
+ #[inline]
+ pub fn add_just_i64(&mut self, just_i64: i64) {
+ self.fbb_.push_slot::<i64>(ScalarStuff::VT_JUST_I64, just_i64, 0);
+ }
+ #[inline]
+ pub fn add_maybe_i64(&mut self, maybe_i64: i64) {
+ self.fbb_.push_slot_always::<i64>(ScalarStuff::VT_MAYBE_I64, maybe_i64);
+ }
+ #[inline]
+ pub fn add_default_i64(&mut self, default_i64: i64) {
+ self.fbb_.push_slot::<i64>(ScalarStuff::VT_DEFAULT_I64, default_i64, 42);
+ }
+ #[inline]
+ pub fn add_just_u64(&mut self, just_u64: u64) {
+ self.fbb_.push_slot::<u64>(ScalarStuff::VT_JUST_U64, just_u64, 0);
+ }
+ #[inline]
+ pub fn add_maybe_u64(&mut self, maybe_u64: u64) {
+ self.fbb_.push_slot_always::<u64>(ScalarStuff::VT_MAYBE_U64, maybe_u64);
+ }
+ #[inline]
+ pub fn add_default_u64(&mut self, default_u64: u64) {
+ self.fbb_.push_slot::<u64>(ScalarStuff::VT_DEFAULT_U64, default_u64, 42);
+ }
+ #[inline]
+ pub fn add_just_f32(&mut self, just_f32: f32) {
+ self.fbb_.push_slot::<f32>(ScalarStuff::VT_JUST_F32, just_f32, 0.0);
+ }
+ #[inline]
+ pub fn add_maybe_f32(&mut self, maybe_f32: f32) {
+ self.fbb_.push_slot_always::<f32>(ScalarStuff::VT_MAYBE_F32, maybe_f32);
+ }
+ #[inline]
+ pub fn add_default_f32(&mut self, default_f32: f32) {
+ self.fbb_.push_slot::<f32>(ScalarStuff::VT_DEFAULT_F32, default_f32, 42.0);
+ }
+ #[inline]
+ pub fn add_just_f64(&mut self, just_f64: f64) {
+ self.fbb_.push_slot::<f64>(ScalarStuff::VT_JUST_F64, just_f64, 0.0);
+ }
+ #[inline]
+ pub fn add_maybe_f64(&mut self, maybe_f64: f64) {
+ self.fbb_.push_slot_always::<f64>(ScalarStuff::VT_MAYBE_F64, maybe_f64);
+ }
+ #[inline]
+ pub fn add_default_f64(&mut self, default_f64: f64) {
+ self.fbb_.push_slot::<f64>(ScalarStuff::VT_DEFAULT_F64, default_f64, 42.0);
+ }
+ #[inline]
+ pub fn add_just_bool(&mut self, just_bool: bool) {
+ self.fbb_.push_slot::<bool>(ScalarStuff::VT_JUST_BOOL, just_bool, false);
+ }
+ #[inline]
+ pub fn add_maybe_bool(&mut self, maybe_bool: bool) {
+ self.fbb_.push_slot_always::<bool>(ScalarStuff::VT_MAYBE_BOOL, maybe_bool);
+ }
+ #[inline]
+ pub fn add_default_bool(&mut self, default_bool: bool) {
+ self.fbb_.push_slot::<bool>(ScalarStuff::VT_DEFAULT_BOOL, default_bool, true);
+ }
+ #[inline]
+ pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> ScalarStuffBuilder<'a, 'b> {
+ let start = _fbb.start_table();
+ ScalarStuffBuilder {
+ fbb_: _fbb,
+ start_: start,
+ }
+ }
+ #[inline]
+ pub fn finish(self) -> flatbuffers::WIPOffset<ScalarStuff<'a>> {
+ let o = self.fbb_.end_table(self.start_);
+ flatbuffers::WIPOffset::new(o.value())
+ }
+}
+
+} // pub mod optional_scalars
+
diff --git a/tests/rust_usage_test/Cargo.toml b/tests/rust_usage_test/Cargo.toml
index e6a5c1df..6fa98a9a 100644
--- a/tests/rust_usage_test/Cargo.toml
+++ b/tests/rust_usage_test/Cargo.toml
@@ -1,7 +1,9 @@
[package]
name = "rust_usage_test"
version = "0.1.0"
-authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
+authors = ["Robert Winslow <hello@rwinslow.com>",
+ "Casper Neo <cneo@google.com>",
+ "FlatBuffers Maintainers"]
[dependencies]
flatbuffers = { path = "../../rust/flatbuffers" }
diff --git a/tests/rust_usage_test/tests/integration_test.rs b/tests/rust_usage_test/tests/integration_test.rs
index 1aea51c6..b861cf03 100644
--- a/tests/rust_usage_test/tests/integration_test.rs
+++ b/tests/rust_usage_test/tests/integration_test.rs
@@ -27,6 +27,7 @@ extern crate serde_derive;
extern crate quickcheck_derive;
mod flexbuffers_tests;
+mod optional_scalars_test;
#[allow(dead_code, unused_imports)]
#[path = "../../include_test/include_test1_generated.rs"]
@@ -41,6 +42,10 @@ pub mod include_test2_generated;
mod monster_test_generated;
pub use monster_test_generated::my_game;
+#[allow(dead_code, unused_imports)]
+#[path = "../../optional_scalars_generated.rs"]
+mod optional_scalars_generated;
+
#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
#[allow(dead_code)]
mod flatbuffers_tests {
diff --git a/tests/rust_usage_test/tests/optional_scalars_test.rs b/tests/rust_usage_test/tests/optional_scalars_test.rs
new file mode 100644
index 00000000..4b63de2e
--- /dev/null
+++ b/tests/rust_usage_test/tests/optional_scalars_test.rs
@@ -0,0 +1,52 @@
+#[allow(dead_code, unused_imports)]
+#[path = "../../optional_scalars_generated.rs"]
+mod optional_scalars_generated;
+use crate::optional_scalars_generated::optional_scalars::*;
+
+// There are 3 variants of scalars in tables - those specified with default=42,
+// optional scalars, and those with nothing specified (implicitly default=0).
+// This tests that you can read what you write.
+macro_rules! make_test {
+ (
+ $test_name: ident,
+ $just: ident, $default: ident, $maybe: ident,
+ $five: expr, $zero: expr, $fortytwo: expr
+ ) => {
+ #[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()
+ });
+ builder.finish(ss, None);
+
+ let s = flatbuffers::get_root::<ScalarStuff>(builder.finished_data());
+ assert_eq!(s.$just(), $five);
+ assert_eq!(s.$default(), $five);
+ assert_eq!(s.$maybe(), Some($five));
+
+ // Test defaults are used when not specified.
+ let s = flatbuffers::get_root::<ScalarStuff>(&[0; 8]);
+ assert_eq!(s.$just(), $zero);
+ assert_eq!(s.$default(), $fortytwo);
+ assert_eq!(s.$maybe(), None);
+ }
+
+ };
+}
+
+make_test!(optional_i8, just_i8, default_i8, maybe_i8, 5, 0, 42);
+make_test!(optional_u8, just_u8, default_u8, maybe_u8, 5, 0, 42);
+make_test!(optional_i16, just_i16, default_i16, maybe_i16, 5, 0, 42);
+make_test!(optional_u16, just_u16, default_u16, maybe_u16, 5, 0, 42);
+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);
diff --git a/tests/test.cpp b/tests/test.cpp
index b4a358c7..50e2902a 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -3457,9 +3457,11 @@ void NullableScalarsTest() {
// Test if nullable scalars are allowed for each language.
const int kNumLanguages = 17;
+ const auto supported = flatbuffers::IDLOptions::kRust;
for (int lang=0; lang<kNumLanguages; lang++) {
flatbuffers::IDLOptions opts;
opts.lang_to_generate |= 1 << lang;
+ if (opts.lang_to_generate & supported) continue;
for (auto schema = schemas.begin(); schema < schemas.end(); schema++) {
const bool has_null = schema->find("null") != std::string::npos;
flatbuffers::Parser parser(opts);