THRIFT-4953: Missing Field Identifiers
When identifiers are not specified, negative id will be converted to a valid
rust identifier.
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 77ee906..70e1847 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -516,6 +516,10 @@
// Replace all instances of `search_string` with `replace_string` in `target`.
void string_replace(string& target, const string& search_string, const string& replace_string);
+
+ // Adjust field identifier to correctly handle unspecified field identifiers
+ // THRIFT-4953
+ string rust_safe_field_id(int32_t id);
};
void t_rs_generator::init_generator() {
@@ -1172,8 +1176,8 @@
generic_type_parameters << ", ";
generic_type_qualifiers << ", ";
}
- generic_type_parameters << "F" << member->get_key();
- generic_type_qualifiers << "F" << member->get_key() << ": Into<Option<" << to_rust_type(member->get_type()) << ">>";
+ generic_type_parameters << "F" << rust_safe_field_id(member->get_key());
+ generic_type_qualifiers << "F" << rust_safe_field_id(member->get_key()) << ": Into<Option<" << to_rust_type(member->get_type()) << ">>";
}
}
@@ -1204,7 +1208,7 @@
}
if (is_optional(member_req)) {
- args << member_name << ": " << "F" << member->get_key();
+ args << member_name << ": " << "F" << rust_safe_field_id(member->get_key());
} else {
args << member_name << ": " << to_rust_type(member->get_type());
}
@@ -1720,7 +1724,7 @@
for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
t_field* tfield = (*members_iter);
- f_gen_ << indent() << tfield->get_key() << " => {" << endl;
+ f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << endl;
indent_up();
render_type_sync_read("val", tfield->get_type());
f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << endl;
@@ -1830,7 +1834,7 @@
vector<t_field*>::const_iterator members_iter;
for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
t_field* member = (*members_iter);
- f_gen_ << indent() << member->get_key() << " => {" << endl;
+ f_gen_ << indent() << rust_safe_field_id(member->get_key()) << " => {" << endl;
indent_up();
render_type_sync_read("val", member->get_type());
f_gen_ << indent() << "if ret.is_none() {" << endl;
@@ -2034,7 +2038,7 @@
string t_rs_generator::struct_field_read_temp_variable(t_field* tfield) {
std::ostringstream foss;
- foss << "f_" << tfield->get_key();
+ foss << "f_" << rust_safe_field_id(tfield->get_key());
return foss.str();
}
@@ -3314,6 +3318,17 @@
return str;
}
+string t_rs_generator::rust_safe_field_id(int32_t id) {
+ string id_str = std::to_string(abs(id));
+ if (id >= 0) {
+ return id_str;
+ } else {
+ string str("neg");
+ str += id_str;
+ return str;
+ }
+}
+
void t_rs_generator::string_replace(string& target, const string& search_string, const string& replace_string) {
if (target.empty()) {
return;
diff --git a/lib/rs/test/Makefile.am b/lib/rs/test/Makefile.am
index 8edd756..486188c 100644
--- a/lib/rs/test/Makefile.am
+++ b/lib/rs/test/Makefile.am
@@ -25,6 +25,7 @@
$(THRIFT) -I ./thrifts -out src --gen rs thrifts/Midlayer.thrift
$(THRIFT) -I ./thrifts -out src --gen rs thrifts/Ultimate.thrift
$(THRIFT) -out src --gen rs $(top_builddir)/test/Recursive.thrift
+ $(THRIFT) -out src --gen rs $(top_builddir)/test/Identifiers.thrift #THRIFT-4953
check: stubs
$(CARGO) build
diff --git a/test/Identifiers.thrift b/test/Identifiers.thrift
new file mode 100644
index 0000000..aa3e4ea
--- /dev/null
+++ b/test/Identifiers.thrift
@@ -0,0 +1,6 @@
+// THRIFT-4953
+struct NoFieldIdentifiersTest {
+ string field_without_id1,
+ string field_without_id2,
+ 1: string field_with_id
+}
\ No newline at end of file