struct_template.rs 3.7 KB

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