Commit 43132560 authored by kzvi's avatar kzvi Committed by Robert

don't return Option from required table field accessors (#4926)

parent c56fff88
...@@ -165,6 +165,24 @@ FullType GetFullType(const Type &type) { ...@@ -165,6 +165,24 @@ FullType GetFullType(const Type &type) {
return ftBool; return ftBool;
} }
// If the second parameter is false then wrap the first with Option<...>
std::string WrapInOptionIfNotRequired(std::string s, bool required) {
if (required) {
return s;
} else {
return "Option<" + s + ">";
}
}
// If the second parameter is false then add .unwrap()
std::string AddUnwrapIfRequired(std::string s, bool required) {
if (required) {
return s + ".unwrap()";
} else {
return s;
}
}
namespace rust { namespace rust {
class RustGenerator : public BaseGenerator { class RustGenerator : public BaseGenerator {
...@@ -967,11 +985,11 @@ class RustGenerator : public BaseGenerator { ...@@ -967,11 +985,11 @@ class RustGenerator : public BaseGenerator {
} }
case ftStruct: { case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<&" + lifetime + " " + typname + ">"; return WrapInOptionIfNotRequired("&" + lifetime + " " + typname, field.required);
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<" + typname + "<" + lifetime + ">>"; return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">", field.required);
} }
case ftEnumKey: case ftEnumKey:
case ftUnionKey: { case ftUnionKey: {
...@@ -980,38 +998,38 @@ class RustGenerator : public BaseGenerator { ...@@ -980,38 +998,38 @@ class RustGenerator : public BaseGenerator {
} }
case ftUnionValue: { case ftUnionValue: {
return "Option<flatbuffers::Table<" + lifetime + ">>"; return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">", field.required);
} }
case ftString: { case ftString: {
return "Option<&" + lifetime + " str>"; return WrapInOptionIfNotRequired("&" + lifetime + " str", field.required);
} }
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
if (IsOneByte(type.VectorType().base_type)) { if (IsOneByte(type.VectorType().base_type)) {
return "Option<&" + lifetime + " [" + typname + "]>"; return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
} }
return "Option<flatbuffers::Vector<" + lifetime + ", " + typname + ">>"; return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return "Option<&" + lifetime + " [bool]>"; return WrapInOptionIfNotRequired("&" + lifetime + " [bool]", field.required);
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return "Option<flatbuffers::Vector<" + lifetime + ", " + typname + ">>"; return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<&" + lifetime + " [" + typname + "]>"; return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + \ return WrapInOptionIfNotRequired("flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + \
typname + "<" + lifetime + ">>>>"; typname + "<" + lifetime + ">>>", field.required);
} }
case ftVectorOfString: { case ftVectorOfString: {
return "Option<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \ return WrapInOptionIfNotRequired("flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \
lifetime + " str>>>"; lifetime + " str>>", field.required);
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
...@@ -1041,17 +1059,17 @@ class RustGenerator : public BaseGenerator { ...@@ -1041,17 +1059,17 @@ class RustGenerator : public BaseGenerator {
} }
case ftStruct: { case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "self._tab.get::<" + typname + ">(" + offset_name + ", None)"; return AddUnwrapIfRequired("self._tab.get::<" + typname + ">(" + offset_name + ", None)", field.required);
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "self._tab.get::<flatbuffers::ForwardsUOffset<" + typname + \ return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" + \
"<" + lifetime + ">>>(" + offset_name + ", None)"; typname + "<" + lifetime + ">>>(" + offset_name + ", None)", field.required);
} }
case ftUnionValue: { case ftUnionValue: {
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Table<" + lifetime + ">>>(" + offset_name + \ "flatbuffers::Table<" + lifetime + ">>>(" + offset_name + \
", None)"; ", None)", field.required);
} }
case ftUnionKey: case ftUnionKey:
case ftEnumKey: { case ftEnumKey: {
...@@ -1062,8 +1080,8 @@ class RustGenerator : public BaseGenerator { ...@@ -1062,8 +1080,8 @@ class RustGenerator : public BaseGenerator {
", Some(" + default_value + ")).unwrap()"; ", Some(" + default_value + ")).unwrap()";
} }
case ftString: { case ftString: {
return "self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" + \ return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" + \
offset_name + ", None)"; offset_name + ", None)", field.required);
} }
case ftVectorOfInteger: case ftVectorOfInteger:
...@@ -1076,35 +1094,35 @@ class RustGenerator : public BaseGenerator { ...@@ -1076,35 +1094,35 @@ class RustGenerator : public BaseGenerator {
if (IsOneByte(type.VectorType().base_type)) { if (IsOneByte(type.VectorType().base_type)) {
s += ".map(|v| v.safe_slice())"; s += ".map(|v| v.safe_slice())";
} }
return s; return AddUnwrapIfRequired(s, field.required);
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Vector<" + lifetime + ", bool>>>(" + \ "flatbuffers::Vector<" + lifetime + ", bool>>>(" + \
offset_name + ", None).map(|v| v.safe_slice())"; offset_name + ", None).map(|v| v.safe_slice())", field.required);
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Vector<" + lifetime + ", " + typname + ">>>(" + \ "flatbuffers::Vector<" + lifetime + ", " + typname + ">>>(" + \
offset_name + ", None)"; offset_name + ", None)", field.required);
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Vector<" + typname + ">>>(" + \ "flatbuffers::Vector<" + typname + ">>>(" + \
offset_name + ", None).map(|v| v.safe_slice() )"; offset_name + ", None).map(|v| v.safe_slice() )", field.required);
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + typname + \ "flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + typname + \
"<" + lifetime + ">>>>>(" + offset_name + ", None)"; "<" + lifetime + ">>>>>(" + offset_name + ", None)", field.required);
} }
case ftVectorOfString: { case ftVectorOfString: {
return "self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \ "flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \
lifetime + " str>>>>(" + offset_name + ", None)"; lifetime + " str>>>>(" + offset_name + ", None)", field.required);
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
...@@ -1449,19 +1467,8 @@ class RustGenerator : public BaseGenerator { ...@@ -1449,19 +1467,8 @@ class RustGenerator : public BaseGenerator {
// must only be called if the field key is defined. // must only be called if the field key is defined.
void GenKeyFieldMethods(const FieldDef &field) { void GenKeyFieldMethods(const FieldDef &field) {
FLATBUFFERS_ASSERT(field.key); FLATBUFFERS_ASSERT(field.key);
const bool is_string = (field.value.type.base_type == BASE_TYPE_STRING);
if (is_string) { code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, ""));
code_.SetValue("KEY_TYPE", "Option<&str>");
} else {
FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type));
auto type = GetTypeBasic(field.value.type);
if (parser_.opts.scoped_enums && field.value.type.enum_def &&
IsScalar(field.value.type.base_type)) {
type = GetTypeGet(field.value.type);
}
code_.SetValue("KEY_TYPE", type);
}
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> " code_ += " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> "
......
...@@ -912,8 +912,8 @@ impl<'a> Monster<'a> { ...@@ -912,8 +912,8 @@ impl<'a> Monster<'a> {
self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap() self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()
} }
#[inline] #[inline]
pub fn name(&'a self) -> Option<&'a str> { pub fn name(&'a self) -> &'a str {
self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None) self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None).unwrap()
} }
#[inline] #[inline]
pub fn key_compare_less_than(&self, o: &Monster) -> bool { pub fn key_compare_less_than(&self, o: &Monster) -> bool {
...@@ -921,7 +921,7 @@ impl<'a> Monster<'a> { ...@@ -921,7 +921,7 @@ impl<'a> Monster<'a> {
} }
#[inline] #[inline]
pub fn key_compare_with_value(&self, val: Option<&str>) -> ::std::cmp::Ordering { pub fn key_compare_with_value(&self, val: & str) -> ::std::cmp::Ordering {
let key = self.name(); let key = self.name();
key.cmp(&val) key.cmp(&val)
} }
......
...@@ -159,8 +159,7 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require ...@@ -159,8 +159,7 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require
check_eq!(m.hp(), 80)?; check_eq!(m.hp(), 80)?;
check_eq!(m.mana(), 150)?; check_eq!(m.mana(), 150)?;
check_eq!(m.name(), Some("MyMonster"))?; check_eq!(m.name(), "MyMonster")?;
check_is_some!(m.name())?;
let pos = m.pos().unwrap(); let pos = m.pos().unwrap();
check_eq!(pos.x(), 1.0f32)?; check_eq!(pos.x(), 1.0f32)?;
...@@ -178,7 +177,7 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require ...@@ -178,7 +177,7 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require
let table2 = m.test().unwrap(); let table2 = m.test().unwrap();
let monster2 = my_game::example::Monster::init_from_table(table2); let monster2 = my_game::example::Monster::init_from_table(table2);
check_eq!(monster2.name(), Some("Fred"))?; check_eq!(monster2.name(), "Fred")?;
check_is_some!(m.inventory())?; check_is_some!(m.inventory())?;
let inv = m.inventory().unwrap(); let inv = m.inventory().unwrap();
...@@ -266,7 +265,7 @@ mod roundtrip_generated_code { ...@@ -266,7 +265,7 @@ mod roundtrip_generated_code {
let mut b = flatbuffers::FlatBufferBuilder::new(); let mut b = flatbuffers::FlatBufferBuilder::new();
let name = b.create_string("foobar"); let name = b.create_string("foobar");
let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()}); let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
assert_eq!(m.name(), Some("foobar")); assert_eq!(m.name(), "foobar");
} }
#[test] #[test]
fn struct_store() { fn struct_store() {
...@@ -325,11 +324,11 @@ mod roundtrip_generated_code { ...@@ -325,11 +324,11 @@ mod roundtrip_generated_code {
} }
let mon = my_game::example::get_root_as_monster(b.finished_data()); let mon = my_game::example::get_root_as_monster(b.finished_data());
assert_eq!(mon.name(), Some("bar")); assert_eq!(mon.name(), "bar");
assert_eq!(mon.test_type(), my_game::example::Any::Monster); assert_eq!(mon.test_type(), my_game::example::Any::Monster);
assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(), assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(),
Some("foo")); "foo");
assert_eq!(mon.test_as_monster().unwrap().name(), Some("foo")); assert_eq!(mon.test_as_monster().unwrap().name(), "foo");
assert_eq!(mon.test_as_test_simple_table_with_enum(), None); assert_eq!(mon.test_as_test_simple_table_with_enum(), None);
assert_eq!(mon.test_as_my_game_example_2_monster(), None); assert_eq!(mon.test_as_my_game_example_2_monster(), None);
} }
...@@ -361,8 +360,8 @@ mod roundtrip_generated_code { ...@@ -361,8 +360,8 @@ mod roundtrip_generated_code {
} }
let mon = my_game::example::get_root_as_monster(b.finished_data()); let mon = my_game::example::get_root_as_monster(b.finished_data());
assert_eq!(mon.name(), Some("bar")); assert_eq!(mon.name(), "bar");
assert_eq!(mon.enemy().unwrap().name(), Some("foo")); assert_eq!(mon.enemy().unwrap().name(), "foo");
} }
#[test] #[test]
fn table_full_namespace_default() { fn table_full_namespace_default() {
...@@ -391,7 +390,7 @@ mod roundtrip_generated_code { ...@@ -391,7 +390,7 @@ mod roundtrip_generated_code {
} }
let mon = my_game::example::get_root_as_monster(b.finished_data()); let mon = my_game::example::get_root_as_monster(b.finished_data());
assert_eq!(mon.name(), Some("bar")); assert_eq!(mon.name(), "bar");
assert_eq!(mon.testempty().unwrap().id(), Some("foo")); assert_eq!(mon.testempty().unwrap().id(), Some("foo"));
} }
#[test] #[test]
...@@ -434,13 +433,13 @@ mod roundtrip_generated_code { ...@@ -434,13 +433,13 @@ mod roundtrip_generated_code {
let m2_a = my_game::example::get_root_as_monster(m.testnestedflatbuffer().unwrap()); let m2_a = my_game::example::get_root_as_monster(m.testnestedflatbuffer().unwrap());
assert_eq!(m2_a.hp(), 123); assert_eq!(m2_a.hp(), 123);
assert_eq!(m2_a.name(), Some("foobar")); assert_eq!(m2_a.name(), "foobar");
assert!(m.testnestedflatbuffer_nested_flatbuffer().is_some()); assert!(m.testnestedflatbuffer_nested_flatbuffer().is_some());
let m2_b = m.testnestedflatbuffer_nested_flatbuffer().unwrap(); let m2_b = m.testnestedflatbuffer_nested_flatbuffer().unwrap();
assert_eq!(m2_b.hp(), 123); assert_eq!(m2_b.hp(), 123);
assert_eq!(m2_b.name(), Some("foobar")); assert_eq!(m2_b.name(), "foobar");
} }
#[test] #[test]
fn nested_flatbuffer_default() { fn nested_flatbuffer_default() {
...@@ -561,9 +560,9 @@ mod roundtrip_generated_code { ...@@ -561,9 +560,9 @@ mod roundtrip_generated_code {
testarrayoftables: Some(v), ..Default::default()}); testarrayoftables: Some(v), ..Default::default()});
assert_eq!(m.testarrayoftables().unwrap().len(), 2); assert_eq!(m.testarrayoftables().unwrap().len(), 2);
assert_eq!(m.testarrayoftables().unwrap().get(0).hp(), 55); assert_eq!(m.testarrayoftables().unwrap().get(0).hp(), 55);
assert_eq!(m.testarrayoftables().unwrap().get(0).name(), Some("foo")); assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100); assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
assert_eq!(m.testarrayoftables().unwrap().get(1).name(), Some("bar")); assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
} }
} }
...@@ -947,7 +946,7 @@ mod framing_format { ...@@ -947,7 +946,7 @@ mod framing_format {
let m = flatbuffers::get_size_prefixed_root::<my_game::example::Monster>(buf); let m = flatbuffers::get_size_prefixed_root::<my_game::example::Monster>(buf);
assert_eq!(m.mana(), 200); assert_eq!(m.mana(), 200);
assert_eq!(m.hp(), 300); assert_eq!(m.hp(), 300);
assert_eq!(m.name(), Some("bob")); assert_eq!(m.name(), "bob");
} }
} }
...@@ -1459,13 +1458,11 @@ mod generated_key_comparisons { ...@@ -1459,13 +1458,11 @@ mod generated_key_comparisons {
let a = my_game::example::get_root_as_monster(buf); let a = my_game::example::get_root_as_monster(buf);
// preconditions // preconditions
assert_eq!(a.name(), Some("MyMonster")); assert_eq!(a.name(), "MyMonster");
assert_eq!(a.key_compare_with_value(None), ::std::cmp::Ordering::Greater); assert_eq!(a.key_compare_with_value("AAA"), ::std::cmp::Ordering::Greater);
assert_eq!(a.key_compare_with_value("MyMonster"), ::std::cmp::Ordering::Equal);
assert_eq!(a.key_compare_with_value(Some("AAA")), ::std::cmp::Ordering::Greater); assert_eq!(a.key_compare_with_value("ZZZ"), ::std::cmp::Ordering::Less);
assert_eq!(a.key_compare_with_value(Some("MyMonster")), ::std::cmp::Ordering::Equal);
assert_eq!(a.key_compare_with_value(Some("ZZZ")), ::std::cmp::Ordering::Less);
} }
#[test] #[test]
...@@ -1478,8 +1475,8 @@ mod generated_key_comparisons { ...@@ -1478,8 +1475,8 @@ mod generated_key_comparisons {
let b = a.test_as_monster().unwrap(); let b = a.test_as_monster().unwrap();
// preconditions // preconditions
assert_eq!(a.name(), Some("MyMonster")); assert_eq!(a.name(), "MyMonster");
assert_eq!(b.name(), Some("Fred")); assert_eq!(b.name(), "Fred");
assert_eq!(a.key_compare_less_than(&a), false); assert_eq!(a.key_compare_less_than(&a), false);
assert_eq!(a.key_compare_less_than(&b), false); assert_eq!(a.key_compare_less_than(&b), false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment