(&mut self)
| 78 | } |
| 79 | |
| 80 | fn parse_endpoint(&mut self) -> Result<Endpoint, String> { |
| 81 | let annotation = self.parse_route_annotation(); |
| 82 | let path_specs = self.parse_path_specs()?; |
| 83 | |
| 84 | self.consume(TokenType::OpenBrace, "Expect '{' before endpoint")?; |
| 85 | |
| 86 | // Parse docs |
| 87 | let docs = self.parse_docs(); |
| 88 | |
| 89 | // Parse structured parts (query and body) |
| 90 | let mut path = Vec::new(); |
| 91 | let mut query = Vec::new(); |
| 92 | let mut body = RequestBody::default(); |
| 93 | |
| 94 | // Only parse structured blocks (query/body) and directives |
| 95 | while !self.is_at_end() { |
| 96 | if self.scanner.check_identifier("query") { |
| 97 | self.advance(); |
| 98 | query = self.parse_fields()?; |
| 99 | } else if self.scanner.check_identifier("body") { |
| 100 | self.advance(); |
| 101 | body.fields = self.parse_fields()?; |
| 102 | } else if self.scanner.check_identifier("path") { |
| 103 | self.advance(); |
| 104 | path = self.parse_fields()?; |
| 105 | } else if self.scanner.check(TokenType::At) { |
| 106 | let directives = DirectiveParser::new(&mut self.scanner).parse_directives(); |
| 107 | for directive in directives { |
| 108 | match directive.name.as_str() { |
| 109 | "form" => body.kind = BodyKind::Form, |
| 110 | "json" => body.kind = BodyKind::Json, |
| 111 | name => { |
| 112 | return Err(format!( |
| 113 | "Invalid directive, only @form or @json are allowed on body block, current: @{name}" |
| 114 | )); |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | if !self.check_identifier("body") { |
| 119 | return Err("Only body block supports @form or @json directive".into()); |
| 120 | } |
| 121 | } |
| 122 | } else { |
| 123 | // Break for anything else to handle raw script |
| 124 | break; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | if self.check(TokenType::CloseBrace) { |
| 129 | return Err("Route without handler script is not allowed.".to_string()); |
| 130 | } |
| 131 | // Parse the handler function body |
| 132 | let script = self.read_raw_script()?; |
| 133 | let statements = format!( |
| 134 | "ai fn handler(path, query, body, request, header){{{}}}", |
| 135 | script |
| 136 | ); |
| 137 | self.consume(TokenType::CloseBrace, "Expect '}' after endpoint")?; |
no test coverage detected