mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-08 22:20:56 +00:00
Optional Scalars support for Rust (#6034)
* First draft of rust optionals * Code cleanup around ftBool and ftVectorOfBool * Tests for Rust optional scalars * test bools too Co-authored-by: Casper Neo <cneo@google.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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_ +=
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
44
tests/optional_scalars.fbs
Normal file
44
tests/optional_scalars.fbs
Normal file
@@ -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;
|
||||
}
|
||||
481
tests/optional_scalars_generated.rs
Normal file
481
tests/optional_scalars_generated.rs
Normal file
@@ -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
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
52
tests/rust_usage_test/tests/optional_scalars_test.rs
Normal file
52
tests/rust_usage_test/tests/optional_scalars_test.rs
Normal file
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user