struct_template.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. use flowy_ast::*;
  2. use phf::phf_map;
  3. use crate::proto_gen::template::get_tera;
  4. use tera::Context;
  5. // Protobuf data type : https://developers.google.com/protocol-buffers/docs/proto3
  6. static RUST_TYPE_MAP: phf::Map<&'static str, &'static str> = phf_map! {
  7. "String" => "string",
  8. "i64" => "int64",
  9. "i32" => "int32",
  10. "u64" => "uint64",
  11. "u32" => "uint32",
  12. "Vec" => "repeated",
  13. "f64" => "double",
  14. "HashMap" => "map",
  15. };
  16. pub struct StructTemplate {
  17. context: Context,
  18. fields: Vec<String>,
  19. }
  20. #[allow(dead_code)]
  21. impl StructTemplate {
  22. pub fn new() -> Self {
  23. StructTemplate {
  24. context: Context::new(),
  25. fields: vec![],
  26. }
  27. }
  28. pub fn set_message_struct_name(&mut self, name: &str) {
  29. self.context.insert("struct_name", name);
  30. }
  31. pub fn set_field(&mut self, field: &ASTField) {
  32. // {{ field_type }} {{ field_name }} = {{index}};
  33. let name = field.name().unwrap().to_string();
  34. let index = field.attrs.pb_index().unwrap();
  35. let ty: &str = &field.ty_as_str();
  36. let mut mapped_ty: &str = ty;
  37. if RUST_TYPE_MAP.contains_key(ty) {
  38. mapped_ty = RUST_TYPE_MAP[ty];
  39. }
  40. if let Some(ref category) = field.bracket_category {
  41. match category {
  42. BracketCategory::Opt => match &field.bracket_inner_ty {
  43. None => {}
  44. Some(inner_ty) => match inner_ty.to_string().as_str() {
  45. //TODO: support hashmap or something else wrapped by Option
  46. "Vec" => {
  47. self.fields
  48. .push(format!("oneof one_of_{} {{ bytes {} = {}; }};", name, name, index));
  49. }
  50. _ => {
  51. self.fields.push(format!(
  52. "oneof one_of_{} {{ {} {} = {}; }};",
  53. name, mapped_ty, name, index
  54. ));
  55. }
  56. },
  57. },
  58. BracketCategory::Map((k, v)) => {
  59. let key: &str = k;
  60. let value: &str = v;
  61. self.fields.push(format!(
  62. // map<string, string> attrs = 1;
  63. "map<{}, {}> {} = {};",
  64. RUST_TYPE_MAP.get(key).unwrap_or(&key),
  65. RUST_TYPE_MAP.get(value).unwrap_or(&value),
  66. name,
  67. index
  68. ));
  69. }
  70. BracketCategory::Vec => {
  71. let bracket_ty: &str = &field.bracket_ty.as_ref().unwrap().to_string();
  72. // Vec<u8>
  73. if mapped_ty == "u8" && bracket_ty == "Vec" {
  74. self.fields.push(format!("bytes {} = {};", name, index))
  75. } else {
  76. self.fields.push(format!(
  77. "{} {} {} = {};",
  78. RUST_TYPE_MAP[bracket_ty], mapped_ty, name, index
  79. ))
  80. }
  81. }
  82. BracketCategory::Other => self.fields.push(format!("{} {} = {};", mapped_ty, name, index)),
  83. }
  84. }
  85. }
  86. pub fn render(&mut self) -> Option<String> {
  87. self.context.insert("fields", &self.fields);
  88. let tera = get_tera("proto_file");
  89. match tera.render("struct.tera", &self.context) {
  90. Ok(r) => Some(r),
  91. Err(e) => {
  92. log::error!("{:?}", e);
  93. None
  94. }
  95. }
  96. }
  97. }