proto_gen.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use crate::proto::ast::*;
  2. use crate::proto::helper::*;
  3. use crate::{proto::template::*, util::*};
  4. use std::{fs::OpenOptions, io::Write};
  5. use walkdir::WalkDir;
  6. pub struct ProtoGen {
  7. pub(crate) rust_source_dir: String,
  8. pub(crate) flutter_mod_dir: String,
  9. pub(crate) derive_meta_dir: String,
  10. }
  11. impl ProtoGen {
  12. pub fn gen(&self) {
  13. let crate_proto_infos = parse_crate_protobuf(self.rust_source_dir.as_ref());
  14. write_proto_files(&crate_proto_infos);
  15. run_protoc(&crate_proto_infos);
  16. write_protobuf_crate_mod_file(&crate_proto_infos);
  17. write_derive_meta(&crate_proto_infos, self.derive_meta_dir.as_ref());
  18. write_rust_crate_protobuf(&crate_proto_infos);
  19. }
  20. }
  21. fn write_proto_files(crate_infos: &Vec<CrateProtoInfo>) {
  22. for crate_info in crate_infos {
  23. let dir = crate_info.inner.proto_file_output_dir();
  24. crate_info.files.iter().for_each(|info| {
  25. let proto_file_path = format!("{}/{}.proto", dir, &info.file_name);
  26. save_content_to_file_with_diff_prompt(
  27. &info.generated_content,
  28. proto_file_path.as_ref(),
  29. false,
  30. );
  31. });
  32. }
  33. }
  34. fn write_rust_crate_protobuf(crate_infos: &Vec<CrateProtoInfo>) {
  35. for crate_info in crate_infos {
  36. let mod_path = crate_info.inner.proto_model_mod_file();
  37. match OpenOptions::new()
  38. .create(true)
  39. .write(true)
  40. .append(false)
  41. .truncate(true)
  42. .open(&mod_path)
  43. {
  44. Ok(ref mut file) => {
  45. let mut mod_file_content = String::new();
  46. for (_, file_name) in WalkDir::new(crate_info.inner.proto_file_output_dir())
  47. .into_iter()
  48. .filter_map(|e| e.ok())
  49. .filter(|e| e.file_type().is_dir() == false)
  50. .map(|e| {
  51. (
  52. e.path().to_str().unwrap().to_string(),
  53. e.path().file_stem().unwrap().to_str().unwrap().to_string(),
  54. )
  55. })
  56. {
  57. let c = format!("\nmod {}; \npub use {}::*; \n", &file_name, &file_name);
  58. mod_file_content.push_str(c.as_ref());
  59. }
  60. file.write_all(mod_file_content.as_bytes()).unwrap();
  61. }
  62. Err(err) => {
  63. panic!("Failed to open file: {}", err);
  64. }
  65. }
  66. }
  67. }
  68. fn run_protoc(crate_infos: &Vec<CrateProtoInfo>) {
  69. for crate_info in crate_infos {
  70. let rust_out = crate_info.inner.proto_struct_output_dir();
  71. let proto_path = crate_info.inner.proto_file_output_dir();
  72. for proto_file in WalkDir::new(&proto_path)
  73. .into_iter()
  74. .filter_map(|e| e.ok())
  75. .filter(|e| is_proto_file(e))
  76. .map(|e| e.path().to_str().unwrap().to_string())
  77. {
  78. if cmd_lib::run_cmd! {
  79. protoc --rust_out=${rust_out} --proto_path=${proto_path} ${proto_file}
  80. }
  81. .is_err()
  82. {
  83. panic!("Create protobuf rust struct fail")
  84. };
  85. }
  86. }
  87. }
  88. fn write_protobuf_crate_mod_file(crate_infos: &Vec<CrateProtoInfo>) {
  89. for crate_info in crate_infos {
  90. crate_info.create_crate_mod_file();
  91. }
  92. }