1use reblessive::Stk;
2
3use crate::api::method::Method;
4use crate::api::middleware::RequestMiddleware;
5use crate::sql::access_type::JwtAccessVerify;
6use crate::sql::index::HnswParams;
7use crate::sql::statements::define::config::api::ApiConfig;
8use crate::sql::statements::define::config::graphql::{GraphQLConfig, TableConfig};
9use crate::sql::statements::define::config::ConfigInner;
10use crate::sql::statements::define::{ApiAction, DefineConfigStatement};
11use crate::sql::statements::DefineApiStatement;
12use crate::sql::Value;
13use crate::syn::error::bail;
14use crate::{
15 sql::{
16 access_type,
17 base::Base,
18 filter::Filter,
19 index::{Distance, VectorType},
20 statements::{
21 define::config::graphql, DefineAccessStatement, DefineAnalyzerStatement,
22 DefineDatabaseStatement, DefineEventStatement, DefineFieldStatement,
23 DefineFunctionStatement, DefineIndexStatement, DefineNamespaceStatement,
24 DefineParamStatement, DefineStatement, DefineTableStatement, DefineUserStatement,
25 },
26 table_type,
27 tokenizer::Tokenizer,
28 user, AccessType, Ident, Idioms, Index, Kind, Param, Permissions, Scoring, Strand,
29 TableType, Values,
30 },
31 syn::{
32 parser::{
33 mac::{expected, unexpected},
34 ParseResult, Parser,
35 },
36 token::{t, Keyword, TokenKind},
37 },
38};
39
40impl Parser<'_> {
41 pub(crate) async fn parse_define_stmt(
42 &mut self,
43 ctx: &mut Stk,
44 ) -> ParseResult<DefineStatement> {
45 let next = self.next();
46 match next.kind {
47 t!("NAMESPACE") => self.parse_define_namespace().map(DefineStatement::Namespace),
48 t!("DATABASE") => self.parse_define_database().map(DefineStatement::Database),
49 t!("FUNCTION") => self.parse_define_function(ctx).await.map(DefineStatement::Function),
50 t!("USER") => self.parse_define_user().map(DefineStatement::User),
51 t!("TOKEN") => self.parse_define_token().map(DefineStatement::Access),
52 t!("SCOPE") => self.parse_define_scope(ctx).await.map(DefineStatement::Access),
53 t!("PARAM") => self.parse_define_param(ctx).await.map(DefineStatement::Param),
54 t!("TABLE") => self.parse_define_table(ctx).await.map(DefineStatement::Table),
55 t!("API") => self.parse_define_api(ctx).await.map(DefineStatement::Api),
56 t!("EVENT") => {
57 ctx.run(|ctx| self.parse_define_event(ctx)).await.map(DefineStatement::Event)
58 }
59 t!("FIELD") => {
60 ctx.run(|ctx| self.parse_define_field(ctx)).await.map(DefineStatement::Field)
61 }
62 t!("INDEX") => {
63 ctx.run(|ctx| self.parse_define_index(ctx)).await.map(DefineStatement::Index)
64 }
65 t!("ANALYZER") => self.parse_define_analyzer().map(DefineStatement::Analyzer),
66 t!("ACCESS") => self.parse_define_access(ctx).await.map(DefineStatement::Access),
67 t!("CONFIG") => self.parse_define_config(ctx).await.map(DefineStatement::Config),
68 _ => unexpected!(self, next, "a define statement keyword"),
69 }
70 }
71
72 pub(crate) fn parse_define_namespace(&mut self) -> ParseResult<DefineNamespaceStatement> {
73 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
74 expected!(self, t!("NOT"));
75 expected!(self, t!("EXISTS"));
76 (true, false)
77 } else if self.eat(t!("OVERWRITE")) {
78 (false, true)
79 } else {
80 (false, false)
81 };
82 let name = self.next_token_value()?;
83 let mut res = DefineNamespaceStatement {
84 id: None,
85 name,
86 if_not_exists,
87 overwrite,
88 ..Default::default()
89 };
90
91 while let t!("COMMENT") = self.peek_kind() {
92 self.pop_peek();
93 res.comment = Some(self.next_token_value()?);
94 }
95
96 Ok(res)
97 }
98
99 pub fn parse_define_database(&mut self) -> ParseResult<DefineDatabaseStatement> {
100 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
101 expected!(self, t!("NOT"));
102 expected!(self, t!("EXISTS"));
103 (true, false)
104 } else if self.eat(t!("OVERWRITE")) {
105 (false, true)
106 } else {
107 (false, false)
108 };
109 let name = self.next_token_value()?;
110 let mut res = DefineDatabaseStatement {
111 name,
112 if_not_exists,
113 overwrite,
114 ..Default::default()
115 };
116 loop {
117 match self.peek_kind() {
118 t!("COMMENT") => {
119 self.pop_peek();
120 res.comment = Some(self.next_token_value()?);
121 }
122 t!("CHANGEFEED") => {
123 self.pop_peek();
124 res.changefeed = Some(self.parse_changefeed()?);
125 }
126 _ => break,
127 }
128 }
129
130 Ok(res)
131 }
132
133 pub async fn parse_define_function(
134 &mut self,
135 ctx: &mut Stk,
136 ) -> ParseResult<DefineFunctionStatement> {
137 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
138 expected!(self, t!("NOT"));
139 expected!(self, t!("EXISTS"));
140 (true, false)
141 } else if self.eat(t!("OVERWRITE")) {
142 (false, true)
143 } else {
144 (false, false)
145 };
146 let name = self.parse_custom_function_name()?;
147 let token = expected!(self, t!("(")).span;
148 let mut args = Vec::new();
149 loop {
150 if self.eat(t!(")")) {
151 break;
152 }
153
154 let param = self.next_token_value::<Param>()?.0;
155 expected!(self, t!(":"));
156 let kind = ctx.run(|ctx| self.parse_inner_kind(ctx)).await?;
157
158 args.push((param, kind));
159
160 if !self.eat(t!(",")) {
161 self.expect_closing_delimiter(t!(")"), token)?;
162 break;
163 }
164 }
165 let returns = if self.eat(t!("->")) {
166 Some(ctx.run(|ctx| self.parse_inner_kind(ctx)).await?)
167 } else {
168 None
169 };
170
171 let next = expected!(self, t!("{")).span;
172 let block = self.parse_block(ctx, next).await?;
173
174 let mut res = DefineFunctionStatement {
175 name,
176 args,
177 block,
178 if_not_exists,
179 overwrite,
180 returns,
181 ..Default::default()
182 };
183
184 loop {
185 match self.peek_kind() {
186 t!("COMMENT") => {
187 self.pop_peek();
188 res.comment = Some(self.next_token_value()?);
189 }
190 t!("PERMISSIONS") => {
191 self.pop_peek();
192 res.permissions = ctx.run(|ctx| self.parse_permission_value(ctx)).await?;
193 }
194 _ => break,
195 }
196 }
197
198 Ok(res)
199 }
200
201 pub fn parse_define_user(&mut self) -> ParseResult<DefineUserStatement> {
202 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
203 expected!(self, t!("NOT"));
204 expected!(self, t!("EXISTS"));
205 (true, false)
206 } else if self.eat(t!("OVERWRITE")) {
207 (false, true)
208 } else {
209 (false, false)
210 };
211 let name = self.next_token_value()?;
212 expected!(self, t!("ON"));
213 let base = self.parse_base(false)?;
214
215 let mut res = DefineUserStatement::from_parsed_values(
216 name,
217 base,
218 vec!["Viewer".into()], user::UserDuration::default(),
220 );
221
222 if if_not_exists {
223 res.if_not_exists = true;
224 }
225
226 if overwrite {
227 res.overwrite = true;
228 }
229
230 loop {
231 match self.peek_kind() {
232 t!("COMMENT") => {
233 self.pop_peek();
234 res.comment = Some(self.next_token_value()?);
235 }
236 t!("PASSWORD") => {
237 self.pop_peek();
238 res.set_password(&self.next_token_value::<Strand>()?.0);
239 }
240 t!("PASSHASH") => {
241 self.pop_peek();
242 res.set_passhash(self.next_token_value::<Strand>()?.0);
243 }
244 t!("ROLES") => {
245 self.pop_peek();
246 let mut roles = Vec::new();
247 loop {
248 let token = self.peek();
249 let role = self.next_token_value::<Ident>()?;
250 if !matches!(role.to_lowercase().as_str(), "viewer" | "editor" | "owner") {
255 unexpected!(self, token, "an existent role");
256 }
257 roles.push(role);
258
259 if !self.eat(t!(",")) {
260 res.roles = roles;
261 break;
262 }
263 }
264 }
265 t!("DURATION") => {
266 self.pop_peek();
267 while self.eat(t!("FOR")) {
268 match self.peek_kind() {
269 t!("TOKEN") => {
270 self.pop_peek();
271 let peek = self.peek();
272 match peek.kind {
273 t!("NONE") => {
274 unexpected!(self, peek, "a token duration");
277 }
278 _ => res.set_token_duration(Some(self.next_token_value()?)),
279 }
280 }
281 t!("SESSION") => {
282 self.pop_peek();
283 match self.peek_kind() {
284 t!("NONE") => {
285 self.pop_peek();
286 res.set_session_duration(None)
287 }
288 _ => res.set_session_duration(Some(self.next_token_value()?)),
289 }
290 }
291 _ => break,
292 }
293 self.eat(t!(","));
294 }
295 }
296 _ => break,
297 }
298 }
299
300 Ok(res)
301 }
302
303 pub async fn parse_define_access(
304 &mut self,
305 stk: &mut Stk,
306 ) -> ParseResult<DefineAccessStatement> {
307 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
308 expected!(self, t!("NOT"));
309 expected!(self, t!("EXISTS"));
310 (true, false)
311 } else if self.eat(t!("OVERWRITE")) {
312 (false, true)
313 } else {
314 (false, false)
315 };
316 let name = self.next_token_value()?;
317 expected!(self, t!("ON"));
318 let base = self.parse_base(false)?;
320
321 let mut res = DefineAccessStatement {
322 name,
323 base,
324 if_not_exists,
325 overwrite,
326 ..Default::default()
327 };
328
329 loop {
330 match self.peek_kind() {
331 t!("COMMENT") => {
332 self.pop_peek();
333 res.comment = Some(self.next_token_value()?);
334 }
335 t!("TYPE") => {
336 self.pop_peek();
337 let peek = self.peek();
338 match peek.kind {
339 t!("JWT") => {
340 self.pop_peek();
341 res.kind = AccessType::Jwt(self.parse_jwt()?);
342 }
343 t!("RECORD") => {
344 let token = self.pop_peek();
345 if !matches!(res.base, Base::Db) {
347 unexpected!(self, token, "a valid access type at this level");
348 }
349 let mut ac = access_type::RecordAccess {
350 ..Default::default()
351 };
352 loop {
353 match self.peek_kind() {
354 t!("SIGNUP") => {
355 self.pop_peek();
356 ac.signup =
357 Some(stk.run(|stk| self.parse_value_field(stk)).await?);
358 }
359 t!("SIGNIN") => {
360 self.pop_peek();
361 ac.signin =
362 Some(stk.run(|stk| self.parse_value_field(stk)).await?);
363 }
364 _ => break,
365 }
366 }
367 while self.eat(t!("WITH")) {
368 match self.peek_kind() {
369 t!("JWT") => {
370 self.pop_peek();
371 let jwt = self.parse_jwt()?;
372 ac.jwt = jwt.clone();
373 if let Some(mut bearer) = ac.bearer {
375 bearer.jwt = jwt;
376 ac.bearer = Some(bearer);
377 }
378 }
379 t!("REFRESH") => {
380 if !self.settings.bearer_access_enabled {
382 unexpected!(
383 self,
384 peek,
385 "the experimental bearer access feature to be enabled"
386 );
387 }
388
389 self.pop_peek();
390 ac.bearer = Some(access_type::BearerAccess {
391 kind: access_type::BearerAccessType::Refresh,
392 subject: access_type::BearerAccessSubject::Record,
393 jwt: ac.jwt.clone(),
395 });
396 }
397 _ => break,
398 }
399 self.eat(t!(","));
400 }
401 res.kind = AccessType::Record(ac);
402 }
403 t!("BEARER") => {
404 if !self.settings.bearer_access_enabled {
406 unexpected!(
407 self,
408 peek,
409 "the experimental bearer access feature to be enabled"
410 );
411 }
412
413 self.pop_peek();
414 let mut ac = access_type::BearerAccess {
415 ..Default::default()
416 };
417 expected!(self, t!("FOR"));
418 match self.peek_kind() {
419 t!("USER") => {
420 self.pop_peek();
421 ac.subject = access_type::BearerAccessSubject::User;
422 }
423 t!("RECORD") => {
424 match &res.base {
425 Base::Db => (),
426 _ => unexpected!(self, peek, "USER"),
427 }
428 self.pop_peek();
429 ac.subject = access_type::BearerAccessSubject::Record;
430 }
431 _ => match &res.base {
432 Base::Db => unexpected!(self, peek, "either USER or RECORD"),
433 _ => unexpected!(self, peek, "USER"),
434 },
435 }
436 if self.eat(t!("WITH")) {
437 expected!(self, t!("JWT"));
438 ac.jwt = self.parse_jwt()?;
439 }
440 res.kind = AccessType::Bearer(ac);
441 }
442 _ => break,
443 }
444 }
445 t!("AUTHENTICATE") => {
446 self.pop_peek();
447 res.authenticate = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
448 }
449 t!("DURATION") => {
450 self.pop_peek();
451 while self.eat(t!("FOR")) {
452 match self.peek_kind() {
453 t!("GRANT") => {
454 self.pop_peek();
455 match self.peek_kind() {
456 t!("NONE") => {
457 self.pop_peek();
458 res.duration.grant = None
459 }
460 _ => res.duration.grant = Some(self.next_token_value()?),
461 }
462 }
463 t!("TOKEN") => {
464 self.pop_peek();
465 let peek = self.peek();
466 match peek.kind {
467 t!("NONE") => {
468 unexpected!(self, peek, "a token duration");
473 }
474 _ => res.duration.token = Some(self.next_token_value()?),
475 }
476 }
477 t!("SESSION") => {
478 self.pop_peek();
479 match self.peek_kind() {
480 t!("NONE") => {
481 self.pop_peek();
482 res.duration.session = None
483 }
484 _ => res.duration.session = Some(self.next_token_value()?),
485 }
486 }
487 _ => break,
488 }
489 self.eat(t!(","));
490 }
491 }
492 _ => break,
493 }
494 }
495
496 Ok(res)
497 }
498
499 pub fn parse_define_token(&mut self) -> ParseResult<DefineAccessStatement> {
501 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
502 expected!(self, t!("NOT"));
503 expected!(self, t!("EXISTS"));
504 (true, false)
505 } else if self.eat(t!("OVERWRITE")) {
506 (false, true)
507 } else {
508 (false, false)
509 };
510 let name = self.next_token_value()?;
511 expected!(self, t!("ON"));
512 let base = self.parse_base(true)?;
513
514 let mut res = DefineAccessStatement {
515 name,
516 base: base.clone(),
517 if_not_exists,
518 overwrite,
519 ..Default::default()
520 };
521
522 match base {
523 Base::Sc(_) => {
525 res.base = Base::Db;
526 let mut ac = access_type::RecordAccess {
527 ..Default::default()
528 };
529 ac.jwt.issue = None;
530 loop {
531 match self.peek_kind() {
532 t!("COMMENT") => {
533 self.pop_peek();
534 res.comment = Some(self.next_token_value()?);
535 }
536 t!("TYPE") => {
539 self.pop_peek();
540 let next = self.next();
541 match next.kind {
542 TokenKind::Algorithm(alg) => {
543 expected!(self, t!("VALUE"));
544 ac.jwt.verify = access_type::JwtAccessVerify::Key(
545 access_type::JwtAccessVerifyKey {
546 alg,
547 key: self.next_token_value::<Strand>()?.0,
548 },
549 );
550 }
551 TokenKind::Keyword(Keyword::Jwks) => {
552 expected!(self, t!("VALUE"));
553 ac.jwt.verify = access_type::JwtAccessVerify::Jwks(
554 access_type::JwtAccessVerifyJwks {
555 url: self.next_token_value::<Strand>()?.0,
556 },
557 );
558 }
559 _ => unexpected!(self, next, "a token algorithm or 'JWKS'"),
560 }
561 }
562 _ => break,
563 }
564 }
565 res.kind = AccessType::Record(ac);
566 }
567 _ => {
569 let mut ac = access_type::JwtAccess {
570 issue: None,
571 ..Default::default()
572 };
573 loop {
574 match self.peek_kind() {
575 t!("COMMENT") => {
576 self.pop_peek();
577 res.comment = Some(self.next_token_value()?);
578 }
579 t!("TYPE") => {
582 self.pop_peek();
583 let next = self.next();
584 match next.kind {
585 TokenKind::Algorithm(alg) => {
586 expected!(self, t!("VALUE"));
587 ac.verify = access_type::JwtAccessVerify::Key(
588 access_type::JwtAccessVerifyKey {
589 alg,
590 key: self.next_token_value::<Strand>()?.0,
591 },
592 );
593 }
594 TokenKind::Keyword(Keyword::Jwks) => {
595 expected!(self, t!("VALUE"));
596 ac.verify = access_type::JwtAccessVerify::Jwks(
597 access_type::JwtAccessVerifyJwks {
598 url: self.next_token_value::<Strand>()?.0,
599 },
600 );
601 }
602 _ => unexpected!(self, next, "a token algorithm or 'JWKS'"),
603 }
604 }
605 _ => break,
606 }
607 }
608 res.kind = AccessType::Jwt(ac);
609 }
610 }
611
612 Ok(res)
613 }
614
615 pub async fn parse_define_scope(
617 &mut self,
618 stk: &mut Stk,
619 ) -> ParseResult<DefineAccessStatement> {
620 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
621 expected!(self, t!("NOT"));
622 expected!(self, t!("EXISTS"));
623 (true, false)
624 } else if self.eat(t!("OVERWRITE")) {
625 (false, true)
626 } else {
627 (false, false)
628 };
629 let name = self.next_token_value()?;
630 let mut res = DefineAccessStatement {
631 name,
632 base: Base::Db,
633 if_not_exists,
634 overwrite,
635 ..Default::default()
636 };
637 let mut ac = access_type::RecordAccess {
638 ..Default::default()
639 };
640
641 loop {
642 match self.peek_kind() {
643 t!("COMMENT") => {
644 self.pop_peek();
645 res.comment = Some(self.next_token_value()?);
646 }
647 t!("SESSION") => {
648 self.pop_peek();
649 res.duration.session = Some(self.next_token_value()?);
650 }
651 t!("SIGNUP") => {
652 self.pop_peek();
653 ac.signup = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
654 }
655 t!("SIGNIN") => {
656 self.pop_peek();
657 ac.signin = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
658 }
659 _ => break,
660 }
661 }
662
663 res.kind = AccessType::Record(ac);
664
665 Ok(res)
666 }
667
668 pub async fn parse_define_param(&mut self, ctx: &mut Stk) -> ParseResult<DefineParamStatement> {
669 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
670 expected!(self, t!("NOT"));
671 expected!(self, t!("EXISTS"));
672 (true, false)
673 } else if self.eat(t!("OVERWRITE")) {
674 (false, true)
675 } else {
676 (false, false)
677 };
678 let name = self.next_token_value::<Param>()?.0;
679
680 let mut res = DefineParamStatement {
681 name,
682 if_not_exists,
683 overwrite,
684 ..Default::default()
685 };
686
687 loop {
688 match self.peek_kind() {
689 t!("VALUE") => {
690 self.pop_peek();
691 res.value = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
692 }
693 t!("COMMENT") => {
694 self.pop_peek();
695 res.comment = Some(self.next_token_value()?);
696 }
697 t!("PERMISSIONS") => {
698 self.pop_peek();
699 res.permissions = ctx.run(|ctx| self.parse_permission_value(ctx)).await?;
700 }
701 _ => break,
702 }
703 }
704 Ok(res)
705 }
706
707 pub async fn parse_define_table(&mut self, ctx: &mut Stk) -> ParseResult<DefineTableStatement> {
708 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
709 expected!(self, t!("NOT"));
710 expected!(self, t!("EXISTS"));
711 (true, false)
712 } else if self.eat(t!("OVERWRITE")) {
713 (false, true)
714 } else {
715 (false, false)
716 };
717 let name = self.next_token_value()?;
718 let mut res = DefineTableStatement {
719 name,
720 permissions: Permissions::none(),
721 if_not_exists,
722 overwrite,
723 ..Default::default()
724 };
725
726 let mut kind: Option<TableType> = None;
727
728 loop {
729 match self.peek_kind() {
730 t!("COMMENT") => {
731 self.pop_peek();
732 res.comment = Some(self.next_token_value()?);
733 }
734 t!("DROP") => {
735 self.pop_peek();
736 res.drop = true;
737 }
738 t!("TYPE") => {
739 self.pop_peek();
740 let peek = self.peek();
741 match peek.kind {
742 t!("NORMAL") => {
743 self.pop_peek();
744 kind = Some(TableType::Normal);
745 }
746 t!("RELATION") => {
747 self.pop_peek();
748 kind = Some(TableType::Relation(self.parse_relation_schema()?));
749 }
750 t!("ANY") => {
751 self.pop_peek();
752 kind = Some(TableType::Any);
753 }
754 _ => unexpected!(self, peek, "`NORMAL`, `RELATION`, or `ANY`"),
755 }
756 }
757 t!("SCHEMALESS") => {
758 self.pop_peek();
759 res.full = false;
760 }
761 t!("SCHEMAFULL") => {
762 self.pop_peek();
763 res.full = true;
764 if kind.is_none() {
765 kind = Some(TableType::Normal);
766 }
767 }
768 t!("PERMISSIONS") => {
769 self.pop_peek();
770 res.permissions = ctx.run(|ctx| self.parse_permission(ctx, false)).await?;
771 }
772 t!("CHANGEFEED") => {
773 self.pop_peek();
774 res.changefeed = Some(self.parse_changefeed()?);
775 }
776 t!("AS") => {
777 self.pop_peek();
778 let peek = self.peek();
779 match peek.kind {
780 t!("(") => {
781 let open = self.pop_peek().span;
782 res.view = Some(self.parse_view(ctx).await?);
783 self.expect_closing_delimiter(t!(")"), open)?;
784 }
785 t!("SELECT") => {
786 res.view = Some(self.parse_view(ctx).await?);
787 }
788 _ => unexpected!(self, peek, "`SELECT`"),
789 }
790 }
791 _ => break,
792 }
793 }
794
795 if let Some(kind) = kind {
796 res.kind = kind;
797 }
798
799 Ok(res)
800 }
801
802 pub async fn parse_define_api(&mut self, ctx: &mut Stk) -> ParseResult<DefineApiStatement> {
803 if !self.settings.define_api_enabled {
804 bail!("Cannot define an API, as the experimental define api capability is not enabled", @self.last_span);
805 }
806
807 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
808 expected!(self, t!("NOT"));
809 expected!(self, t!("EXISTS"));
810 (true, false)
811 } else if self.eat(t!("OVERWRITE")) {
812 (false, true)
813 } else {
814 (false, false)
815 };
816
817 let path = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
818
819 let mut res = DefineApiStatement {
820 path,
821 if_not_exists,
822 overwrite,
823 ..Default::default()
824 };
825
826 loop {
827 if !self.eat(t!("FOR")) {
828 break;
829 }
830
831 match self.peek().kind {
832 t!("ANY") => {
833 self.pop_peek();
834 res.config = match self.parse_api_config(ctx).await? {
835 v if v.is_empty() => None,
836 v => Some(v),
837 };
838
839 if self.eat(t!("THEN")) {
840 res.fallback = Some(ctx.run(|ctx| self.parse_value_field(ctx)).await?);
841 }
842 }
843 t!("DELETE") | t!("GET") | t!("PATCH") | t!("POST") | t!("PUT") | t!("TRACE") => {
844 let mut methods: Vec<Method> = vec![];
845 'methods: loop {
846 let method = match self.peek().kind {
847 t!("DELETE") => Method::Delete,
848 t!("GET") => Method::Get,
849 t!("PATCH") => Method::Patch,
850 t!("POST") => Method::Post,
851 t!("PUT") => Method::Put,
852 t!("TRACE") => Method::Trace,
853 found => {
854 bail!("Expected one of `delete`, `get`, `patch`, `post`, `put` or `trace`, found {found}");
855 }
856 };
857
858 self.pop_peek();
859 methods.push(method);
860
861 if !self.eat(t!(",")) {
862 break 'methods;
863 }
864 }
865
866 let config = match self.parse_api_config(ctx).await? {
867 v if v.is_empty() => None,
868 v => Some(v),
869 };
870
871 expected!(self, t!("THEN"));
872 let action = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
873 res.actions.push(ApiAction {
874 methods,
875 action,
876 config,
877 });
878 }
879 found => {
880 bail!(
881 "Expected one of `any`, `delete`, `get`, `patch`, `post`, `put` or `trace`, found {found}"
882 );
883 }
884 }
885 }
886
887 Ok(res)
888 }
889
890 pub async fn parse_define_event(&mut self, ctx: &mut Stk) -> ParseResult<DefineEventStatement> {
891 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
892 expected!(self, t!("NOT"));
893 expected!(self, t!("EXISTS"));
894 (true, false)
895 } else if self.eat(t!("OVERWRITE")) {
896 (false, true)
897 } else {
898 (false, false)
899 };
900 let name = self.next_token_value()?;
901 expected!(self, t!("ON"));
902 self.eat(t!("TABLE"));
903 let what = self.next_token_value()?;
904
905 let mut res = DefineEventStatement {
906 name,
907 what,
908 when: Value::Bool(true),
909 if_not_exists,
910 overwrite,
911 ..Default::default()
912 };
913
914 loop {
915 match self.peek_kind() {
916 t!("WHEN") => {
917 self.pop_peek();
918 res.when = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
919 }
920 t!("THEN") => {
921 self.pop_peek();
922 res.then = Values(vec![ctx.run(|ctx| self.parse_value_field(ctx)).await?]);
923 while self.eat(t!(",")) {
924 res.then.0.push(ctx.run(|ctx| self.parse_value_field(ctx)).await?)
925 }
926 }
927 t!("COMMENT") => {
928 self.pop_peek();
929 res.comment = Some(self.next_token_value()?);
930 }
931 _ => break,
932 }
933 }
934 Ok(res)
935 }
936
937 pub async fn parse_define_field(&mut self, ctx: &mut Stk) -> ParseResult<DefineFieldStatement> {
938 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
939 expected!(self, t!("NOT"));
940 expected!(self, t!("EXISTS"));
941 (true, false)
942 } else if self.eat(t!("OVERWRITE")) {
943 (false, true)
944 } else {
945 (false, false)
946 };
947 let name = self.parse_local_idiom(ctx).await?;
948 expected!(self, t!("ON"));
949 self.eat(t!("TABLE"));
950 let what = self.next_token_value()?;
951
952 let mut res = DefineFieldStatement {
953 name,
954 what,
955 if_not_exists,
956 overwrite,
957 ..Default::default()
958 };
959
960 loop {
961 match self.peek_kind() {
962 t!("FLEXIBLE") => {
964 self.pop_peek();
965 res.flex = true;
966 }
967 t!("TYPE") => {
968 self.pop_peek();
969 res.kind = Some(ctx.run(|ctx| self.parse_inner_kind(ctx)).await?);
970 }
971 t!("READONLY") => {
972 self.pop_peek();
973 res.readonly = true;
974 }
975 t!("VALUE") => {
976 self.pop_peek();
977 res.value = Some(ctx.run(|ctx| self.parse_value_field(ctx)).await?);
978 }
979 t!("ASSERT") => {
980 self.pop_peek();
981 res.assert = Some(ctx.run(|ctx| self.parse_value_field(ctx)).await?);
982 }
983 t!("DEFAULT") => {
984 self.pop_peek();
985 if self.eat(t!("ALWAYS")) {
986 res.default_always = true;
987 }
988
989 res.default = Some(ctx.run(|ctx| self.parse_value_field(ctx)).await?);
990 }
991 t!("PERMISSIONS") => {
992 self.pop_peek();
993 res.permissions = ctx.run(|ctx| self.parse_permission(ctx, true)).await?;
994 }
995 t!("COMMENT") => {
996 self.pop_peek();
997 res.comment = Some(self.next_token_value()?);
998 }
999 t!("REFERENCE") => {
1000 if !self.settings.references_enabled {
1001 bail!(
1002 "Experimental capability `record_references` is not enabled",
1003 @self.last_span() => "Use of `REFERENCE` keyword is still experimental"
1004 )
1005 }
1006
1007 self.pop_peek();
1008 res.reference = Some(self.parse_reference(ctx).await?);
1009 }
1010 _ => break,
1011 }
1012 }
1013
1014 Ok(res)
1015 }
1016
1017 pub async fn parse_define_index(&mut self, ctx: &mut Stk) -> ParseResult<DefineIndexStatement> {
1018 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1019 expected!(self, t!("NOT"));
1020 expected!(self, t!("EXISTS"));
1021 (true, false)
1022 } else if self.eat(t!("OVERWRITE")) {
1023 (false, true)
1024 } else {
1025 (false, false)
1026 };
1027 let name = self.next_token_value()?;
1028 expected!(self, t!("ON"));
1029 self.eat(t!("TABLE"));
1030 let what = self.next_token_value()?;
1031
1032 let mut res = DefineIndexStatement {
1033 name,
1034 what,
1035
1036 if_not_exists,
1037 overwrite,
1038 ..Default::default()
1039 };
1040
1041 loop {
1042 match self.peek_kind() {
1043 t!("FIELDS") => {
1045 self.pop_peek();
1046 res.cols = Idioms(vec![self.parse_local_idiom(ctx).await?]);
1047 while self.eat(t!(",")) {
1048 res.cols.0.push(self.parse_local_idiom(ctx).await?);
1049 }
1050 }
1051 t!("UNIQUE") => {
1052 self.pop_peek();
1053 res.index = Index::Uniq;
1054 }
1055 t!("SEARCH") => {
1056 self.pop_peek();
1057 let mut analyzer: Option<Ident> = None;
1058 let mut scoring = None;
1059 let mut doc_ids_order = 100;
1060 let mut doc_lengths_order = 100;
1061 let mut postings_order = 100;
1062 let mut terms_order = 100;
1063 let mut doc_ids_cache = 100;
1064 let mut doc_lengths_cache = 100;
1065 let mut postings_cache = 100;
1066 let mut terms_cache = 100;
1067 let mut hl = false;
1068
1069 loop {
1070 match self.peek_kind() {
1071 t!("ANALYZER") => {
1072 self.pop_peek();
1073 analyzer = Some(self.next_token_value()).transpose()?;
1074 }
1075 t!("VS") => {
1076 self.pop_peek();
1077 scoring = Some(Scoring::Vs);
1078 }
1079 t!("BM25") => {
1080 self.pop_peek();
1081 if self.eat(t!("(")) {
1082 let open = self.last_span();
1083 let k1 = self.next_token_value()?;
1084 expected!(self, t!(","));
1085 let b = self.next_token_value()?;
1086 self.expect_closing_delimiter(t!(")"), open)?;
1087 scoring = Some(Scoring::Bm {
1088 k1,
1089 b,
1090 })
1091 } else {
1092 scoring = Some(Default::default());
1093 };
1094 }
1095 t!("DOC_IDS_ORDER") => {
1096 self.pop_peek();
1097 doc_ids_order = self.next_token_value()?;
1098 }
1099 t!("DOC_LENGTHS_ORDER") => {
1100 self.pop_peek();
1101 doc_lengths_order = self.next_token_value()?;
1102 }
1103 t!("POSTINGS_ORDER") => {
1104 self.pop_peek();
1105 postings_order = self.next_token_value()?;
1106 }
1107 t!("TERMS_ORDER") => {
1108 self.pop_peek();
1109 terms_order = self.next_token_value()?;
1110 }
1111 t!("DOC_IDS_CACHE") => {
1112 self.pop_peek();
1113 doc_ids_cache = self.next_token_value()?;
1114 }
1115 t!("DOC_LENGTHS_CACHE") => {
1116 self.pop_peek();
1117 doc_lengths_cache = self.next_token_value()?;
1118 }
1119 t!("POSTINGS_CACHE") => {
1120 self.pop_peek();
1121 postings_cache = self.next_token_value()?;
1122 }
1123 t!("TERMS_CACHE") => {
1124 self.pop_peek();
1125 terms_cache = self.next_token_value()?;
1126 }
1127 t!("HIGHLIGHTS") => {
1128 self.pop_peek();
1129 hl = true;
1130 }
1131 _ => break,
1132 }
1133 }
1134
1135 res.index = Index::Search(crate::sql::index::SearchParams {
1136 az: analyzer.unwrap_or_else(|| Ident::from("like")),
1137 sc: scoring.unwrap_or_else(Default::default),
1138 hl,
1139 doc_ids_order,
1140 doc_lengths_order,
1141 postings_order,
1142 terms_order,
1143 doc_ids_cache,
1144 doc_lengths_cache,
1145 postings_cache,
1146 terms_cache,
1147 });
1148 }
1149 t!("MTREE") => {
1150 self.pop_peek();
1151 expected!(self, t!("DIMENSION"));
1152 let dimension = self.next_token_value()?;
1153 let mut distance = Distance::Euclidean;
1154 let mut vector_type = VectorType::F64;
1155 let mut capacity = 40;
1156 let mut doc_ids_cache = 100;
1157 let mut doc_ids_order = 100;
1158 let mut mtree_cache = 100;
1159 loop {
1160 match self.peek_kind() {
1161 t!("DISTANCE") => {
1162 self.pop_peek();
1163 distance = self.parse_distance()?
1164 }
1165 t!("TYPE") => {
1166 self.pop_peek();
1167 vector_type = self.parse_vector_type()?
1168 }
1169 t!("CAPACITY") => {
1170 self.pop_peek();
1171 capacity = self.next_token_value()?
1172 }
1173 t!("DOC_IDS_CACHE") => {
1174 self.pop_peek();
1175 doc_ids_cache = self.next_token_value()?
1176 }
1177 t!("DOC_IDS_ORDER") => {
1178 self.pop_peek();
1179 doc_ids_order = self.next_token_value()?
1180 }
1181 t!("MTREE_CACHE") => {
1182 self.pop_peek();
1183 mtree_cache = self.next_token_value()?
1184 }
1185 _ => break,
1186 }
1187 }
1188 res.index = Index::MTree(crate::sql::index::MTreeParams::new(
1189 dimension,
1190 distance,
1191 vector_type,
1192 capacity,
1193 doc_ids_order,
1194 doc_ids_cache,
1195 mtree_cache,
1196 ))
1197 }
1198 t!("HNSW") => {
1199 self.pop_peek();
1200 expected!(self, t!("DIMENSION"));
1201 let dimension = self.next_token_value()?;
1202 let mut distance = Distance::Euclidean;
1203 let mut vector_type = VectorType::F64;
1204 let mut m = None;
1205 let mut m0 = None;
1206 let mut ml = None;
1207 let mut ef_construction = 150;
1208 let mut extend_candidates = false;
1209 let mut keep_pruned_connections = false;
1210 loop {
1211 match self.peek_kind() {
1212 t!("DISTANCE") => {
1213 self.pop_peek();
1214 distance = self.parse_distance()?;
1215 }
1216 t!("TYPE") => {
1217 self.pop_peek();
1218 vector_type = self.parse_vector_type()?;
1219 }
1220 t!("LM") => {
1221 self.pop_peek();
1222 ml = Some(self.next_token_value()?);
1223 }
1224 t!("M0") => {
1225 self.pop_peek();
1226 m0 = Some(self.next_token_value()?);
1227 }
1228 t!("M") => {
1229 self.pop_peek();
1230 m = Some(self.next_token_value()?);
1231 }
1232 t!("EFC") => {
1233 self.pop_peek();
1234 ef_construction = self.next_token_value()?;
1235 }
1236 t!("EXTEND_CANDIDATES") => {
1237 self.pop_peek();
1238 extend_candidates = true;
1239 }
1240 t!("KEEP_PRUNED_CONNECTIONS") => {
1241 self.pop_peek();
1242 keep_pruned_connections = true;
1243 }
1244 _ => {
1245 break;
1246 }
1247 }
1248 }
1249
1250 let m = m.unwrap_or(12);
1251 let m0 = m0.unwrap_or(m * 2);
1252 let ml = ml.unwrap_or(1.0 / (m as f64).ln()).into();
1253 res.index = Index::Hnsw(HnswParams::new(
1254 dimension,
1255 distance,
1256 vector_type,
1257 m,
1258 m0,
1259 ml,
1260 ef_construction,
1261 extend_candidates,
1262 keep_pruned_connections,
1263 ));
1264 }
1265 t!("CONCURRENTLY") => {
1266 self.pop_peek();
1267 res.concurrently = true;
1268 }
1269 t!("COMMENT") => {
1270 self.pop_peek();
1271 res.comment = Some(self.next_token_value()?);
1272 }
1273 _ => break,
1274 }
1275 }
1276
1277 Ok(res)
1278 }
1279
1280 pub fn parse_define_analyzer(&mut self) -> ParseResult<DefineAnalyzerStatement> {
1281 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1282 expected!(self, t!("NOT"));
1283 expected!(self, t!("EXISTS"));
1284 (true, false)
1285 } else if self.eat(t!("OVERWRITE")) {
1286 (false, true)
1287 } else {
1288 (false, false)
1289 };
1290 let name = self.next_token_value()?;
1291 let mut res = DefineAnalyzerStatement {
1292 name,
1293
1294 function: None,
1295 tokenizers: None,
1296 filters: None,
1297 comment: None,
1298
1299 if_not_exists,
1300 overwrite,
1301 };
1302 loop {
1303 match self.peek_kind() {
1304 t!("FILTERS") => {
1305 self.pop_peek();
1306 let mut filters = Vec::new();
1307 loop {
1308 let next = self.next();
1309 match next.kind {
1310 t!("ASCII") => {
1311 filters.push(Filter::Ascii);
1312 }
1313 t!("LOWERCASE") => {
1314 filters.push(Filter::Lowercase);
1315 }
1316 t!("UPPERCASE") => {
1317 filters.push(Filter::Uppercase);
1318 }
1319 t!("EDGENGRAM") => {
1320 let open_span = expected!(self, t!("(")).span;
1321 let a = self.next_token_value()?;
1322 expected!(self, t!(","));
1323 let b = self.next_token_value()?;
1324 self.expect_closing_delimiter(t!(")"), open_span)?;
1325 filters.push(Filter::EdgeNgram(a, b));
1326 }
1327 t!("NGRAM") => {
1328 let open_span = expected!(self, t!("(")).span;
1329 let a = self.next_token_value()?;
1330 expected!(self, t!(","));
1331 let b = self.next_token_value()?;
1332 self.expect_closing_delimiter(t!(")"), open_span)?;
1333 filters.push(Filter::Ngram(a, b));
1334 }
1335 t!("SNOWBALL") => {
1336 let open_span = expected!(self, t!("(")).span;
1337 let language = self.next_token_value()?;
1338 self.expect_closing_delimiter(t!(")"), open_span)?;
1339 filters.push(Filter::Snowball(language))
1340 }
1341 t!("MAPPER") => {
1342 let open_span = expected!(self, t!("(")).span;
1343 let path: Strand = self.next_token_value()?;
1344 self.expect_closing_delimiter(t!(")"), open_span)?;
1345 filters.push(Filter::Mapper(path.into()))
1346 }
1347 _ => unexpected!(self, next, "a filter"),
1348 }
1349 if !self.eat(t!(",")) {
1350 break;
1351 }
1352 }
1353 res.filters = Some(filters);
1354 }
1355 t!("TOKENIZERS") => {
1356 self.pop_peek();
1357 let mut tokenizers = Vec::new();
1358
1359 loop {
1360 let next = self.next();
1361 let tokenizer = match next.kind {
1362 t!("BLANK") => Tokenizer::Blank,
1363 t!("CAMEL") => Tokenizer::Camel,
1364 t!("CLASS") => Tokenizer::Class,
1365 t!("PUNCT") => Tokenizer::Punct,
1366 _ => unexpected!(self, next, "a tokenizer"),
1367 };
1368 tokenizers.push(tokenizer);
1369 if !self.eat(t!(",")) {
1370 break;
1371 }
1372 }
1373 res.tokenizers = Some(tokenizers);
1374 }
1375
1376 t!("FUNCTION") => {
1377 self.pop_peek();
1378 expected!(self, t!("fn"));
1379 expected!(self, t!("::"));
1380 let mut ident = self.next_token_value::<Ident>()?;
1381 while self.eat(t!("::")) {
1382 let value = self.next_token_value::<Ident>()?;
1383 ident.0.push_str("::");
1384 ident.0.push_str(&value);
1385 }
1386 res.function = Some(ident);
1387 }
1388 t!("COMMENT") => {
1389 self.pop_peek();
1390 res.comment = Some(self.next_token_value()?);
1391 }
1392 _ => break,
1393 }
1394 }
1395 Ok(res)
1396 }
1397
1398 pub async fn parse_define_config(
1399 &mut self,
1400 stk: &mut Stk,
1401 ) -> ParseResult<DefineConfigStatement> {
1402 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1403 expected!(self, t!("NOT"));
1404 expected!(self, t!("EXISTS"));
1405 (true, false)
1406 } else if self.eat(t!("OVERWRITE")) {
1407 (false, true)
1408 } else {
1409 (false, false)
1410 };
1411
1412 let next = self.next();
1413 let inner = match next.kind {
1414 t!("API") => self.parse_api_config(stk).await.map(ConfigInner::Api)?,
1415 t!("GRAPHQL") => self.parse_graphql_config().map(ConfigInner::GraphQL)?,
1416 _ => unexpected!(self, next, "a type of config"),
1417 };
1418
1419 Ok(DefineConfigStatement {
1420 inner,
1421 if_not_exists,
1422 overwrite,
1423 })
1424 }
1425
1426 pub async fn parse_api_config(&mut self, stk: &mut Stk) -> ParseResult<ApiConfig> {
1427 let mut config = ApiConfig::default();
1428 loop {
1429 match self.peek_kind() {
1430 t!("PERMISSIONS") => {
1431 self.pop_peek();
1432 config.permissions = Some(self.parse_permission_value(stk).await?);
1433 }
1434 t!("MIDDLEWARE") => {
1435 self.pop_peek();
1436
1437 let mut middleware: Vec<(String, Vec<Value>)> = Vec::new();
1438 loop {
1441 let mut name = match self.peek_kind() {
1442 t!("API") => {
1443 self.pop_peek();
1448 expected!(self, t!("::"));
1449 "api::".to_string()
1450 }
1451 t!("fn") => {
1452 bail!("Custom middlewares are not yet supported")
1453 }
1454 _ => {
1455 break;
1456 }
1457 };
1458
1459 let part = self.next_token_value::<Ident>()?;
1460 name.push_str(part.0.to_lowercase().as_str());
1461
1462 while self.eat(t!("::")) {
1463 let part = self.next_token_value::<Ident>()?;
1464 name.push_str("::");
1465 name.push_str(part.0.to_lowercase().as_str());
1466 }
1467
1468 expected!(self, t!("("));
1469 let args = self.parse_function_args(stk).await?;
1470
1471 middleware.push((name, args));
1472
1473 if !self.eat(t!(",")) {
1474 break;
1475 }
1476 }
1477
1478 config.middleware = Some(RequestMiddleware(middleware));
1479 }
1480 _ => {
1481 break;
1482 }
1483 }
1484 }
1485 Ok(config)
1486 }
1487
1488 fn parse_graphql_config(&mut self) -> ParseResult<GraphQLConfig> {
1489 use graphql::{FunctionsConfig, TablesConfig};
1490 let mut tmp_tables = Option::<TablesConfig>::None;
1491 let mut tmp_fncs = Option::<FunctionsConfig>::None;
1492 loop {
1493 match self.peek_kind() {
1494 t!("NONE") => {
1495 self.pop_peek();
1496 tmp_tables = Some(TablesConfig::None);
1497 tmp_fncs = Some(FunctionsConfig::None);
1498 }
1499 t!("AUTO") => {
1500 self.pop_peek();
1501 tmp_tables = Some(TablesConfig::Auto);
1502 tmp_fncs = Some(FunctionsConfig::Auto);
1503 }
1504 t!("TABLES") => {
1505 self.pop_peek();
1506
1507 let next = self.next();
1508 match next.kind {
1509 t!("INCLUDE") => {
1510 tmp_tables =
1511 Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1512 }
1513 t!("EXCLUDE") => {
1514 tmp_tables =
1515 Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1516 }
1517 t!("NONE") => {
1518 tmp_tables = Some(TablesConfig::None);
1519 }
1520 t!("AUTO") => {
1521 tmp_tables = Some(TablesConfig::Auto);
1522 }
1523 _ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1524 }
1525 }
1526 t!("FUNCTIONS") => {
1527 self.pop_peek();
1528
1529 let next = self.next();
1530 match next.kind {
1531 t!("INCLUDE") => {}
1532 t!("EXCLUDE") => {}
1533 t!("NONE") => {
1534 tmp_fncs = Some(FunctionsConfig::None);
1535 }
1536 t!("AUTO") => {
1537 tmp_fncs = Some(FunctionsConfig::Auto);
1538 }
1539 _ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1540 }
1541 }
1542 _ => break,
1543 }
1544 }
1545
1546 Ok(GraphQLConfig {
1547 tables: tmp_tables.unwrap_or_default(),
1548 functions: tmp_fncs.unwrap_or_default(),
1549 })
1550 }
1551
1552 fn parse_graphql_table_configs(&mut self) -> ParseResult<Vec<graphql::TableConfig>> {
1553 let mut acc = vec![];
1554 loop {
1555 match self.peek_kind() {
1556 x if Self::kind_is_identifier(x) => {
1557 let name: Ident = self.next_token_value()?;
1558 acc.push(TableConfig {
1559 name: name.0,
1560 });
1561 }
1562 _ => unexpected!(self, self.next(), "a table config"),
1563 }
1564 if !self.eat(t!(",")) {
1565 break;
1566 }
1567 }
1568 Ok(acc)
1569 }
1570
1571 pub fn parse_relation_schema(&mut self) -> ParseResult<table_type::Relation> {
1572 let mut res = table_type::Relation {
1573 from: None,
1574 to: None,
1575 enforced: false,
1576 };
1577 loop {
1578 match self.peek_kind() {
1579 t!("FROM") | t!("IN") => {
1580 self.pop_peek();
1581 let from = self.parse_tables()?;
1582 res.from = Some(from);
1583 }
1584 t!("TO") | t!("OUT") => {
1585 self.pop_peek();
1586 let to = self.parse_tables()?;
1587 res.to = Some(to);
1588 }
1589 _ => break,
1590 }
1591 }
1592 if self.eat(t!("ENFORCED")) {
1593 res.enforced = true;
1594 }
1595 Ok(res)
1596 }
1597
1598 pub fn parse_tables(&mut self) -> ParseResult<Kind> {
1599 let mut names = vec![self.next_token_value()?];
1600 while self.eat(t!("|")) {
1601 names.push(self.next_token_value()?);
1602 }
1603 Ok(Kind::Record(names))
1604 }
1605
1606 pub fn parse_jwt(&mut self) -> ParseResult<access_type::JwtAccess> {
1607 let mut res = access_type::JwtAccess {
1608 issue: None,
1610 ..Default::default()
1611 };
1612
1613 let mut iss = access_type::JwtAccessIssue {
1614 ..Default::default()
1615 };
1616
1617 let peek = self.peek();
1618 match peek.kind {
1619 t!("ALGORITHM") => {
1620 self.pop_peek();
1621 let next = self.next();
1622 match next.kind {
1623 TokenKind::Algorithm(alg) => {
1624 let next = self.next();
1625 match next.kind {
1626 t!("KEY") => {
1627 let key = self.next_token_value::<Strand>()?.0;
1628 res.verify = access_type::JwtAccessVerify::Key(
1629 access_type::JwtAccessVerifyKey {
1630 alg,
1631 key: key.to_owned(),
1632 },
1633 );
1634
1635 iss.alg = alg;
1637
1638 if alg.is_symmetric() {
1641 iss.key = key;
1642 res.issue = Some(iss.clone());
1645 }
1646 }
1647 _ => unexpected!(self, next, "a key"),
1648 }
1649 }
1650 _ => unexpected!(self, next, "a valid algorithm"),
1651 }
1652 }
1653 t!("URL") => {
1654 self.pop_peek();
1655 let url = self.next_token_value::<Strand>()?.0;
1656 res.verify = access_type::JwtAccessVerify::Jwks(access_type::JwtAccessVerifyJwks {
1657 url,
1658 });
1659 }
1660 _ => unexpected!(self, peek, "`ALGORITHM`, or `URL`"),
1661 }
1662
1663 if self.eat(t!("WITH")) {
1664 expected!(self, t!("ISSUER"));
1665 loop {
1666 let peek = self.peek();
1667 match peek.kind {
1668 t!("ALGORITHM") => {
1669 self.pop_peek();
1670 let next = self.next();
1671 match next.kind {
1672 TokenKind::Algorithm(alg) => {
1673 if let JwtAccessVerify::Key(ref ver) = res.verify {
1675 if alg != ver.alg {
1676 unexpected!(
1677 self,
1678 next,
1679 "a compatible algorithm or no algorithm"
1680 );
1681 }
1682 }
1683 iss.alg = alg;
1684 }
1685 _ => unexpected!(self, next, "a valid algorithm"),
1686 }
1687 }
1688 t!("KEY") => {
1689 self.pop_peek();
1690 let key = self.next_token_value::<Strand>()?.0;
1691 if let JwtAccessVerify::Key(ref ver) = res.verify {
1693 if ver.alg.is_symmetric() && key != ver.key {
1694 unexpected!(self, peek, "a symmetric key or no key");
1695 }
1696 }
1697 iss.key = key;
1698 }
1699 _ => break,
1700 }
1701 }
1702 res.issue = Some(iss);
1703 }
1704
1705 Ok(res)
1706 }
1707}