event_attrs.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. use crate::{get_event_meta_items, parse_lit_str, symbol::*, ASTResult};
  2. use syn::{
  3. self,
  4. parse::{self, Parse},
  5. Meta::{List, NameValue, Path},
  6. NestedMeta::{Lit, Meta},
  7. };
  8. #[derive(Debug, Clone)]
  9. pub struct EventAttrs {
  10. input: Option<syn::Path>,
  11. output: Option<syn::Path>,
  12. error_ty: Option<String>,
  13. pub ignore: bool,
  14. }
  15. #[derive(Debug, Clone)]
  16. pub struct EventEnumAttrs {
  17. pub enum_name: String,
  18. pub enum_item_name: String,
  19. pub value: String,
  20. pub event_attrs: EventAttrs,
  21. }
  22. impl EventEnumAttrs {
  23. pub fn from_ast(
  24. ast_result: &ASTResult,
  25. ident: &syn::Ident,
  26. variant: &syn::Variant,
  27. enum_attrs: &[syn::Attribute],
  28. ) -> Self {
  29. let enum_item_name = variant.ident.to_string();
  30. let enum_name = ident.to_string();
  31. let mut value = String::new();
  32. if variant.discriminant.is_some() {
  33. if let syn::Expr::Lit(ref expr_list) = variant.discriminant.as_ref().unwrap().1 {
  34. let lit_int = if let syn::Lit::Int(ref int_value) = expr_list.lit {
  35. int_value
  36. } else {
  37. unimplemented!()
  38. };
  39. value = lit_int.base10_digits().to_string();
  40. }
  41. }
  42. let event_attrs = get_event_attrs_from(ast_result, &variant.attrs, enum_attrs);
  43. EventEnumAttrs {
  44. enum_name,
  45. enum_item_name,
  46. value,
  47. event_attrs,
  48. }
  49. }
  50. pub fn event_input(&self) -> Option<syn::Path> {
  51. self.event_attrs.input.clone()
  52. }
  53. pub fn event_output(&self) -> Option<syn::Path> {
  54. self.event_attrs.output.clone()
  55. }
  56. pub fn event_error(&self) -> String {
  57. self.event_attrs.error_ty.as_ref().unwrap().clone()
  58. }
  59. }
  60. fn get_event_attrs_from(
  61. ast_result: &ASTResult,
  62. variant_attrs: &[syn::Attribute],
  63. enum_attrs: &[syn::Attribute],
  64. ) -> EventAttrs {
  65. let mut event_attrs = EventAttrs {
  66. input: None,
  67. output: None,
  68. error_ty: None,
  69. ignore: false,
  70. };
  71. enum_attrs
  72. .iter()
  73. .filter(|attr| attr.path.segments.iter().any(|s| s.ident == EVENT_ERR))
  74. .for_each(|attr| {
  75. if let Ok(NameValue(named_value)) = attr.parse_meta() {
  76. if let syn::Lit::Str(s) = named_value.lit {
  77. event_attrs.error_ty = Some(s.value());
  78. } else {
  79. eprintln!("❌ {} should not be empty", EVENT_ERR);
  80. }
  81. } else {
  82. eprintln!("❌ Can not find any {} on attr: {:#?}", EVENT_ERR, attr);
  83. }
  84. });
  85. let mut extract_event_attr = |attr: &syn::Attribute, meta_item: &syn::NestedMeta| match &meta_item {
  86. Meta(NameValue(name_value)) => {
  87. if name_value.path == EVENT_INPUT {
  88. if let syn::Lit::Str(s) = &name_value.lit {
  89. let input_type = parse_lit_str(s)
  90. .map_err(|_| {
  91. ast_result
  92. .error_spanned_by(s, format!("failed to parse request deserializer {:?}", s.value()))
  93. })
  94. .unwrap();
  95. event_attrs.input = Some(input_type);
  96. }
  97. }
  98. if name_value.path == EVENT_OUTPUT {
  99. if let syn::Lit::Str(s) = &name_value.lit {
  100. let output_type = parse_lit_str(s)
  101. .map_err(|_| {
  102. ast_result
  103. .error_spanned_by(s, format!("failed to parse response deserializer {:?}", s.value()))
  104. })
  105. .unwrap();
  106. event_attrs.output = Some(output_type);
  107. }
  108. }
  109. }
  110. Meta(Path(word)) => {
  111. if word == EVENT_IGNORE && attr.path == EVENT {
  112. event_attrs.ignore = true;
  113. }
  114. }
  115. Lit(s) => ast_result.error_spanned_by(s, "unexpected attribute"),
  116. _ => ast_result.error_spanned_by(meta_item, "unexpected attribute"),
  117. };
  118. let attr_meta_items_info = variant_attrs
  119. .iter()
  120. .flat_map(|attr| match get_event_meta_items(ast_result, attr) {
  121. Ok(items) => Some((attr, items)),
  122. Err(_) => None,
  123. })
  124. .collect::<Vec<(&syn::Attribute, Vec<syn::NestedMeta>)>>();
  125. for (attr, nested_metas) in attr_meta_items_info {
  126. nested_metas
  127. .iter()
  128. .for_each(|meta_item| extract_event_attr(attr, meta_item))
  129. }
  130. // eprintln!("😁{:#?}", event_attrs);
  131. event_attrs
  132. }