---
source: crates/bullion/language/syntax/macro/src/ast/tests.rs
expression: "use bullion_syntax_macro::ast::tests::function"
snapshot_kind: text
---
Source: >
  #[bullion_syntax(AST)]
  pub struct Function {
      visibility: Field<Enum<crate::modifier::Visibility>>,
      ident: NodeId<crate::symbol::Ident>,
      /// The generic parameters of the function, including any constraints.
      generic_parameters: Option<NodeId<crate::ty::GenericParameters>>,
      parameters: Vec<crate::ty::Parameters>,
      return_ty: Option<NodeId<crate::ty::Path>>,
      /// A list of effects that must be handled by an ancestor.
      effects_required: Vec<NodeId<crate::ty::Path>>,
      /// A list of effects that are handled by this function.
      effects_handled: Vec<NodeId<crate::ty::Path>>,
      /// The body of the function.
      body: NodeId<crate::expression::Block>,
  }

Output: >
  #[derive(Clone, PartialEq)]
  pub struct Function {
      /// The unique identifier for this node.
      pub(crate) id: crate::NodeId,
      /// The syntax node id that this node is based on.
      pub(crate) syntax: bullion_syntax_concrete::CstNodeId,
      /// Any meta information that is associated with this node.
      pub(crate) meta: Option<crate::NodeId>,
      pub(crate) visibility: crate::modifier::Visibility,
      pub(crate) ident: crate::NodeId,
      pub(crate) generic_parameters: Option<crate::NodeId>,
      pub(crate) parameters: Vec<crate::ty::Parameters>,
      pub(crate) return_ty: Option<crate::NodeId>,
      pub(crate) effects_required: Vec<crate::NodeId>,
      pub(crate) effects_handled: Vec<crate::NodeId>,
      pub(crate) body: crate::NodeId,
  }
  impl Function {
      pub fn get_id(&self) -> crate::NodeId {
          self.id
      }
      pub fn get_syntax(&self) -> bullion_syntax_concrete::CstNodeId {
          self.syntax
      }
      pub fn get_meta(&self) -> Option<crate::NodeId> {
          self.meta
      }
  }
  pub mod function_field {}
  #[allow(unused)]
  impl Function {
      ///Returns the `visibility` field
      pub fn get_visibility<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> &crate::modifier::Visibility {
          {
              let visibility = &self.visibility;
              visibility
          }
      }
      ///Returns the `ident` field
      pub fn get_ident<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<&'ast crate::symbol::Ident> {
          {
              let ident = &self.ident;
              ast.node(*ident).and_then(|node| crate::symbol::Ident::from_node(node))
          }
      }
      ///Returns the NodeId for the `ident` field
      pub fn get_ident_id<'ast>(&self, ast: &'ast crate::AST) -> crate::NodeId {
          {
              let ident = &self.ident;
              *ident
          }
      }
      ///Returns the `generic_parameters` field
      pub fn get_generic_parameters<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<&'ast crate::ty::GenericParameters> {
          {
              if let Some(ref generic_parameters) = self.generic_parameters {
                  ast.node(*generic_parameters)
                      .and_then(|node| crate::ty::GenericParameters::from_node(node))
              } else {
                  None
              }
          }
      }
      ///Returns the NodeId for the `generic_parameters` field
      pub fn get_generic_parameters_id<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<crate::NodeId> {
          {
              if let Some(ref generic_parameters) = self.generic_parameters {
                  Some(*generic_parameters)
              } else {
                  None
              }
          }
      }
      ///Returns the `parameters` field
      pub fn get_parameters<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<crate::ty::Parameters> {
          {
              let parameters = &self.parameters;
              ast.node(*parameters)
          }
      }
      ///Returns the NodeIds for the `parameters` field
      pub fn get_parameters_ids<'ast>(&self, ast: &'ast crate::AST) -> Vec<crate::NodeId> {
          {
              let parameters = &self.parameters;
              parameters.clone()
          }
      }
      ///Returns the `return_ty` field
      pub fn get_return_ty<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<&'ast crate::ty::Path> {
          {
              if let Some(ref return_ty) = self.return_ty {
                  ast.node(*return_ty).and_then(|node| crate::ty::Path::from_node(node))
              } else {
                  None
              }
          }
      }
      ///Returns the NodeId for the `return_ty` field
      pub fn get_return_ty_id<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<crate::NodeId> {
          {
              if let Some(ref return_ty) = self.return_ty {
                  Some(*return_ty)
              } else {
                  None
              }
          }
      }
      ///Returns the `effects_required` field
      pub fn get_effects_required<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<&'ast crate::ty::Path> {
          {
              let effects_required = &self.effects_required;
              effects_required
                  .iter()
                  .filter_map(|n: &crate::NodeId| {
                      ast.node(*n)
                          .and_then(|node: &crate::Node| {
                              crate::ty::Path::from_node(node)
                          })
                  })
                  .collect::<Vec<_>>()
          }
      }
      ///Returns the NodeIds for the `effects_required` field
      pub fn get_effects_required_ids<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<crate::NodeId> {
          {
              let effects_required = &self.effects_required;
              effects_required.clone()
          }
      }
      ///Returns the `effects_handled` field
      pub fn get_effects_handled<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<&'ast crate::ty::Path> {
          {
              let effects_handled = &self.effects_handled;
              effects_handled
                  .iter()
                  .filter_map(|n: &crate::NodeId| {
                      ast.node(*n)
                          .and_then(|node: &crate::Node| {
                              crate::ty::Path::from_node(node)
                          })
                  })
                  .collect::<Vec<_>>()
          }
      }
      ///Returns the NodeIds for the `effects_handled` field
      pub fn get_effects_handled_ids<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<crate::NodeId> {
          {
              let effects_handled = &self.effects_handled;
              effects_handled.clone()
          }
      }
      ///Returns the `body` field
      pub fn get_body<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<&'ast crate::expression::Block> {
          {
              let body = &self.body;
              ast.node(*body).and_then(|node| crate::expression::Block::from_node(node))
          }
      }
      ///Returns the NodeId for the `body` field
      pub fn get_body_id<'ast>(&self, ast: &'ast crate::AST) -> crate::NodeId {
          {
              let body = &self.body;
              *body
          }
      }
  }
  #[allow(unused)]
  impl<'ast> Function {
      pub fn validate(&self, ast: &'ast crate::AST) -> bullion_error::Result<()> {
          Ok(())
      }
  }
  #[allow(unused)]
  impl std::fmt::Display for Function {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          f.debug_struct(
                  &format!(
                      "{}::{}", & module_path!() .replace("bullion_syntax_abstract::", ""),
                      "Function"
                  ),
              )
              .finish()
      }
  }
  #[allow(unused)]
  impl std::fmt::Debug for Function {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          f.debug_struct(
                  &format!(
                      "{}::{}", & module_path!() .replace("bullion_syntax_abstract::", ""),
                      "Function"
                  ),
              )
              .finish()
      }
  }
  #[allow(unused)]
  impl bluegum::Bluegum for Function {
      fn node(&self, b: &mut bluegum::Builder) {
          b.name(
              &crate::style_title(
                  &module_path!().replace("bullion_syntax_abstract::", ""),
                  &"Function",
              ),
          );
      }
  }
  #[allow(unused)]
  impl<'tokens, 'src> bluegum::BluegumWithState<crate::Printer<'tokens>> for Function {
      fn node_with_state(
          &self,
          b: &mut bluegum::Builder,
          state: &crate::Printer<'tokens>,
      ) {
          use owo_colors::OwoColorize;
          use unicode_width::UnicodeWidthStr;
          b.name(
              &crate::style_title(
                  &module_path!().replace("bullion_syntax_abstract::", ""),
                  &"Function",
              ),
          );
          if let Some(cst_node) = state.get_syntax(self.syntax) {
              let span = cst_node.span();
              if let Some(span_data) = span.data(state.get_span_cache()) {
                  b.debug(
                      "span",
                      format!("{}..{}", span_data.start, span_data.start + span_data.len),
                  );
              }
          }
          if let Some(meta) = self.meta {
              b.add_node_with_state(state, &"meta".blue().italic().to_string(), &meta);
          }
          {
              {
                  let visibility = &self.visibility;
                  use {owo_colors::OwoColorize, unicode_width::UnicodeWidthStr};
                  b.field(
                      stringify!(visibility),
                      format!("{:?}", visibility).purple().italic().to_string(),
                  );
              };
              {
                  let ident = &self.ident;
                  b.add_node_with_state(state, stringify!(ident), ident);
              };
              {
                  if let Some(ref generic_parameters) = self.generic_parameters {
                      b.add_node_with_state(
                          state,
                          stringify!(generic_parameters),
                          generic_parameters,
                      );
                  }
              };
              {
                  let parameters = &self.parameters;
                  b.add_nodes_of_builders(
                      stringify!(parameters),
                      parameters
                          .iter()
                          .map(|child| bluegum::Builder::render_with_state(child, state))
                          .collect::<Vec<bluegum::Builder>>(),
                  );
              };
              {
                  if let Some(ref return_ty) = self.return_ty {
                      b.add_node_with_state(state, stringify!(return_ty), return_ty);
                  }
              };
              {
                  let effects_required = &self.effects_required;
                  b.add_nodes_of_builders(
                      stringify!(effects_required),
                      effects_required
                          .iter()
                          .map(|child| bluegum::Builder::render_with_state(child, state))
                          .collect::<Vec<bluegum::Builder>>(),
                  );
              };
              {
                  let effects_handled = &self.effects_handled;
                  b.add_nodes_of_builders(
                      stringify!(effects_handled),
                      effects_handled
                          .iter()
                          .map(|child| bluegum::Builder::render_with_state(child, state))
                          .collect::<Vec<bluegum::Builder>>(),
                  );
              };
              {
                  let body = &self.body;
                  b.add_node_with_state(state, stringify!(body), body);
              };
          };
      }
  }
