diff --git a/pilota-build/src/codegen/mod.rs b/pilota-build/src/codegen/mod.rs index 6cbd759c..aa80bc30 100644 --- a/pilota-build/src/codegen/mod.rs +++ b/pilota-build/src/codegen/mod.rs @@ -528,9 +528,9 @@ where this: &mut Codegen, base_dir: &Path, p: &Arc<[FastStr]>, - def_ids: &Vec, + def_ids: &[CodegenItem], stream: &mut RefMut, String>, - mut dup: &mut AHashMap>, + dup: &mut AHashMap>, ) { let base_mod_name = p.iter().map(|s| s.to_string()).join("/"); let mod_file_name = format!("{}/mod.rs", base_mod_name); @@ -557,11 +557,12 @@ where let mod_dir = base_dir.join(base_mod_name.clone()); let file_name = format!("{}_{}.rs", name_prefix, node.name()); - this.write_item(&mut item_stream, *def_id, &mut dup); + this.write_item(&mut item_stream, *def_id, dup); let full_path = mod_dir.join(file_name.clone()); std::fs::create_dir_all(mod_dir).unwrap(); + let item_stream = item_stream.lines().map(|s| s.trim_end()).join("\n"); let mut file = std::io::BufWriter::new(std::fs::File::create(full_path.clone()).unwrap()); file.write_all(item_stream.as_bytes()).unwrap(); @@ -572,6 +573,7 @@ where } let mod_path = base_dir.join(&mod_file_name); + let mod_stream = mod_stream.lines().map(|s| s.trim_end()).join("\n"); let mut mod_file = std::io::BufWriter::new(std::fs::File::create(&mod_path).unwrap()); mod_file.write_all(mod_stream.as_bytes()).unwrap(); mod_file.flush().unwrap(); diff --git a/pilota-build/src/codegen/workspace.rs b/pilota-build/src/codegen/workspace.rs index 0a59ac92..65efb12e 100644 --- a/pilota-build/src/codegen/workspace.rs +++ b/pilota-build/src/codegen/workspace.rs @@ -77,14 +77,11 @@ where let members = entry_map .keys() - .filter_map(|k| { - if let DefLocation::Fixed(..) = k { - let name = self.cx().crate_name(k); - Some(format!(" \"{name}\"")) - } else { - None - } + .map(|k| { + let name = self.cx().crate_name(k); + format!(" \"{name}\"") }) + .dedup() .sorted() .join(",\n"); diff --git a/pilota-build/src/fmt.rs b/pilota-build/src/fmt.rs index 61f061e1..925e3eb6 100644 --- a/pilota-build/src/fmt.rs +++ b/pilota-build/src/fmt.rs @@ -24,8 +24,8 @@ pub fn fmt_file>(file: P) { Err(e) => eprintln!("{}", e), Ok(output) => { if !output.status.success() { - eprintln!("rustfmt failed to format {}", file.display()); std::io::stderr().write_all(&output.stderr).unwrap(); + exit(output.status.code().unwrap_or(1)) } } } diff --git a/pilota-build/src/test/mod.rs b/pilota-build/src/test/mod.rs index 1022e24d..5f50827b 100644 --- a/pilota-build/src/test/mod.rs +++ b/pilota-build/src/test/mod.rs @@ -118,6 +118,23 @@ fn test_protobuf(source: impl AsRef, target: impl AsRef) { }); } +fn test_protobuf_with_split( + source: impl AsRef, + target: impl AsRef, + gen_dir: impl AsRef, +) { + test_with_split_builder(source, target, gen_dir, |source, target| { + crate::Builder::protobuf() + .ignore_unused(false) + .split_generated_files(true) + .include_dirs(vec![source.parent().unwrap().to_path_buf()]) + .compile_with_config( + vec![IdlService::from_path(source.to_path_buf())], + crate::Output::File(target.into()), + ) + }); +} + fn test_with_builder( source: impl AsRef, target: impl AsRef, @@ -148,7 +165,7 @@ fn test_with_builder_workspace( f: F, ) { if std::env::var("UPDATE_TEST_DATA").as_deref() == Ok("1") { - fs::remove_dir(&target); + _ = fs::remove_dir(&target); fs::create_dir_all(&target).unwrap(); let cargo_toml_path = target.as_ref().join("Cargo.toml"); File::create(cargo_toml_path).unwrap(); @@ -230,7 +247,7 @@ fn test_thrift_workspace( .iter() .map(|name| IdlService::from_path(input_dir.as_ref().join(format!("{}.thrift", name)))) .collect(); - test_with_builder_workspace(input_dir, output_dir, |source, target| { + test_with_builder_workspace(input_dir, output_dir, |_, target| { crate::Builder::thrift() .ignore_unused(false) .compile_with_config(services, crate::Output::Workspace(target.into())); @@ -246,7 +263,7 @@ fn test_thrift_workspace_with_split( .iter() .map(|name| IdlService::from_path(input_dir.as_ref().join(format!("{}.thrift", name)))) .collect(); - test_with_builder_workspace(input_dir, output_dir, |source, target| { + test_with_builder_workspace(input_dir, output_dir, |_, target| { crate::Builder::thrift() .ignore_unused(false) .split_generated_files(true) @@ -386,6 +403,32 @@ fn test_protobuf_gen() { }); } +#[test] +fn test_protobuf_gen_with_split() { + let test_data_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("test_data") + .join("protobuf_with_split"); + + test_data_dir.read_dir().unwrap().for_each(|f| { + let f = f.unwrap(); + + let path = f.path(); + + if let Some(ext) = path.extension() { + if ext == "proto" { + let mut rs_path = path.clone(); + rs_path.set_extension("rs"); + + let mut gen_dir = path.clone(); + gen_dir.pop(); + gen_dir.push(rs_path.file_stem().unwrap()); + + test_protobuf_with_split(path, rs_path, gen_dir.as_path()); + } + } + }); +} + #[test] fn test_plugin_gen() { let test_data_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) diff --git a/pilota-build/test_data/protobuf_with_split/service.proto b/pilota-build/test_data/protobuf_with_split/service.proto new file mode 100644 index 00000000..06aea5c5 --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package service; + +message EchoRequest { + string message = 1; +} + +message EchoResponse { + string message = 1; +} + +service Echo { + rpc Echo(EchoRequest) returns (EchoResponse) {} +} diff --git a/pilota-build/test_data/protobuf_with_split/service.rs b/pilota-build/test_data/protobuf_with_split/service.rs new file mode 100644 index 00000000..d1b42ee9 --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service.rs @@ -0,0 +1,7 @@ +pub mod service { + #![allow(warnings, clippy::all)] + + pub mod service { + include!("service/mod.rs"); + } +} diff --git a/pilota-build/test_data/protobuf_with_split/service/message_EchoRequest.rs b/pilota-build/test_data/protobuf_with_split/service/message_EchoRequest.rs new file mode 100644 index 00000000..24fa7e01 --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service/message_EchoRequest.rs @@ -0,0 +1,43 @@ +#[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] +pub struct EchoRequest { + pub message: ::pilota::FastStr, +} +impl ::pilota::prost::Message for EchoRequest { + #[inline] + fn encoded_len(&self) -> usize { + 0 + ::pilota::prost::encoding::faststr::encoded_len(1, &self.message) + } + + #[allow(unused_variables)] + fn encode_raw(&self, buf: &mut B) + where + B: ::pilota::prost::bytes::BufMut, + { + ::pilota::prost::encoding::faststr::encode(1, &self.message, buf); + } + + #[allow(unused_variables)] + fn merge_field( + &mut self, + tag: u32, + wire_type: ::pilota::prost::encoding::WireType, + buf: &mut B, + ctx: ::pilota::prost::encoding::DecodeContext, + ) -> ::core::result::Result<(), ::pilota::prost::DecodeError> + where + B: ::pilota::prost::bytes::Buf, + { + const STRUCT_NAME: &'static str = stringify!(EchoRequest); + match tag { + 1 => { + let mut _inner_pilota_value = &mut self.message; + ::pilota::prost::encoding::faststr::merge(wire_type, _inner_pilota_value, buf, ctx) + .map_err(|mut error| { + error.push(STRUCT_NAME, stringify!(message)); + error + }) + } + _ => ::pilota::prost::encoding::skip_field(wire_type, tag, buf, ctx), + } + } +} diff --git a/pilota-build/test_data/protobuf_with_split/service/message_EchoResponse.rs b/pilota-build/test_data/protobuf_with_split/service/message_EchoResponse.rs new file mode 100644 index 00000000..175a76d3 --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service/message_EchoResponse.rs @@ -0,0 +1,43 @@ +#[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] +pub struct EchoResponse { + pub message: ::pilota::FastStr, +} +impl ::pilota::prost::Message for EchoResponse { + #[inline] + fn encoded_len(&self) -> usize { + 0 + ::pilota::prost::encoding::faststr::encoded_len(1, &self.message) + } + + #[allow(unused_variables)] + fn encode_raw(&self, buf: &mut B) + where + B: ::pilota::prost::bytes::BufMut, + { + ::pilota::prost::encoding::faststr::encode(1, &self.message, buf); + } + + #[allow(unused_variables)] + fn merge_field( + &mut self, + tag: u32, + wire_type: ::pilota::prost::encoding::WireType, + buf: &mut B, + ctx: ::pilota::prost::encoding::DecodeContext, + ) -> ::core::result::Result<(), ::pilota::prost::DecodeError> + where + B: ::pilota::prost::bytes::Buf, + { + const STRUCT_NAME: &'static str = stringify!(EchoResponse); + match tag { + 1 => { + let mut _inner_pilota_value = &mut self.message; + ::pilota::prost::encoding::faststr::merge(wire_type, _inner_pilota_value, buf, ctx) + .map_err(|mut error| { + error.push(STRUCT_NAME, stringify!(message)); + error + }) + } + _ => ::pilota::prost::encoding::skip_field(wire_type, tag, buf, ctx), + } + } +} diff --git a/pilota-build/test_data/protobuf_with_split/service/mod.rs b/pilota-build/test_data/protobuf_with_split/service/mod.rs new file mode 100644 index 00000000..eb71abf0 --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service/mod.rs @@ -0,0 +1,3 @@ +include!("message_EchoRequest.rs"); +include!("service_Echo.rs"); +include!("message_EchoResponse.rs"); diff --git a/pilota-build/test_data/protobuf_with_split/service/service_Echo.rs b/pilota-build/test_data/protobuf_with_split/service/service_Echo.rs new file mode 100644 index 00000000..4b5639cf --- /dev/null +++ b/pilota-build/test_data/protobuf_with_split/service/service_Echo.rs @@ -0,0 +1,2 @@ + +pub trait Echo {} diff --git a/pilota-build/test_data/thrift_workspace/output/Cargo.toml b/pilota-build/test_data/thrift_workspace/output/Cargo.toml index f88e4700..ade11789 100644 --- a/pilota-build/test_data/thrift_workspace/output/Cargo.toml +++ b/pilota-build/test_data/thrift_workspace/output/Cargo.toml @@ -1,7 +1,8 @@ [workspace] members = [ "article", - "author", "common", + "author", + "common", "image", ] diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/Cargo.toml b/pilota-build/test_data/thrift_workspace_with_split/output/Cargo.toml index f88e4700..ade11789 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/Cargo.toml +++ b/pilota-build/test_data/thrift_workspace_with_split/output/Cargo.toml @@ -1,7 +1,8 @@ [workspace] members = [ "article", - "author", "common", + "author", + "common", "image", ] diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/article/src/article/message_Article.rs b/pilota-build/test_data/thrift_workspace_with_split/output/article/src/article/message_Article.rs index 29ad8d68..a99b4db0 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/article/src/article/message_Article.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/article/src/article/message_Article.rs @@ -204,32 +204,32 @@ impl ::pilota::thrift::Message for Article { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::I64 => { var_1 = Some(__protocol.read_i64().await?); - + },Some(2) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_2 = Some(__protocol.read_faststr().await?); - + },Some(3) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_3 = Some(__protocol.read_faststr().await?); - + },Some(4) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_4 = Some(<::common::author::Author as ::pilota::thrift::Message>::decode_async(__protocol).await?); - + },Some(5) if field_ident.field_type == ::pilota::thrift::TType::I32 => { var_5 = Some(::decode_async(__protocol).await?); - + },Some(6) if field_ident.field_type == ::pilota::thrift::TType::List => { var_6 = Some({ let list_ident = __protocol.read_list_begin().await?; @@ -240,19 +240,19 @@ impl ::pilota::thrift::Message for Article { __protocol.read_list_end().await?; val }); - + },Some(7) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_7 = Some(<::common::common::CommonData as ::pilota::thrift::Message>::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/author/src/author/message_GetAuthorResponse.rs b/pilota-build/test_data/thrift_workspace_with_split/output/author/src/author/message_GetAuthorResponse.rs index ca4eb853..de2cb5b8 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/author/src/author/message_GetAuthorResponse.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/author/src/author/message_GetAuthorResponse.rs @@ -94,29 +94,29 @@ impl ::pilota::thrift::Message for GetAuthorResponse { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_1 = Some(<::common::author::Author as ::pilota::thrift::Message>::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/cdn/message_CDN.rs b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/cdn/message_CDN.rs index 8ece535f..542b489b 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/cdn/message_CDN.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/cdn/message_CDN.rs @@ -124,35 +124,35 @@ impl ::pilota::thrift::Message for Cdn { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::I64 => { var_1 = Some(__protocol.read_i64().await?); - + },Some(2) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_2 = Some(__protocol.read_faststr().await?); - + },Some(3) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_3 = Some(::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/message_Image.rs b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/message_Image.rs index 6ac83879..1fbb35c9 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/message_Image.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/article/image/message_Image.rs @@ -139,38 +139,38 @@ impl ::pilota::thrift::Message for Image { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::I64 => { var_1 = Some(__protocol.read_i64().await?); - + },Some(2) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_2 = Some(__protocol.read_faststr().await?); - + },Some(3) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_3 = Some(::decode_async(__protocol).await?); - + },Some(4) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_4 = Some(::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/author/message_Author.rs b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/author/message_Author.rs index a57b6372..340f8b11 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/common/src/author/message_Author.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/common/src/author/message_Author.rs @@ -154,41 +154,41 @@ impl ::pilota::thrift::Message for Author { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::I64 => { var_1 = Some(__protocol.read_i64().await?); - + },Some(2) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_2 = Some(__protocol.read_faststr().await?); - + },Some(3) if field_ident.field_type == ::pilota::thrift::TType::Binary => { var_3 = Some(__protocol.read_faststr().await?); - + },Some(4) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_4 = Some(::decode_async(__protocol).await?); - + },Some(5) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_5 = Some(::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) diff --git a/pilota-build/test_data/thrift_workspace_with_split/output/image/src/article/image/message_GetImageResponse.rs b/pilota-build/test_data/thrift_workspace_with_split/output/image/src/article/image/message_GetImageResponse.rs index e8eb80e9..abd1ebf9 100644 --- a/pilota-build/test_data/thrift_workspace_with_split/output/image/src/article/image/message_GetImageResponse.rs +++ b/pilota-build/test_data/thrift_workspace_with_split/output/image/src/article/image/message_GetImageResponse.rs @@ -94,29 +94,29 @@ impl ::pilota::thrift::Message for GetImageResponse { __protocol.read_struct_begin().await?; if let ::std::result::Result::Err(mut err) = async { loop { - - + + let field_ident = __protocol.read_field_begin().await?; if field_ident.field_type == ::pilota::thrift::TType::Stop { - + break; } else { - + } __pilota_decoding_field_id = field_ident.id; match field_ident.id { Some(1) if field_ident.field_type == ::pilota::thrift::TType::Struct => { var_1 = Some(<::common::article::image::Image as ::pilota::thrift::Message>::decode_async(__protocol).await?); - + }, _ => { __protocol.skip(field_ident.field_type).await?; - + }, } __protocol.read_field_end().await?; - + }; ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(())