mod.rs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. use flowy_ast::{ASTContainer, ASTField, ASTResult};
  2. use proc_macro2::TokenStream;
  3. pub fn expand_derive(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
  4. let ast_result = ASTResult::new();
  5. let cont = match ASTContainer::from_ast(&ast_result, input) {
  6. Some(cont) => cont,
  7. None => return Err(ast_result.check().unwrap_err()),
  8. };
  9. let mut token_stream: TokenStream = TokenStream::default();
  10. token_stream.extend(make_helper_funcs_token_stream(&cont));
  11. token_stream.extend(make_to_node_data_token_stream(&cont));
  12. if let Some(get_value_token_stream) = make_get_set_value_token_steam(&cont) {
  13. token_stream.extend(get_value_token_stream);
  14. }
  15. token_stream.extend(make_alter_children_token_stream(&ast_result, &cont));
  16. ast_result.check()?;
  17. Ok(token_stream)
  18. }
  19. pub fn make_helper_funcs_token_stream(ast: &ASTContainer) -> TokenStream {
  20. let mut token_streams = TokenStream::default();
  21. let struct_ident = &ast.ident;
  22. token_streams.extend(quote! {
  23. impl #struct_ident {
  24. pub fn get_path(&self) -> Option<Path> {
  25. let node_id = &self.node_id?;
  26. Some(self.tree.read().path_from_node_id(node_id.clone()))
  27. }
  28. }
  29. });
  30. token_streams
  31. }
  32. pub fn make_alter_children_token_stream(ast_result: &ASTResult, ast: &ASTContainer) -> TokenStream {
  33. let mut token_streams = TokenStream::default();
  34. let children_fields = ast
  35. .data
  36. .all_fields()
  37. .filter(|field| field.node_attrs.has_child)
  38. .collect::<Vec<&ASTField>>();
  39. if !children_fields.is_empty() {
  40. let struct_ident = &ast.ident;
  41. if children_fields.len() > 1 {
  42. ast_result.error_spanned_by(struct_ident, "Only one children property");
  43. return token_streams;
  44. }
  45. let children_field = children_fields.first().unwrap();
  46. let field_name = children_field.name().unwrap();
  47. let child_name = children_field.node_attrs.child_name.as_ref().unwrap();
  48. let get_func_name = format_ident!("get_{}", child_name.value());
  49. let get_mut_func_name = format_ident!("get_mut_{}", child_name.value());
  50. let add_func_name = format_ident!("add_{}", child_name.value());
  51. let remove_func_name = format_ident!("remove_{}", child_name.value());
  52. let ty = children_field.bracket_inner_ty.as_ref().unwrap().clone();
  53. token_streams.extend(quote! {
  54. impl #struct_ident {
  55. pub fn #get_func_name<T: AsRef<str>>(&self, id: T) -> Option<&#ty> {
  56. let id = id.as_ref();
  57. self.#field_name.iter().find(|element| element.id == id)
  58. }
  59. pub fn #get_mut_func_name<T: AsRef<str>>(&mut self, id: T) -> Option<&mut #ty> {
  60. let id = id.as_ref();
  61. self.#field_name.iter_mut().find(|element| element.id == id)
  62. }
  63. pub fn #remove_func_name<T: AsRef<str>>(&mut self, id: T) {
  64. let id = id.as_ref();
  65. if let Some(index) = self.#field_name.iter().position(|element| element.id == id && element.node_id.is_some()) {
  66. let element = self.#field_name.remove(index);
  67. let element_path = element.get_path().unwrap();
  68. let mut write_guard = self.tree.write();
  69. let mut nodes = vec![];
  70. if let Some(node_data) = element.node_id.and_then(|node_id| write_guard.get_node_data(node_id.clone())) {
  71. nodes.push(node_data);
  72. }
  73. let _ = write_guard.apply_op(NodeOperation::Delete {
  74. path: element_path,
  75. nodes,
  76. });
  77. }
  78. }
  79. pub fn #add_func_name(&mut self, mut value: #ty) -> Result<(), String> {
  80. if self.node_id.is_none() {
  81. return Err("The node id is empty".to_owned());
  82. }
  83. let mut transaction = Transaction::new();
  84. let parent_path = self.get_path().unwrap();
  85. let path = parent_path.clone_with(self.#field_name.len());
  86. let node_data = value.to_node_data();
  87. transaction.push_operation(NodeOperation::Insert {
  88. path: path.clone(),
  89. nodes: vec![node_data],
  90. });
  91. let _ = self.tree.write().apply_transaction(transaction);
  92. let child_node_id = self.tree.read().node_id_at_path(path).unwrap();
  93. value.node_id = Some(child_node_id);
  94. self.#field_name.push(value);
  95. Ok(())
  96. }
  97. }
  98. });
  99. }
  100. token_streams
  101. }
  102. pub fn make_to_node_data_token_stream(ast: &ASTContainer) -> TokenStream {
  103. let struct_ident = &ast.ident;
  104. let mut token_streams = TokenStream::default();
  105. let node_type = ast
  106. .node_type
  107. .as_ref()
  108. .expect("Define the type of the node by using #[node_type = \"xx\" in the struct");
  109. let set_key_values = ast
  110. .data
  111. .all_fields()
  112. .filter(|field| !field.node_attrs.has_child)
  113. .flat_map(|field| {
  114. let mut field_name = field
  115. .name()
  116. .expect("the name of the field should not be empty");
  117. let original_field_name = field
  118. .name()
  119. .expect("the name of the field should not be empty");
  120. if let Some(rename) = &field.node_attrs.rename {
  121. field_name = format_ident!("{}", rename.value());
  122. }
  123. let field_name_str = field_name.to_string();
  124. quote! {
  125. .insert_attribute(#field_name_str, self.#original_field_name.clone())
  126. }
  127. });
  128. let children_fields = ast
  129. .data
  130. .all_fields()
  131. .filter(|field| field.node_attrs.has_child)
  132. .collect::<Vec<&ASTField>>();
  133. let childrens_token_streams = match children_fields.is_empty() {
  134. true => {
  135. quote! {
  136. let children = vec![];
  137. }
  138. },
  139. false => {
  140. let children_field = children_fields.first().unwrap();
  141. let original_field_name = children_field
  142. .name()
  143. .expect("the name of the field should not be empty");
  144. quote! {
  145. let children = self.#original_field_name.iter().map(|value| value.to_node_data()).collect::<Vec<NodeData>>();
  146. }
  147. },
  148. };
  149. token_streams.extend(quote! {
  150. impl ToNodeData for #struct_ident {
  151. fn to_node_data(&self) -> NodeData {
  152. #childrens_token_streams
  153. let builder = NodeDataBuilder::new(#node_type)
  154. #(#set_key_values)*
  155. .extend_node_data(children);
  156. builder.build()
  157. }
  158. }
  159. });
  160. token_streams
  161. }
  162. pub fn make_get_set_value_token_steam(ast: &ASTContainer) -> Option<TokenStream> {
  163. let struct_ident = &ast.ident;
  164. let mut token_streams = TokenStream::default();
  165. let tree = format_ident!("tree");
  166. for field in ast.data.all_fields() {
  167. if field.node_attrs.has_child {
  168. continue;
  169. }
  170. let mut field_name = field
  171. .name()
  172. .expect("the name of the field should not be empty");
  173. if let Some(rename) = &field.node_attrs.rename {
  174. field_name = format_ident!("{}", rename.value());
  175. }
  176. let field_name_str = field_name.to_string();
  177. let get_func_name = format_ident!("get_{}", field_name);
  178. let set_func_name = format_ident!("set_{}", field_name);
  179. let get_value_return_ty = field.ty;
  180. let set_value_input_ty = field.ty;
  181. if let Some(get_value_with_fn) = &field.node_attrs.get_node_value_with {
  182. token_streams.extend(quote! {
  183. impl #struct_ident {
  184. pub fn #get_func_name(&self) -> Option<#get_value_return_ty> {
  185. let node_id = self.node_id.as_ref()?;
  186. #get_value_with_fn(self.#tree.clone(), node_id, #field_name_str)
  187. }
  188. }
  189. });
  190. }
  191. if let Some(set_value_with_fn) = &field.node_attrs.set_node_value_with {
  192. token_streams.extend(quote! {
  193. impl #struct_ident {
  194. pub fn #set_func_name(&self, value: #set_value_input_ty) {
  195. if let Some(node_id) = self.node_id.as_ref() {
  196. let _ = #set_value_with_fn(self.#tree.clone(), node_id, #field_name_str, value);
  197. }
  198. }
  199. }
  200. });
  201. }
  202. }
  203. Some(token_streams)
  204. }