event_attrs.rs 4.0 KB

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