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