1use crate::ast::*;
22use crate::error::{Result, SchemaError};
23use crate::span::Span;
24use crate::token::{Token, TokenKind};
25
26pub struct Parser<'a> {
28 tokens: &'a [Token],
30 pos: usize,
32 recovered_errors: Vec<crate::error::SchemaError>,
34}
35
36impl<'a> Parser<'a> {
37 pub fn new(tokens: &'a [Token], source: &'a str) -> Self {
39 let _ = source; Self {
41 tokens,
42 pos: 0,
43 recovered_errors: Vec::new(),
44 }
45 }
46
47 pub fn take_errors(&mut self) -> Vec<crate::error::SchemaError> {
53 std::mem::take(&mut self.recovered_errors)
54 }
55
56 pub fn parse_schema(&mut self) -> Result<Schema> {
58 let start = self.current_span();
59 self.skip_newlines();
60
61 let mut declarations = Vec::new();
62
63 while !self.is_at_end() {
64 match self.parse_declaration() {
65 Ok(decl) => declarations.push(decl),
66 Err(e) => {
67 self.recovered_errors.push(e);
69 self.recover_to_next_declaration();
70 }
71 }
72 self.skip_newlines();
73 }
74
75 let end = self.previous_span();
76 Ok(Schema::new(declarations, start.merge(end)))
77 }
78
79 fn parse_declaration(&mut self) -> Result<Declaration> {
81 self.skip_newlines();
82
83 match self.peek_kind() {
84 Some(TokenKind::Datasource) => Ok(Declaration::Datasource(self.parse_datasource()?)),
85 Some(TokenKind::Generator) => Ok(Declaration::Generator(self.parse_generator()?)),
86 Some(TokenKind::Model) => Ok(Declaration::Model(self.parse_model()?)),
87 Some(TokenKind::Enum) => Ok(Declaration::Enum(self.parse_enum()?)),
88 Some(TokenKind::Type) => Ok(Declaration::Type(self.parse_type_decl()?)),
89 Some(kind) => Err(SchemaError::Parse(
90 format!("Expected declaration, found {:?}", kind),
91 self.current_span(),
92 )),
93 None => Err(SchemaError::Parse(
94 "Unexpected end of file".to_string(),
95 self.current_span(),
96 )),
97 }
98 }
99
100 fn parse_datasource(&mut self) -> Result<DatasourceDecl> {
102 let start = self.expect(TokenKind::Datasource)?.span;
103 let name = self.parse_ident()?;
104 self.expect(TokenKind::LBrace)?;
105 self.skip_newlines();
106
107 let mut fields = Vec::new();
108 while !self.check(TokenKind::RBrace) && !self.is_at_end() {
109 fields.push(self.parse_config_field()?);
110 self.skip_newlines();
111 }
112
113 let end = self.expect(TokenKind::RBrace)?.span;
114 Ok(DatasourceDecl {
115 name,
116 fields,
117 span: start.merge(end),
118 })
119 }
120
121 fn parse_generator(&mut self) -> Result<GeneratorDecl> {
123 let start = self.expect(TokenKind::Generator)?.span;
124 let name = self.parse_ident()?;
125 self.expect(TokenKind::LBrace)?;
126 self.skip_newlines();
127
128 let mut fields = Vec::new();
129 while !self.check(TokenKind::RBrace) && !self.is_at_end() {
130 fields.push(self.parse_config_field()?);
131 self.skip_newlines();
132 }
133
134 let end = self.expect(TokenKind::RBrace)?.span;
135 Ok(GeneratorDecl {
136 name,
137 fields,
138 span: start.merge(end),
139 })
140 }
141
142 fn parse_config_field(&mut self) -> Result<ConfigField> {
144 let name = self.parse_ident()?;
145 self.expect(TokenKind::Equal)?;
146 let value = self.parse_expr()?;
147 let span = name.span.merge(value.span());
148 Ok(ConfigField { name, value, span })
149 }
150
151 fn parse_model(&mut self) -> Result<ModelDecl> {
153 let start = self.expect(TokenKind::Model)?.span;
154 let name = self.parse_ident()?;
155 self.expect(TokenKind::LBrace)?;
156 self.skip_newlines();
157
158 let mut fields = Vec::new();
159 let mut attributes = Vec::new();
160
161 while !self.check(TokenKind::RBrace) && !self.is_at_end() {
162 if self.check(TokenKind::AtAt) {
163 attributes.push(self.parse_model_attribute()?);
164 } else {
165 fields.push(self.parse_field_decl()?);
166 }
167 self.skip_newlines();
168 }
169
170 let end = self.expect(TokenKind::RBrace)?.span;
171 Ok(ModelDecl {
172 name,
173 fields,
174 attributes,
175 span: start.merge(end),
176 })
177 }
178
179 fn parse_type_decl(&mut self) -> Result<TypeDecl> {
181 let start = self.expect(TokenKind::Type)?.span;
182 let name = self.parse_ident()?;
183 self.expect(TokenKind::LBrace)?;
184 self.skip_newlines();
185
186 let mut fields = Vec::new();
187
188 while !self.check(TokenKind::RBrace) && !self.is_at_end() {
189 fields.push(self.parse_field_decl()?);
191 self.skip_newlines();
192 }
193
194 let end = self.expect(TokenKind::RBrace)?.span;
195 Ok(TypeDecl {
196 name,
197 fields,
198 span: start.merge(end),
199 })
200 }
201
202 fn parse_field_decl(&mut self) -> Result<FieldDecl> {
204 let name = self.parse_ident()?;
205 let field_type = self.parse_field_type()?;
206 let modifier = self.parse_field_modifier()?;
207 let base_span = name.span.merge(self.previous_span());
209
210 let mut attributes = Vec::new();
211 while self.check(TokenKind::At) && !self.check(TokenKind::AtAt) {
212 attributes.push(self.parse_field_attribute()?);
213 }
214
215 let span = if let Some(last_attr) = attributes.last() {
216 match last_attr {
217 FieldAttribute::Id => base_span,
218 FieldAttribute::Unique => base_span,
219 FieldAttribute::UpdatedAt { span } => base_span.merge(*span),
220 FieldAttribute::Default(_, span) => base_span.merge(*span),
221 FieldAttribute::Map(_) => base_span,
222 FieldAttribute::Store { .. } => base_span,
223 FieldAttribute::Relation { span, .. } => base_span.merge(*span),
224 FieldAttribute::Computed { span, .. } => base_span.merge(*span),
225 FieldAttribute::Check { span, .. } => base_span.merge(*span),
226 }
227 } else {
228 base_span
229 };
230
231 Ok(FieldDecl {
232 name,
233 field_type,
234 modifier,
235 attributes,
236 span,
237 })
238 }
239
240 fn parse_field_type(&mut self) -> Result<FieldType> {
242 let ident = self.parse_ident()?;
243
244 let field_type = match ident.value.as_str() {
245 "String" => FieldType::String,
246 "Boolean" => FieldType::Boolean,
247 "Int" => FieldType::Int,
248 "BigInt" => FieldType::BigInt,
249 "Float" => FieldType::Float,
250 "DateTime" => FieldType::DateTime,
251 "Bytes" => FieldType::Bytes,
252 "Json" => FieldType::Json,
253 "Uuid" => FieldType::Uuid,
254 "Jsonb" => FieldType::Jsonb,
255 "Xml" => FieldType::Xml,
256 "Char" => {
257 self.expect(TokenKind::LParen)?;
258 let length = self.parse_number()?.parse::<u32>().map_err(|_| {
259 SchemaError::Parse("Invalid length value".to_string(), self.current_span())
260 })?;
261 self.expect(TokenKind::RParen)?;
262 FieldType::Char { length }
263 }
264 "VarChar" => {
265 self.expect(TokenKind::LParen)?;
266 let length = self.parse_number()?.parse::<u32>().map_err(|_| {
267 SchemaError::Parse("Invalid length value".to_string(), self.current_span())
268 })?;
269 self.expect(TokenKind::RParen)?;
270 FieldType::VarChar { length }
271 }
272 "Decimal" => {
273 if self.check(TokenKind::LParen) {
274 self.advance();
275 let precision = self.parse_number()?.parse::<u32>().map_err(|_| {
276 SchemaError::Parse(
277 "Invalid precision value".to_string(),
278 self.current_span(),
279 )
280 })?;
281 self.expect(TokenKind::Comma)?;
282 let scale = self.parse_number()?.parse::<u32>().map_err(|_| {
283 SchemaError::Parse("Invalid scale value".to_string(), self.current_span())
284 })?;
285 self.expect(TokenKind::RParen)?;
286 FieldType::Decimal { precision, scale }
287 } else {
288 return Err(SchemaError::Parse(
289 "Decimal type requires precision and scale: Decimal(p, s)".to_string(),
290 ident.span,
291 ));
292 }
293 }
294 _ => FieldType::UserType(ident.value),
295 };
296
297 Ok(field_type)
298 }
299
300 fn parse_field_modifier(&mut self) -> Result<FieldModifier> {
302 if self.check(TokenKind::Question) {
303 self.advance();
304 Ok(FieldModifier::Optional)
305 } else if self.check(TokenKind::Bang) {
306 self.advance();
307 Ok(FieldModifier::NotNull)
308 } else if self.check(TokenKind::LBracket) {
309 self.advance();
310 self.expect(TokenKind::RBracket)?;
311 Ok(FieldModifier::Array)
312 } else {
313 Ok(FieldModifier::None)
314 }
315 }
316
317 fn parse_field_attribute(&mut self) -> Result<FieldAttribute> {
319 let at_token = self.expect(TokenKind::At)?;
320 let at_span = at_token.span;
321 let name = self.parse_ident()?;
322
323 match name.value.as_str() {
324 "id" => Ok(FieldAttribute::Id),
325 "unique" => Ok(FieldAttribute::Unique),
326 "updatedAt" => Ok(FieldAttribute::UpdatedAt {
327 span: at_span.merge(name.span),
328 }),
329 "default" => {
330 self.expect(TokenKind::LParen)?;
331 let expr = self.parse_expr()?;
332 let rparen = self.expect(TokenKind::RParen)?;
333 let full_span = at_span.merge(rparen.span);
334 Ok(FieldAttribute::Default(expr, full_span))
335 }
336 "map" => {
337 self.expect(TokenKind::LParen)?;
338 let map_name = self.parse_string()?;
339 self.expect(TokenKind::RParen)?;
340 Ok(FieldAttribute::Map(map_name))
341 }
342 "store" => {
343 let start = name.span;
344 self.expect(TokenKind::LParen)?;
345 let strategy_ident = self.parse_ident()?;
346 let strategy = match strategy_ident.value.as_str() {
347 "json" => StorageStrategy::Json,
348 "native" => StorageStrategy::Native,
349 _ => {
350 return Err(SchemaError::Parse(
351 format!(
352 "Unknown storage strategy: '{}'. Valid options: 'json', 'native'",
353 strategy_ident.value
354 ),
355 strategy_ident.span,
356 ))
357 }
358 };
359 let end = self.expect(TokenKind::RParen)?.span;
360 Ok(FieldAttribute::Store {
361 strategy,
362 span: start.merge(end),
363 })
364 }
365 "relation" => {
366 let start = name.span;
367 self.expect(TokenKind::LParen)?;
368
369 let mut rel_name = None;
370 let mut fields = None;
371 let mut references = None;
372 let mut on_delete = None;
373 let mut on_update = None;
374
375 while !self.check(TokenKind::RParen) && !self.is_at_end() {
376 let arg_name = self.parse_ident()?;
377 self.expect(TokenKind::Colon)?;
378
379 match arg_name.value.as_str() {
380 "name" => rel_name = Some(self.parse_string()?),
381 "fields" => fields = Some(self.parse_ident_array()?),
382 "references" => references = Some(self.parse_ident_array()?),
383 "onDelete" => on_delete = Some(self.parse_referential_action()?),
384 "onUpdate" => on_update = Some(self.parse_referential_action()?),
385 _ => {
386 return Err(SchemaError::Parse(
387 format!("Unknown relation argument: {}", arg_name.value),
388 arg_name.span,
389 ))
390 }
391 }
392
393 if self.check(TokenKind::Comma) {
394 self.advance();
395 }
396 }
397
398 let end = self.expect(TokenKind::RParen)?.span;
399 Ok(FieldAttribute::Relation {
400 name: rel_name,
401 fields,
402 references,
403 on_delete,
404 on_update,
405 span: start.merge(end),
406 })
407 }
408 "computed" => {
409 let start = at_span;
410 self.expect(TokenKind::LParen)?;
411 let expr = self.parse_sql_expr()?;
412 self.expect(TokenKind::Comma)?;
413 let kind_ident = self.parse_ident()?;
414 let kind = match kind_ident.value.as_str() {
415 "Stored" => ComputedKind::Stored,
416 "Virtual" => ComputedKind::Virtual,
417 other => {
418 return Err(SchemaError::Parse(
419 format!(
420 "Unknown computed kind '{}'. Valid options: Stored, Virtual",
421 other
422 ),
423 kind_ident.span,
424 ))
425 }
426 };
427 let end = self.expect(TokenKind::RParen)?.span;
428 Ok(FieldAttribute::Computed {
429 expr,
430 kind,
431 span: start.merge(end),
432 })
433 }
434 "check" => {
435 let start = at_span;
436 self.expect(TokenKind::LParen)?;
437 let expr = self.parse_bool_expr()?;
438 let end = self.expect(TokenKind::RParen)?.span;
439 Ok(FieldAttribute::Check {
440 expr,
441 span: start.merge(end),
442 })
443 }
444 _ => Err(SchemaError::Parse(
445 format!("Unknown field attribute: @{}", name.value),
446 name.span,
447 )),
448 }
449 }
450
451 fn parse_sql_expr(&mut self) -> Result<crate::sql_expr::SqlExpr> {
454 if self.pos >= self.tokens.len() {
455 return Err(SchemaError::Parse(
456 "Unexpected end of file in @computed expression".to_string(),
457 self.current_span(),
458 ));
459 }
460 let fallback_span = self.current_span();
461 let expr_start = self.pos;
462 let mut depth: i32 = 0;
463
464 loop {
465 match self.peek_kind() {
466 Some(TokenKind::LParen) => {
467 depth += 1;
468 self.advance();
469 }
470 Some(TokenKind::RParen) if depth == 0 => break,
471 Some(TokenKind::RParen) => {
472 depth -= 1;
473 self.advance();
474 }
475 Some(TokenKind::Comma) if depth == 0 => break,
476 None | Some(TokenKind::Eof) => {
477 return Err(SchemaError::Parse(
478 "Unexpected end of file in @computed expression".to_string(),
479 self.current_span(),
480 ));
481 }
482 _ => {
483 self.advance();
484 }
485 }
486 }
487
488 let expr_tokens: Vec<_> = self.tokens[expr_start..self.pos]
489 .iter()
490 .filter(|t| !matches!(t.kind, TokenKind::Newline))
491 .cloned()
492 .collect();
493
494 crate::sql_expr::parse_sql_expr(&expr_tokens, fallback_span)
495 }
496
497 fn parse_bool_expr(&mut self) -> Result<crate::bool_expr::BoolExpr> {
500 if self.pos >= self.tokens.len() {
501 return Err(SchemaError::Parse(
502 "Unexpected end of file in @check expression".to_string(),
503 self.current_span(),
504 ));
505 }
506 let fallback_span = self.current_span();
507 let expr_start = self.pos;
508 let mut depth: i32 = 0;
509
510 loop {
511 match self.peek_kind() {
512 Some(TokenKind::LParen) => {
513 depth += 1;
514 self.advance();
515 }
516 Some(TokenKind::RParen) if depth == 0 => break,
517 Some(TokenKind::RParen) => {
518 depth -= 1;
519 self.advance();
520 }
521 None | Some(TokenKind::Eof) => {
522 return Err(SchemaError::Parse(
523 "Unexpected end of file in @check expression".to_string(),
524 self.current_span(),
525 ));
526 }
527 _ => {
528 self.advance();
529 }
530 }
531 }
532
533 let expr_tokens: Vec<_> = self.tokens[expr_start..self.pos]
534 .iter()
535 .filter(|t| !matches!(t.kind, TokenKind::Newline))
536 .cloned()
537 .collect();
538
539 crate::bool_expr::parse_bool_expr(&expr_tokens, fallback_span)
540 }
541
542 fn parse_model_attribute(&mut self) -> Result<ModelAttribute> {
544 self.expect(TokenKind::AtAt)?;
545 let name = self.parse_ident()?;
546
547 match name.value.as_str() {
548 "map" => {
549 self.expect(TokenKind::LParen)?;
550 let map_name = self.parse_string()?;
551 self.expect(TokenKind::RParen)?;
552 Ok(ModelAttribute::Map(map_name))
553 }
554 "id" => {
555 self.expect(TokenKind::LParen)?;
556 let fields = self.parse_ident_array()?;
557 self.expect(TokenKind::RParen)?;
558 Ok(ModelAttribute::Id(fields))
559 }
560 "unique" => {
561 self.expect(TokenKind::LParen)?;
562 let fields = self.parse_ident_array()?;
563 self.expect(TokenKind::RParen)?;
564 Ok(ModelAttribute::Unique(fields))
565 }
566 "index" => {
567 self.expect(TokenKind::LParen)?;
568 let fields = self.parse_ident_array()?;
569 let mut index_type: Option<Ident> = None;
570 let mut index_name: Option<String> = None;
571 let mut index_map: Option<String> = None;
572 while self.check(TokenKind::Comma) {
573 self.advance();
574 if self.check(TokenKind::RParen) {
575 break;
576 }
577 let key = self.parse_ident()?;
578 self.expect(TokenKind::Colon)?;
579 match key.value.as_str() {
580 "type" => {
581 index_type = Some(self.parse_ident()?);
582 }
583 "name" => {
584 index_name = Some(self.parse_string()?);
585 }
586 "map" => {
587 index_map = Some(self.parse_string()?);
588 }
589 _ => {
590 return Err(SchemaError::Parse(
591 format!("Unknown @@index argument: '{}'", key.value),
592 key.span,
593 ));
594 }
595 }
596 }
597 self.expect(TokenKind::RParen)?;
598 Ok(ModelAttribute::Index {
599 fields,
600 index_type,
601 name: index_name,
602 map: index_map,
603 })
604 }
605 "check" => {
606 self.expect(TokenKind::LParen)?;
607 let expr = self.parse_bool_expr()?;
608 let end = self.expect(TokenKind::RParen)?.span;
609 Ok(ModelAttribute::Check {
610 expr,
611 span: name.span.merge(end),
612 })
613 }
614 _ => Err(SchemaError::Parse(
615 format!("Unknown model attribute: @@{}", name.value),
616 name.span,
617 )),
618 }
619 }
620
621 fn parse_ident_array(&mut self) -> Result<Vec<Ident>> {
623 self.expect(TokenKind::LBracket)?;
624 let mut idents = Vec::new();
625
626 while !self.check(TokenKind::RBracket) && !self.is_at_end() {
627 idents.push(self.parse_ident()?);
628 if self.check(TokenKind::Comma) {
629 self.advance();
630 }
631 }
632
633 self.expect(TokenKind::RBracket)?;
634 Ok(idents)
635 }
636
637 fn parse_referential_action(&mut self) -> Result<ReferentialAction> {
639 let ident = self.parse_ident()?;
640 match ident.value.as_str() {
641 "Cascade" => Ok(ReferentialAction::Cascade),
642 "Restrict" => Ok(ReferentialAction::Restrict),
643 "NoAction" => Ok(ReferentialAction::NoAction),
644 "SetNull" => Ok(ReferentialAction::SetNull),
645 "SetDefault" => Ok(ReferentialAction::SetDefault),
646 _ => Err(SchemaError::Parse(
647 format!("Unknown referential action: {}", ident.value),
648 ident.span,
649 )),
650 }
651 }
652
653 fn parse_enum(&mut self) -> Result<EnumDecl> {
655 let start = self.expect(TokenKind::Enum)?.span;
656 let name = self.parse_ident()?;
657 self.expect(TokenKind::LBrace)?;
658 self.skip_newlines();
659
660 let mut variants = Vec::new();
661 while !self.check(TokenKind::RBrace) && !self.is_at_end() {
662 let variant_name = self.parse_ident()?;
663 let variant_span = variant_name.span;
664 variants.push(EnumVariant {
665 name: variant_name,
666 span: variant_span,
667 });
668 self.skip_newlines();
669 }
670
671 let end = self.expect(TokenKind::RBrace)?.span;
672 Ok(EnumDecl {
673 name,
674 variants,
675 span: start.merge(end),
676 })
677 }
678
679 fn parse_expr(&mut self) -> Result<Expr> {
681 match self.peek_kind() {
682 Some(TokenKind::String(_)) => {
683 let s = self.parse_string()?;
684 let span = self.previous_span();
685 Ok(Expr::Literal(Literal::String(s, span)))
686 }
687 Some(TokenKind::Number(_)) => {
688 let n = self.parse_number()?;
689 let span = self.previous_span();
690 Ok(Expr::Literal(Literal::Number(n, span)))
691 }
692 Some(TokenKind::True) => {
693 let span = self.advance().span;
694 Ok(Expr::Literal(Literal::Boolean(true, span)))
695 }
696 Some(TokenKind::False) => {
697 let span = self.advance().span;
698 Ok(Expr::Literal(Literal::Boolean(false, span)))
699 }
700 Some(TokenKind::LBracket) => self.parse_array_expr(),
701 Some(TokenKind::Ident(_)) => {
702 let ident = self.parse_ident()?;
703
704 if self.check(TokenKind::LParen) {
705 let start = ident.span;
706 self.advance();
707
708 let mut args = Vec::new();
709 while !self.check(TokenKind::RParen) && !self.is_at_end() {
710 args.push(self.parse_expr()?);
711 if self.check(TokenKind::Comma) {
712 self.advance();
713 }
714 }
715
716 let end = self.expect(TokenKind::RParen)?.span;
717 Ok(Expr::FunctionCall {
718 name: ident,
719 args,
720 span: start.merge(end),
721 })
722 } else {
723 Ok(Expr::Ident(ident))
724 }
725 }
726 Some(kind) => Err(SchemaError::Parse(
727 format!("Expected expression, found {:?}", kind),
728 self.current_span(),
729 )),
730 None => Err(SchemaError::Parse(
731 "Unexpected end of file in expression".to_string(),
732 self.current_span(),
733 )),
734 }
735 }
736
737 fn parse_array_expr(&mut self) -> Result<Expr> {
739 let start = self.expect(TokenKind::LBracket)?.span;
740 let mut elements = Vec::new();
741
742 while !self.check(TokenKind::RBracket) && !self.is_at_end() {
743 elements.push(self.parse_expr()?);
744 if self.check(TokenKind::Comma) {
745 self.advance();
746 }
747 }
748
749 let end = self.expect(TokenKind::RBracket)?.span;
750 Ok(Expr::Array {
751 elements,
752 span: start.merge(end),
753 })
754 }
755
756 fn parse_ident(&mut self) -> Result<Ident> {
758 match self.peek_kind() {
759 Some(TokenKind::Ident(ref name)) => {
760 let name = name.clone();
761 let span = self.advance().span;
762 Ok(Ident::new(name, span))
763 }
764 Some(TokenKind::Type) => {
767 let span = self.advance().span;
768 Ok(Ident::new("type".to_string(), span))
769 }
770 Some(kind) => Err(SchemaError::Parse(
771 format!("Expected identifier, found {:?}", kind),
772 self.current_span(),
773 )),
774 None => Err(SchemaError::Parse(
775 "Expected identifier, found EOF".to_string(),
776 self.current_span(),
777 )),
778 }
779 }
780
781 fn parse_string(&mut self) -> Result<String> {
783 match self.peek_kind() {
784 Some(TokenKind::String(ref s)) => {
785 let s = s.clone();
786 self.advance();
787 Ok(s)
788 }
789 Some(kind) => Err(SchemaError::Parse(
790 format!("Expected string, found {:?}", kind),
791 self.current_span(),
792 )),
793 None => Err(SchemaError::Parse(
794 "Expected string, found EOF".to_string(),
795 self.current_span(),
796 )),
797 }
798 }
799
800 fn parse_number(&mut self) -> Result<String> {
802 match self.peek_kind() {
803 Some(TokenKind::Number(ref n)) => {
804 let n = n.clone();
805 self.advance();
806 Ok(n)
807 }
808 Some(kind) => Err(SchemaError::Parse(
809 format!("Expected number, found {:?}", kind),
810 self.current_span(),
811 )),
812 None => Err(SchemaError::Parse(
813 "Expected number, found EOF".to_string(),
814 self.current_span(),
815 )),
816 }
817 }
818
819 fn check(&self, kind: TokenKind) -> bool {
821 self.peek_kind()
822 .map(|k| std::mem::discriminant(&k) == std::mem::discriminant(&kind))
823 .unwrap_or(false)
824 }
825
826 fn expect(&mut self, kind: TokenKind) -> Result<&'a Token> {
828 if self.check(kind.clone()) {
829 Ok(self.advance())
830 } else {
831 Err(SchemaError::Parse(
832 format!("Expected {:?}, found {:?}", kind, self.peek_kind()),
833 self.current_span(),
834 ))
835 }
836 }
837
838 fn peek_kind(&self) -> Option<TokenKind> {
840 self.tokens.get(self.pos).map(|t| t.kind.clone())
841 }
842
843 fn advance(&mut self) -> &'a Token {
845 let token = &self.tokens[self.pos];
846 if self.pos < self.tokens.len() {
847 self.pos += 1;
848 }
849 token
850 }
851
852 fn current_span(&self) -> Span {
854 self.tokens
855 .get(self.pos)
856 .map(|t| t.span)
857 .unwrap_or_else(|| self.previous_span())
858 }
859
860 fn previous_span(&self) -> Span {
862 if self.pos > 0 {
863 self.tokens[self.pos - 1].span
864 } else {
865 Span::new(0, 0)
866 }
867 }
868
869 fn is_at_end(&self) -> bool {
871 self.pos >= self.tokens.len() || matches!(self.peek_kind(), Some(TokenKind::Eof))
872 }
873
874 fn skip_newlines(&mut self) {
876 while matches!(self.peek_kind(), Some(TokenKind::Newline)) {
877 self.advance();
878 }
879 }
880
881 fn recover_to_next_declaration(&mut self) {
883 while !self.is_at_end() {
884 match self.peek_kind() {
885 Some(TokenKind::Datasource)
886 | Some(TokenKind::Generator)
887 | Some(TokenKind::Model)
888 | Some(TokenKind::Enum)
889 | Some(TokenKind::Type) => break,
890 _ => {
891 self.advance();
892 }
893 }
894 }
895 }
896}
897
898#[cfg(test)]
899mod tests {
900 use super::*;
901 use crate::lexer::Lexer;
902
903 fn tokenize(input: &str) -> Vec<Token> {
904 let mut lexer = Lexer::new(input);
905 let mut tokens = Vec::new();
906 loop {
907 match lexer.next_token() {
908 Ok(token) => {
909 if matches!(token.kind, TokenKind::Eof) {
910 tokens.push(token);
911 break;
912 }
913 tokens.push(token);
914 }
915 Err(e) => panic!("Tokenization failed: {}", e),
916 }
917 }
918 tokens
919 }
920
921 #[test]
922 fn test_parse_empty_schema() {
923 let input = "";
924 let tokens = tokenize(input);
925 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
926 assert_eq!(schema.declarations.len(), 0);
927 }
928
929 #[test]
930 fn test_parse_simple_model() {
931 let input = r#"
932 model User {
933 id Int @id
934 }
935 "#;
936 let tokens = tokenize(input);
937 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
938 assert_eq!(schema.declarations.len(), 1);
939
940 match &schema.declarations[0] {
941 Declaration::Model(model) => {
942 assert_eq!(model.name.value, "User");
943 assert_eq!(model.fields.len(), 1);
944 assert_eq!(model.fields[0].name.value, "id");
945 }
946 _ => panic!("Expected model declaration"),
947 }
948 }
949
950 #[test]
951 fn test_parse_field_types() {
952 let input = r#"
953 model Test {
954 str String
955 num Int
956 big BigInt
957 opt String?
958 arr Int[]
959 dec Decimal(10, 2)
960 }
961 "#;
962 let tokens = tokenize(input);
963 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
964
965 match &schema.declarations[0] {
966 Declaration::Model(model) => {
967 assert_eq!(model.fields.len(), 6);
968 assert!(matches!(model.fields[0].field_type, FieldType::String));
969 assert!(matches!(model.fields[1].field_type, FieldType::Int));
970 assert!(matches!(model.fields[2].field_type, FieldType::BigInt));
971 assert!(model.fields[3].is_optional());
972 assert!(model.fields[4].is_array());
973 assert!(matches!(
974 model.fields[5].field_type,
975 FieldType::Decimal {
976 precision: 10,
977 scale: 2
978 }
979 ));
980 }
981 _ => panic!("Expected model"),
982 }
983 }
984
985 #[test]
986 fn test_parse_field_attributes() {
987 let input = r#"
988 model User {
989 id Int @id @default(autoincrement())
990 email String @unique @map("user_email")
991 }
992 "#;
993 let tokens = tokenize(input);
994 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
995
996 match &schema.declarations[0] {
997 Declaration::Model(model) => {
998 assert_eq!(model.fields[0].attributes.len(), 2);
999 assert!(matches!(model.fields[0].attributes[0], FieldAttribute::Id));
1000 assert!(matches!(
1001 model.fields[0].attributes[1],
1002 FieldAttribute::Default(..)
1003 ));
1004
1005 assert_eq!(model.fields[1].attributes.len(), 2);
1006 assert!(matches!(
1007 model.fields[1].attributes[0],
1008 FieldAttribute::Unique
1009 ));
1010 assert!(matches!(
1011 model.fields[1].attributes[1],
1012 FieldAttribute::Map(_)
1013 ));
1014 }
1015 _ => panic!("Expected model"),
1016 }
1017 }
1018
1019 #[test]
1020 fn test_parse_model_attributes() {
1021 let input = r#"
1022 model User {
1023 id Int
1024 @@map("users")
1025 @@id([id])
1026 }
1027 "#;
1028 let tokens = tokenize(input);
1029 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
1030
1031 match &schema.declarations[0] {
1032 Declaration::Model(model) => {
1033 assert_eq!(model.attributes.len(), 2);
1034 assert!(matches!(model.attributes[0], ModelAttribute::Map(_)));
1035 assert!(matches!(model.attributes[1], ModelAttribute::Id(_)));
1036 }
1037 _ => panic!("Expected model"),
1038 }
1039 }
1040
1041 #[test]
1042 fn test_parse_enum() {
1043 let input = r#"
1044 enum Role {
1045 USER
1046 ADMIN
1047 }
1048 "#;
1049 let tokens = tokenize(input);
1050 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
1051
1052 match &schema.declarations[0] {
1053 Declaration::Enum(enum_decl) => {
1054 assert_eq!(enum_decl.name.value, "Role");
1055 assert_eq!(enum_decl.variants.len(), 2);
1056 assert_eq!(enum_decl.variants[0].name.value, "USER");
1057 assert_eq!(enum_decl.variants[1].name.value, "ADMIN");
1058 }
1059 _ => panic!("Expected enum"),
1060 }
1061 }
1062
1063 #[test]
1064 fn test_parse_datasource() {
1065 let input = r#"
1066 datasource db {
1067 provider = "postgresql"
1068 url = env("DATABASE_URL")
1069 }
1070 "#;
1071 let tokens = tokenize(input);
1072 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
1073
1074 match &schema.declarations[0] {
1075 Declaration::Datasource(ds) => {
1076 assert_eq!(ds.name.value, "db");
1077 assert_eq!(ds.fields.len(), 2);
1078 assert_eq!(ds.provider(), Some("postgresql"));
1079 }
1080 _ => panic!("Expected datasource"),
1081 }
1082 }
1083
1084 #[test]
1085 fn test_parse_generator() {
1086 let input = r#"
1087 generator client {
1088 provider = "nautilus-client-rs"
1089 output = "../generated"
1090 }
1091 "#;
1092 let tokens = tokenize(input);
1093 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
1094
1095 match &schema.declarations[0] {
1096 Declaration::Generator(gen) => {
1097 assert_eq!(gen.name.value, "client");
1098 assert_eq!(gen.fields.len(), 2);
1099 }
1100 _ => panic!("Expected generator"),
1101 }
1102 }
1103
1104 #[test]
1105 fn test_parse_relation() {
1106 let input = r#"
1107 model Post {
1108 userId Int
1109 user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1110 }
1111 "#;
1112 let tokens = tokenize(input);
1113 let schema = Parser::new(&tokens, input).parse_schema().unwrap();
1114
1115 match &schema.declarations[0] {
1116 Declaration::Model(model) => match &model.fields[1].attributes[0] {
1117 FieldAttribute::Relation {
1118 fields,
1119 references,
1120 on_delete,
1121 ..
1122 } => {
1123 assert!(fields.is_some());
1124 assert!(references.is_some());
1125 assert_eq!(*on_delete, Some(ReferentialAction::Cascade));
1126 }
1127 _ => panic!("Expected relation attribute"),
1128 },
1129 _ => panic!("Expected model"),
1130 }
1131 }
1132}