---
source: crates/laburnum-syntax-macro/src/tests/mod.rs
expression: "use laburnum_syntax_macro::tests::test_edge_case_many_union_types"
snapshot_kind: text
---
Input: >
  #[laburnum_syntax(AST)]
  pub struct ManyUnionTypes {
      two_types: NodeId<crate::Type1, crate::Type2>,
      three_types: NodeId<crate::Type1, crate::Type2, crate::Type3>,
      four_types: NodeId<crate::Type1, crate::Type2, crate::Type3, crate::Type4>,
      vec_multi: Vec<crate::declaration::Function, crate::declaration::Import>,
  }

Output: >
  #[derive(Clone, PartialEq)]
  pub struct ManyUnionTypes {
      /// The unique identifier for this node.
      pub(crate) id: crate::NodeId,
      /// The syntax node id that this node is based on.
      pub(crate) syntax: crate::SyntaxId,
      /// Any meta information that is associated with this node.
      pub(crate) meta: Option<crate::NodeId>,
      pub(crate) two_types: crate::NodeId,
      pub(crate) three_types: crate::NodeId,
      pub(crate) four_types: crate::NodeId,
      pub(crate) vec_multi: Vec<crate::NodeId>,
  }
  impl ManyUnionTypes {
      pub fn get_id(&self) -> crate::NodeId {
          self.id
      }
      pub fn get_syntax(&self) -> crate::SyntaxId {
          self.syntax
      }
      pub fn get_meta(&self) -> Option<crate::NodeId> {
          self.meta
      }
  }
  pub mod many_union_types_field {
      #[derive(Debug)]
      pub enum TwoTypes<'ast> {
          Type1(&'ast crate::Type1),
          Type2(&'ast crate::Type2),
          Error,
      }
      impl<'ast> TwoTypes<'ast> {
          pub fn validate(&self, ast: &'ast crate::AST) -> crate::Result<()> {
              match self {
                  Self::Error => Err(crate::invalid_node_error()),
                  _ => Ok(()),
              }
          }
          pub fn from_node(node: &'ast crate::Node) -> Option<TwoTypes<'ast>> {
              Some(Self::from(node))
          }
      }
      impl<'ast> From<&'ast crate::Node> for TwoTypes<'ast> {
          fn from(n: &'ast crate::Node) -> Self {
              match n {
                  crate::Node::Type1(val) => TwoTypes::Type1(val),
                  crate::Node::Type2(val) => TwoTypes::Type2(val),
                  _ => TwoTypes::Error,
              }
          }
      }
      impl<'ast> From<&'ast crate::Type1> for TwoTypes<'ast> {
          fn from(v: &'ast crate::Type1) -> Self {
              Self::Type1(v)
          }
      }
      impl<'ast> From<&'ast crate::Type2> for TwoTypes<'ast> {
          fn from(v: &'ast crate::Type2) -> Self {
              Self::Type2(v)
          }
      }
      #[derive(Debug)]
      pub enum ThreeTypes<'ast> {
          Type1(&'ast crate::Type1),
          Type2(&'ast crate::Type2),
          Type3(&'ast crate::Type3),
          Error,
      }
      impl<'ast> ThreeTypes<'ast> {
          pub fn validate(&self, ast: &'ast crate::AST) -> crate::Result<()> {
              match self {
                  Self::Error => Err(crate::invalid_node_error()),
                  _ => Ok(()),
              }
          }
          pub fn from_node(node: &'ast crate::Node) -> Option<ThreeTypes<'ast>> {
              Some(Self::from(node))
          }
      }
      impl<'ast> From<&'ast crate::Node> for ThreeTypes<'ast> {
          fn from(n: &'ast crate::Node) -> Self {
              match n {
                  crate::Node::Type1(val) => ThreeTypes::Type1(val),
                  crate::Node::Type2(val) => ThreeTypes::Type2(val),
                  crate::Node::Type3(val) => ThreeTypes::Type3(val),
                  _ => ThreeTypes::Error,
              }
          }
      }
      impl<'ast> From<&'ast crate::Type1> for ThreeTypes<'ast> {
          fn from(v: &'ast crate::Type1) -> Self {
              Self::Type1(v)
          }
      }
      impl<'ast> From<&'ast crate::Type2> for ThreeTypes<'ast> {
          fn from(v: &'ast crate::Type2) -> Self {
              Self::Type2(v)
          }
      }
      impl<'ast> From<&'ast crate::Type3> for ThreeTypes<'ast> {
          fn from(v: &'ast crate::Type3) -> Self {
              Self::Type3(v)
          }
      }
      #[derive(Debug)]
      pub enum FourTypes<'ast> {
          Type1(&'ast crate::Type1),
          Type2(&'ast crate::Type2),
          Type3(&'ast crate::Type3),
          Type4(&'ast crate::Type4),
          Error,
      }
      impl<'ast> FourTypes<'ast> {
          pub fn validate(&self, ast: &'ast crate::AST) -> crate::Result<()> {
              match self {
                  Self::Error => Err(crate::invalid_node_error()),
                  _ => Ok(()),
              }
          }
          pub fn from_node(node: &'ast crate::Node) -> Option<FourTypes<'ast>> {
              Some(Self::from(node))
          }
      }
      impl<'ast> From<&'ast crate::Node> for FourTypes<'ast> {
          fn from(n: &'ast crate::Node) -> Self {
              match n {
                  crate::Node::Type1(val) => FourTypes::Type1(val),
                  crate::Node::Type2(val) => FourTypes::Type2(val),
                  crate::Node::Type3(val) => FourTypes::Type3(val),
                  crate::Node::Type4(val) => FourTypes::Type4(val),
                  _ => FourTypes::Error,
              }
          }
      }
      impl<'ast> From<&'ast crate::Type1> for FourTypes<'ast> {
          fn from(v: &'ast crate::Type1) -> Self {
              Self::Type1(v)
          }
      }
      impl<'ast> From<&'ast crate::Type2> for FourTypes<'ast> {
          fn from(v: &'ast crate::Type2) -> Self {
              Self::Type2(v)
          }
      }
      impl<'ast> From<&'ast crate::Type3> for FourTypes<'ast> {
          fn from(v: &'ast crate::Type3) -> Self {
              Self::Type3(v)
          }
      }
      impl<'ast> From<&'ast crate::Type4> for FourTypes<'ast> {
          fn from(v: &'ast crate::Type4) -> Self {
              Self::Type4(v)
          }
      }
      #[derive(Debug)]
      pub enum VecMulti<'ast> {
          DeclarationFunction(&'ast crate::declaration::Function),
          DeclarationImport(&'ast crate::declaration::Import),
          Error,
      }
      impl<'ast> VecMulti<'ast> {
          pub fn validate(&self, ast: &'ast crate::AST) -> crate::Result<()> {
              match self {
                  Self::Error => Err(crate::invalid_node_error()),
                  _ => Ok(()),
              }
          }
          pub fn from_node(node: &'ast crate::Node) -> Option<VecMulti<'ast>> {
              Some(Self::from(node))
          }
      }
      impl<'ast> From<&'ast crate::Node> for VecMulti<'ast> {
          fn from(n: &'ast crate::Node) -> Self {
              match n {
                  crate::Node::DeclarationFunction(val) => {
                      VecMulti::DeclarationFunction(val)
                  }
                  crate::Node::DeclarationImport(val) => VecMulti::DeclarationImport(val),
                  _ => VecMulti::Error,
              }
          }
      }
      impl<'ast> From<&'ast crate::declaration::Function> for VecMulti<'ast> {
          fn from(v: &'ast crate::declaration::Function) -> Self {
              Self::DeclarationFunction(v)
          }
      }
      impl<'ast> From<&'ast crate::declaration::Import> for VecMulti<'ast> {
          fn from(v: &'ast crate::declaration::Import) -> Self {
              Self::DeclarationImport(v)
          }
      }
  }
  #[allow(unused)]
  impl ManyUnionTypes {
      ///Returns the `two_types` field
      pub fn get_two_types<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<many_union_types_field::TwoTypes<'ast>> {
          {
              let two_types = &self.two_types;
              ast.node(*two_types)
                  .and_then(|node| many_union_types_field::TwoTypes::from_node(node))
          }
      }
      ///Returns the `three_types` field
      pub fn get_three_types<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<many_union_types_field::ThreeTypes<'ast>> {
          {
              let three_types = &self.three_types;
              ast.node(*three_types)
                  .and_then(|node| many_union_types_field::ThreeTypes::from_node(node))
          }
      }
      ///Returns the `four_types` field
      pub fn get_four_types<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Option<many_union_types_field::FourTypes<'ast>> {
          {
              let four_types = &self.four_types;
              ast.node(*four_types)
                  .and_then(|node| many_union_types_field::FourTypes::from_node(node))
          }
      }
      ///Returns the `vec_multi` field
      pub fn get_vec_multi<'ast>(
          &self,
          ast: &'ast crate::AST,
      ) -> Vec<many_union_types_field::VecMulti<'ast>> {
          {
              let vec_multi = &self.vec_multi;
              vec_multi
                  .iter()
                  .filter_map(|n| {
                      ast
                          .node(*n)
                          .and_then(|node| many_union_types_field::VecMulti::from_node(
                              node,
                          ))
                  })
                  .collect::<Vec<_>>()
          }
      }
  }
  #[allow(unused)]
  impl<'ast> ManyUnionTypes {
      pub fn validate(&self, ast: &'ast crate::AST) -> crate::Result<()> {
          self.get_two_types(ast).unwrap().validate(ast).unwrap();
          self.get_three_types(ast).unwrap().validate(ast).unwrap();
          self.get_four_types(ast).unwrap().validate(ast).unwrap();
          self.get_vec_multi(ast).iter().map(|f| f.validate(ast).unwrap());
          Ok(())
      }
  }
  #[allow(unused)]
  impl std::fmt::Display for ManyUnionTypes {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          f.debug_struct(
                  &format!(
                      "{}::{}", { let __mp = module_path!(); __mp.find("::").map(| i | &
                      __mp[i + 2..]).unwrap_or(__mp) }, "ManyUnionTypes"
                  ),
              )
              .finish()
      }
  }
  #[allow(unused)]
  impl std::fmt::Debug for ManyUnionTypes {
      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          f.debug_struct(
                  &format!(
                      "{}::{}", { let __mp = module_path!(); __mp.find("::").map(| i | &
                      __mp[i + 2..]).unwrap_or(__mp) }, "ManyUnionTypes"
                  ),
              )
              .finish()
      }
  }
  #[allow(unused)]
  impl bluegum::Bluegum for ManyUnionTypes {
      fn node(&self, b: &mut bluegum::Builder) {
          b.name(
              &crate::style_title(
                  {
                      let __mp = module_path!();
                      __mp.find("::").map(|i| &__mp[i + 2..]).unwrap_or(__mp)
                  },
                  &"ManyUnionTypes",
              ),
          );
      }
  }
  #[allow(unused)]
  impl<'tokens, 'src> bluegum::BluegumWithState<crate::Printer<'tokens>>
  for ManyUnionTypes {
      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(
                  {
                      let __mp = module_path!();
                      __mp.find("::").map(|i| &__mp[i + 2..]).unwrap_or(__mp)
                  },
                  &"ManyUnionTypes",
              ),
          );
          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 two_types = &self.two_types;
                  b.add_node_with_state(state, stringify!(two_types), two_types);
              };
              {
                  let three_types = &self.three_types;
                  b.add_node_with_state(state, stringify!(three_types), three_types);
              };
              {
                  let four_types = &self.four_types;
                  b.add_node_with_state(state, stringify!(four_types), four_types);
              };
              {
                  let vec_multi = &self.vec_multi;
                  b.add_nodes_of_builders(
                      stringify!(vec_multi),
                      vec_multi
                          .iter()
                          .map(|child| bluegum::Builder::render_with_state(child, state))
                          .collect::<Vec<bluegum::Builder>>(),
                  );
              };
          };
      }
  }
