(
state: &mut ParserState<'heap, '_, '_>,
)
| 77 | } |
| 78 | |
| 79 | fn parse_struct<'heap>( |
| 80 | state: &mut ParserState<'heap, '_, '_>, |
| 81 | ) -> Result<StructExpr<'heap>, ParserDiagnostic> { |
| 82 | // We do not use expected here, to give the user a better error message |
| 83 | let token = state |
| 84 | .advance(Expected::hint(SyntaxKind::LBrace)) |
| 85 | .change_category(From::from)?; |
| 86 | |
| 87 | if token.kind.syntax() != SyntaxKind::LBrace { |
| 88 | let span = state.insert_range(token.span); |
| 89 | |
| 90 | return Err(struct_expected_object(span, token.kind.syntax())) |
| 91 | .change_category(From::from)?; |
| 92 | } |
| 93 | |
| 94 | let mut entries = Vec::new(); |
| 95 | |
| 96 | let span = visit_object(state, token, |state, key| { |
| 97 | let key_span = state.insert_range(key.span); |
| 98 | |
| 99 | let ident = match parse_ident_from_string(state, key_span, &key.value) { |
| 100 | Ok(ident) => ident, |
| 101 | Err(error) => { |
| 102 | let error = (error.offset(), error.into_inner()); |
| 103 | |
| 104 | return Err( |
| 105 | struct_key_expected_identifier(state.spans(), key_span, error) |
| 106 | .map_category(From::from), |
| 107 | ); |
| 108 | } |
| 109 | }; |
| 110 | |
| 111 | let value = parse_expr(state)?; |
| 112 | let value_span = state.current_span(); |
| 113 | |
| 114 | entries.push(StructEntry { |
| 115 | id: NodeId::PLACEHOLDER, |
| 116 | span: state.insert_range(key.span.cover(value_span)), |
| 117 | key: ident, |
| 118 | value: Box::new_in(value, state.heap()), |
| 119 | }); |
| 120 | |
| 121 | Ok(()) |
| 122 | })?; |
| 123 | |
| 124 | Ok(StructExpr { |
| 125 | id: NodeId::PLACEHOLDER, |
| 126 | span: state.insert_range(span), |
| 127 | entries: entries.into_iter().collect_in(state.heap()), |
| 128 | r#type: None, |
| 129 | }) |
| 130 | } |
| 131 | |
| 132 | #[cfg(test)] |
| 133 | mod tests { |
no test coverage detected