diff options
author | Tdxdxoz <tdxdxoz@gmail.com> | 2022-07-17 14:14:12 +0200 |
---|---|---|
committer | Jens Geyer <jensg@apache.org> | 2022-09-01 22:05:45 +0200 |
commit | 85d82bfd0c244d88fb01a1e761606d78868dc49c (patch) | |
tree | 286391a5fc28f2d9cfc31ef80137682fbe091b25 /compiler | |
parent | 7815d645045b62ca74f6caabbb4cd2b60c33a6c4 (diff) | |
download | thrift-85d82bfd0c244d88fb01a1e761606d78868dc49c.tar.gz |
THRIFT-5600: upgrade rust toolchain to 1.61 and edition 2021
THRIFT-5606: Wrong indent for const double
Client: rs
Patch: Ommy Zhang <tdxdxoz@gmail.com>
This closes #2634
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cpp/src/thrift/generate/t_rs_generator.cc | 233 |
1 files changed, 87 insertions, 146 deletions
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc index 2f26847eb..6ce402739 100644 --- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc @@ -127,7 +127,7 @@ private: void render_const_value_holder(const string& name, t_type* ttype, t_const_value* tvalue); // Write the actual const value - the right side of a const definition. - void render_const_value(t_type* ttype, t_const_value* tvalue, bool is_owned = true); + void render_const_value(t_type* ttype, t_const_value* tvalue, bool is_owned = true, bool is_inline = true); // Write a const struct (returned from `const_value` method). void render_const_struct(t_type* ttype, t_const_value* tvalue); @@ -141,14 +141,6 @@ private: // Write a const map (returned from `const_value` method). void render_const_map(t_type* ttype, t_const_value* tvalue); - // Write the code to insert constant values into a rust vec or set. The - // `insert_function` is the rust function that we'll use to insert the elements. - void render_container_const_value( - const string& insert_function, - t_type* ttype, - t_const_value* tvalue - ); - // Write the rust representation of a thrift struct to the generated file. Set `struct_type` to `T_ARGS` // if rendering the struct used to pack arguments for a service call. When `struct_type` is `T_ARGS` the // struct and its members have module visibility, and all fields are required. When `struct_type` is @@ -195,10 +187,6 @@ private: // user-defined exception to be properly handled as Rust errors. void render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct); - // Write the implementations for the `Default`. This trait allows you to specify only the fields you want - // and use `..Default::default()` to fill in the rest. - void render_struct_default_trait_impl(const string& struct_name, t_struct* tstruct); - // Write the function that serializes a struct to its wire representation. If `struct_type` is `T_ARGS` // then all fields are considered "required", if not, the default optionality is used. void render_struct_sync_write(t_struct *tstruct, t_rs_generator::e_struct_type struct_type); @@ -541,18 +529,21 @@ void t_rs_generator::init_generator() { void t_rs_generator::render_attributes_and_includes() { // turn off some compiler/clippy warnings + // code may not be used + f_gen_ << "#![allow(dead_code)]" << endl; // code always includes BTreeMap/BTreeSet/OrderedFloat f_gen_ << "#![allow(unused_imports)]" << endl; // code might not include imports from crates f_gen_ << "#![allow(unused_extern_crates)]" << endl; // constructors take *all* struct parameters, which can trigger the "too many arguments" warning // some auto-gen'd types can be deeply nested. clippy recommends factoring them out which is hard to autogen + // some methods may start with "is_" // FIXME: re-enable the 'vec_box' lint see: [THRIFT-5364](https://issues.apache.org/jira/browse/THRIFT-5364) // This can happen because we automatically generate a Vec<Box<Type>> when the type is a typedef // and it's a forward typedef. This (typedef + forward typedef) can happen in two situations: // 1. When the type is recursive // 2. When you define types out of order - f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity, clippy::vec_box)]" << endl; + f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity, clippy::vec_box, clippy::wrong_self_convention)]" << endl; // prevent rustfmt from running against this file // lines are too long, code is (thankfully!) not visual-indented, etc. // can't use #[rustfmt::skip] see: https://github.com/rust-lang/rust/issues/54726 @@ -684,7 +675,7 @@ void t_rs_generator::render_const_value_holder(const string& name, t_type* ttype f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << endl; indent_up(); - render_const_value(ttype, tvalue); + render_const_value(ttype, tvalue, true, false); indent_down(); f_gen_ << indent() << "}" << endl; @@ -693,7 +684,11 @@ void t_rs_generator::render_const_value_holder(const string& name, t_type* ttype f_gen_ << endl; } -void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue, bool is_owned) { +void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue, bool is_owned, bool is_inline) { + if (!is_inline) { + f_gen_ << indent(); + } + if (ttype->is_base_type()) { t_base_type* tbase_type = (t_base_type*)ttype; switch (tbase_type->get_base()) { @@ -727,9 +722,9 @@ void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue, bo throw "cannot generate const value for " + t_base_type::t_base_name(tbase_type->get_base()); } } else if (ttype->is_typedef()) { - render_const_value(get_true_type(ttype), tvalue); + render_const_value(get_true_type(ttype), tvalue, is_owned, true); } else if (ttype->is_enum()) { - f_gen_ << indent() << "{" << endl; + f_gen_ << "{" << endl; indent_up(); f_gen_ << indent() @@ -739,13 +734,11 @@ void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue, bo << ").expect(\"expecting valid const value\")" << endl; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}"; } else if (ttype->is_struct() || ttype->is_xception()) { render_const_struct(ttype, tvalue); } else if (ttype->is_container()) { - f_gen_ << indent() << "{" << endl; - indent_up(); - + // all of them use vec! or from(), extra block is no longer needed if (ttype->is_list()) { render_const_list(ttype, tvalue); } else if (ttype->is_set()) { @@ -755,111 +748,87 @@ void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue, bo } else { throw "cannot generate const container value for " + ttype->get_name(); } - - indent_down(); - f_gen_ << indent() << "}" << endl; } else { throw "cannot generate const value for " + ttype->get_name(); } + + if (!is_inline) { + f_gen_ << endl; + } } void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) { if (((t_struct*)ttype)->is_union()) { - f_gen_ << indent() << "{" << endl; + f_gen_ << "{" << endl; indent_up(); f_gen_ << indent() << "unimplemented!()" << endl; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}"; } else { - f_gen_ << indent() << "{" << endl; + f_gen_ << "{" << endl; indent_up(); f_gen_ << indent() << "unimplemented!()" << endl; indent_down(); - f_gen_ << indent() << "}" << endl; + f_gen_ << indent() << "}"; } } void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_list*)ttype)->get_elem_type(); - f_gen_ << indent() << "let mut l: Vec<" << to_rust_type(elem_type) << "> = Vec::new();" << endl; + f_gen_ << "vec![" << endl; + indent_up(); const vector<t_const_value*>& elems = tvalue->get_list(); vector<t_const_value*>::const_iterator elem_iter; for(elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) { + f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); - render_container_const_value("l.push", elem_type, elem_value); + render_const_value(elem_type, elem_value); + f_gen_ << "," << endl; } - f_gen_ << indent() << "l" << endl; + indent_down(); + f_gen_ << indent() << "]"; } void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) { t_type* elem_type = ((t_set*)ttype)->get_elem_type(); - f_gen_ << indent() << "let mut s: BTreeSet<" << to_rust_type(elem_type) << "> = BTreeSet::new();" << endl; + f_gen_ << "BTreeSet::from([" << endl; + indent_up(); const vector<t_const_value*>& elems = tvalue->get_list(); vector<t_const_value*>::const_iterator elem_iter; for(elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) { + f_gen_ << indent(); t_const_value* elem_value = (*elem_iter); - render_container_const_value("s.insert", elem_type, elem_value); + render_const_value(elem_type, elem_value); + f_gen_ << "," << endl; } - f_gen_ << indent() << "s" << endl; + indent_down(); + f_gen_ << indent() << "])"; } void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) { t_type* key_type = ((t_map*)ttype)->get_key_type(); t_type* val_type = ((t_map*)ttype)->get_val_type(); - f_gen_ - << indent() - << "let mut m: BTreeMap<" - << to_rust_type(key_type) << ", " << to_rust_type(val_type) - << "> = BTreeMap::new();" - << endl; + f_gen_ << "BTreeMap::from([" << endl; + indent_up(); const map<t_const_value*, t_const_value*, t_const_value::value_compare>& elems = tvalue->get_map(); map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator elem_iter; for (elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) { t_const_value* key_value = elem_iter->first; t_const_value* val_value = elem_iter->second; - if (get_true_type(key_type)->is_base_type()) { - f_gen_ << indent() << "let k = "; - render_const_value(key_type, key_value); - f_gen_ << ";" << endl; - } else { - f_gen_ << indent() << "let k = {" << endl; - indent_up(); - render_const_value(key_type, key_value); - indent_down(); - f_gen_ << indent() << "};" << endl; - } - if (get_true_type(val_type)->is_base_type()) { - f_gen_ << indent() << "let v = "; - render_const_value(val_type, val_value); - f_gen_ << ";" << endl; - } else { - f_gen_ << indent() << "let v = {" << endl; - indent_up(); - render_const_value(val_type, val_value); - indent_down(); - f_gen_ << indent() << "};" << endl; - } - f_gen_ << indent() << "m.insert(k, v);" << endl; - } - f_gen_ << indent() << "m" << endl; -} -void t_rs_generator::render_container_const_value( - const string& insert_function, - t_type* ttype, - t_const_value* tvalue -) { - if (get_true_type(ttype)->is_base_type()) { - f_gen_ << indent() << insert_function << "("; - render_const_value(ttype, tvalue); - f_gen_ << ");" << endl; - } else { - f_gen_ << indent() << insert_function << "(" << endl; + f_gen_ << indent() << "(" << endl; indent_up(); - render_const_value(ttype, tvalue); + f_gen_ << indent(); + render_const_value(key_type, key_value); + f_gen_ << "," << endl; + f_gen_ << indent(); + render_const_value(val_type, val_value); + f_gen_ << "," << endl; indent_down(); - f_gen_ << indent() << ");" << endl; + f_gen_ << indent() << ")," << endl; } + indent_down(); + f_gen_ << indent() << "])"; } //----------------------------------------------------------------------------- @@ -1057,9 +1026,6 @@ void t_rs_generator::render_struct( render_type_comment(struct_name); render_struct_definition(struct_name, tstruct, struct_type); render_struct_impl(struct_name, tstruct, struct_type); - if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) { - render_struct_default_trait_impl(struct_name, tstruct); - } if (struct_type == t_rs_generator::T_EXCEPTION) { render_exception_struct_error_trait_impls(struct_name, tstruct); } @@ -1071,15 +1037,27 @@ void t_rs_generator::render_struct_definition( t_rs_generator::e_struct_type struct_type ) { render_rustdoc((t_doc*) tstruct); - f_gen_ << "#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl; + + const vector<t_field*> members = tstruct->get_sorted_members(); + vector<t_field*>::const_iterator members_iter; + bool need_default = struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION; + for (members_iter = members.begin(); need_default && members_iter != members.end(); ++members_iter) { + t_field* member = *members_iter; + if (!is_optional(member->get_req())) { + need_default = false; + } + } + f_gen_ + << "#[derive(Clone, Debug" + << (need_default ? ", Default" : "") + << ", Eq, Hash, Ord, PartialEq, PartialOrd)]" + << endl; f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << endl; // render the members - vector<t_field*> members = tstruct->get_sorted_members(); if (!members.empty()) { indent_up(); - vector<t_field*>::iterator members_iter; for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) { t_field* member = (*members_iter); t_field::e_req member_req = actual_field_req(member, struct_type); @@ -1137,49 +1115,6 @@ void t_rs_generator::render_exception_struct_error_trait_impls(const string& str f_gen_ << endl; } -void t_rs_generator::render_struct_default_trait_impl(const string& struct_name, t_struct* tstruct) { - bool has_required_field = false; - - const vector<t_field*>& members = tstruct->get_sorted_members(); - vector<t_field*>::const_iterator members_iter; - for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { - t_field* member = *members_iter; - if (!is_optional(member->get_req())) { - has_required_field = true; - break; - } - } - - if (has_required_field) { - return; - } - - f_gen_ << "impl Default for " << struct_name << " {" << endl; - indent_up(); - f_gen_ << indent() << "fn default() -> Self {" << endl; - indent_up(); - - if (members.empty()) { - f_gen_ << indent() << struct_name << "{}" << endl; - } else { - f_gen_ << indent() << struct_name << "{" << endl; - indent_up(); - for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { - t_field *member = (*members_iter); - string member_name(rust_field_name(member)); - f_gen_ << indent() << member_name << ": " << opt_in_req_out_value(member->get_type()) << "," << endl; - } - indent_down(); - f_gen_ << indent() << "}" << endl; - } - - indent_down(); - f_gen_ << indent() << "}" << endl; - indent_down(); - f_gen_ << "}" << endl; - f_gen_ << endl; -} - void t_rs_generator::render_struct_impl( const string& struct_name, t_struct* tstruct, @@ -1777,29 +1712,35 @@ void t_rs_generator::render_struct_sync_read( f_gen_ << indent() << "}" << endl; // now read all the fields found - f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; - f_gen_ << indent() << "match field_id {" << endl; // start match - indent_up(); + // avoid clippy::match_single_binding + if (members.empty()) { + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; + } else { + f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl; + f_gen_ << indent() << "match field_id {" << endl; // start match + indent_up(); - for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { - t_field* tfield = (*members_iter); - f_gen_ << indent() << rust_safe_field_id(tfield->get_key()) << " => {" << endl; + for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) { + t_field* tfield = (*members_iter); + 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; + indent_down(); + f_gen_ << indent() << "}," << endl; + } + + // default case (skip fields) + f_gen_ << indent() << "_ => {" << endl; indent_up(); - render_type_sync_read("val", tfield->get_type()); - f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << endl; + f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; indent_down(); f_gen_ << indent() << "}," << endl; - } - // default case (skip fields) - f_gen_ << indent() << "_ => {" << endl; - indent_up(); - f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl; - indent_down(); - f_gen_ << indent() << "}," << endl; + indent_down(); + f_gen_ << indent() << "};" << endl; // finish match + } - indent_down(); - f_gen_ << indent() << "};" << endl; // finish match f_gen_ << indent() << "i_prot.read_field_end()?;" << endl; indent_down(); f_gen_ << indent() << "}" << endl; // finish loop |