(mut self)
| 84 | } |
| 85 | |
| 86 | fn parse(mut self) -> Result<AnimationTreeAsset, String> { |
| 87 | let mut name = Cow::Borrowed("AnimationTree"); |
| 88 | let mut slots = Vec::new(); |
| 89 | let mut nodes = Vec::new(); |
| 90 | let mut output = Cow::Borrowed(""); |
| 91 | let mut seen_nodes = HashSet::<String>::new(); |
| 92 | |
| 93 | while self.current != Token::Eof { |
| 94 | if self.current != Token::LBracket { |
| 95 | self.advance(); |
| 96 | continue; |
| 97 | } |
| 98 | self.advance(); |
| 99 | if self.current == Token::Slash { |
| 100 | return Err("unexpected close block".to_string()); |
| 101 | } |
| 102 | let block = self.expect_ident()?; |
| 103 | self.expect(Token::RBracket)?; |
| 104 | match block.as_str() { |
| 105 | "AnimationTree" => { |
| 106 | name = self.parse_header_block()?; |
| 107 | } |
| 108 | "AnimationSlots" => { |
| 109 | slots = self.parse_slots_block(&block)?; |
| 110 | } |
| 111 | "Output" => { |
| 112 | output = self.parse_output_block()?; |
| 113 | } |
| 114 | key => { |
| 115 | if !seen_nodes.insert(key.to_string()) { |
| 116 | return Err(format!("duplicate animation tree node `{key}`")); |
| 117 | } |
| 118 | let node = self.parse_graph_node_block(key.to_string())?; |
| 119 | nodes.push(node); |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | if output.is_empty() { |
| 125 | return Err("animation tree missing [Output]".to_string()); |
| 126 | } |
| 127 | |
| 128 | let slot_keys = slots |
| 129 | .iter() |
| 130 | .map(|s| s.name.as_ref().to_string()) |
| 131 | .collect::<HashSet<_>>(); |
| 132 | for node in &nodes { |
| 133 | if slot_keys.contains(node.key.as_ref()) { |
| 134 | return Err(format!( |
| 135 | "animation tree node `{}` conflicts with slot name", |
| 136 | node.key |
| 137 | )); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | let keys = nodes |
| 142 | .iter() |
| 143 | .map(|n| n.key.as_ref().to_string()) |
no test coverage detected