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!("COUNT") => {
1056 self.pop_peek();
1057 res.index = Index::Count;
1058 }
1059 t!("SEARCH") => {
1060 self.pop_peek();
1061 let mut analyzer: Option<Ident> = None;
1062 let mut scoring = None;
1063 let mut doc_ids_order = 100;
1064 let mut doc_lengths_order = 100;
1065 let mut postings_order = 100;
1066 let mut terms_order = 100;
1067 let mut doc_ids_cache = 100;
1068 let mut doc_lengths_cache = 100;
1069 let mut postings_cache = 100;
1070 let mut terms_cache = 100;
1071 let mut hl = false;
1072
1073 loop {
1074 match self.peek_kind() {
1075 t!("ANALYZER") => {
1076 self.pop_peek();
1077 analyzer = Some(self.next_token_value()).transpose()?;
1078 }
1079 t!("VS") => {
1080 self.pop_peek();
1081 scoring = Some(Scoring::Vs);
1082 }
1083 t!("BM25") => {
1084 self.pop_peek();
1085 if self.eat(t!("(")) {
1086 let open = self.last_span();
1087 let k1 = self.next_token_value()?;
1088 expected!(self, t!(","));
1089 let b = self.next_token_value()?;
1090 self.expect_closing_delimiter(t!(")"), open)?;
1091 scoring = Some(Scoring::Bm {
1092 k1,
1093 b,
1094 })
1095 } else {
1096 scoring = Some(Default::default());
1097 };
1098 }
1099 t!("DOC_IDS_ORDER") => {
1100 self.pop_peek();
1101 doc_ids_order = self.next_token_value()?;
1102 }
1103 t!("DOC_LENGTHS_ORDER") => {
1104 self.pop_peek();
1105 doc_lengths_order = self.next_token_value()?;
1106 }
1107 t!("POSTINGS_ORDER") => {
1108 self.pop_peek();
1109 postings_order = self.next_token_value()?;
1110 }
1111 t!("TERMS_ORDER") => {
1112 self.pop_peek();
1113 terms_order = self.next_token_value()?;
1114 }
1115 t!("DOC_IDS_CACHE") => {
1116 self.pop_peek();
1117 doc_ids_cache = self.next_token_value()?;
1118 }
1119 t!("DOC_LENGTHS_CACHE") => {
1120 self.pop_peek();
1121 doc_lengths_cache = self.next_token_value()?;
1122 }
1123 t!("POSTINGS_CACHE") => {
1124 self.pop_peek();
1125 postings_cache = self.next_token_value()?;
1126 }
1127 t!("TERMS_CACHE") => {
1128 self.pop_peek();
1129 terms_cache = self.next_token_value()?;
1130 }
1131 t!("HIGHLIGHTS") => {
1132 self.pop_peek();
1133 hl = true;
1134 }
1135 _ => break,
1136 }
1137 }
1138
1139 res.index = Index::Search(crate::sql::index::SearchParams {
1140 az: analyzer.unwrap_or_else(|| Ident::from("like")),
1141 sc: scoring.unwrap_or_else(Default::default),
1142 hl,
1143 doc_ids_order,
1144 doc_lengths_order,
1145 postings_order,
1146 terms_order,
1147 doc_ids_cache,
1148 doc_lengths_cache,
1149 postings_cache,
1150 terms_cache,
1151 });
1152 }
1153 t!("MTREE") => {
1154 self.pop_peek();
1155 expected!(self, t!("DIMENSION"));
1156 let dimension = self.next_token_value()?;
1157 let mut distance = Distance::Euclidean;
1158 let mut vector_type = VectorType::F64;
1159 let mut capacity = 40;
1160 let mut doc_ids_cache = 100;
1161 let mut doc_ids_order = 100;
1162 let mut mtree_cache = 100;
1163 loop {
1164 match self.peek_kind() {
1165 t!("DISTANCE") => {
1166 self.pop_peek();
1167 distance = self.parse_distance()?
1168 }
1169 t!("TYPE") => {
1170 self.pop_peek();
1171 vector_type = self.parse_vector_type()?
1172 }
1173 t!("CAPACITY") => {
1174 self.pop_peek();
1175 capacity = self.next_token_value()?
1176 }
1177 t!("DOC_IDS_CACHE") => {
1178 self.pop_peek();
1179 doc_ids_cache = self.next_token_value()?
1180 }
1181 t!("DOC_IDS_ORDER") => {
1182 self.pop_peek();
1183 doc_ids_order = self.next_token_value()?
1184 }
1185 t!("MTREE_CACHE") => {
1186 self.pop_peek();
1187 mtree_cache = self.next_token_value()?
1188 }
1189 _ => break,
1190 }
1191 }
1192 res.index = Index::MTree(crate::sql::index::MTreeParams::new(
1193 dimension,
1194 distance,
1195 vector_type,
1196 capacity,
1197 doc_ids_order,
1198 doc_ids_cache,
1199 mtree_cache,
1200 ))
1201 }
1202 t!("HNSW") => {
1203 self.pop_peek();
1204 expected!(self, t!("DIMENSION"));
1205 let dimension = self.next_token_value()?;
1206 let mut distance = Distance::Euclidean;
1207 let mut vector_type = VectorType::F32;
1208 let mut m = None;
1209 let mut m0 = None;
1210 let mut ml = None;
1211 let mut ef_construction = 150;
1212 let mut extend_candidates = false;
1213 let mut keep_pruned_connections = false;
1214 loop {
1215 match self.peek_kind() {
1216 t!("DISTANCE") => {
1217 self.pop_peek();
1218 distance = self.parse_distance()?;
1219 }
1220 t!("TYPE") => {
1221 self.pop_peek();
1222 vector_type = self.parse_vector_type()?;
1223 }
1224 t!("LM") => {
1225 self.pop_peek();
1226 ml = Some(self.next_token_value()?);
1227 }
1228 t!("M0") => {
1229 self.pop_peek();
1230 m0 = Some(self.next_token_value()?);
1231 }
1232 t!("M") => {
1233 self.pop_peek();
1234 m = Some(self.next_token_value()?);
1235 }
1236 t!("EFC") => {
1237 self.pop_peek();
1238 ef_construction = self.next_token_value()?;
1239 }
1240 t!("EXTEND_CANDIDATES") => {
1241 self.pop_peek();
1242 extend_candidates = true;
1243 }
1244 t!("KEEP_PRUNED_CONNECTIONS") => {
1245 self.pop_peek();
1246 keep_pruned_connections = true;
1247 }
1248 _ => {
1249 break;
1250 }
1251 }
1252 }
1253
1254 let m = m.unwrap_or(12);
1255 let m0 = m0.unwrap_or(m * 2);
1256 let ml = ml.unwrap_or(1.0 / (m as f64).ln()).into();
1257 res.index = Index::Hnsw(HnswParams::new(
1258 dimension,
1259 distance,
1260 vector_type,
1261 m,
1262 m0,
1263 ml,
1264 ef_construction,
1265 extend_candidates,
1266 keep_pruned_connections,
1267 ));
1268 }
1269 t!("CONCURRENTLY") => {
1270 self.pop_peek();
1271 res.concurrently = true;
1272 }
1273 t!("COMMENT") => {
1274 self.pop_peek();
1275 res.comment = Some(self.next_token_value()?);
1276 }
1277 _ => break,
1278 }
1279 }
1280 if matches!(res.index, Index::Count) && !res.cols.is_empty() {
1281 bail!("Cannot create a count index with fields");
1282 }
1283 Ok(res)
1284 }
1285
1286 pub fn parse_define_analyzer(&mut self) -> ParseResult<DefineAnalyzerStatement> {
1287 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1288 expected!(self, t!("NOT"));
1289 expected!(self, t!("EXISTS"));
1290 (true, false)
1291 } else if self.eat(t!("OVERWRITE")) {
1292 (false, true)
1293 } else {
1294 (false, false)
1295 };
1296 let name = self.next_token_value()?;
1297 let mut res = DefineAnalyzerStatement {
1298 name,
1299
1300 function: None,
1301 tokenizers: None,
1302 filters: None,
1303 comment: None,
1304
1305 if_not_exists,
1306 overwrite,
1307 };
1308 loop {
1309 match self.peek_kind() {
1310 t!("FILTERS") => {
1311 self.pop_peek();
1312 let mut filters = Vec::new();
1313 loop {
1314 let next = self.next();
1315 match next.kind {
1316 t!("ASCII") => {
1317 filters.push(Filter::Ascii);
1318 }
1319 t!("LOWERCASE") => {
1320 filters.push(Filter::Lowercase);
1321 }
1322 t!("UPPERCASE") => {
1323 filters.push(Filter::Uppercase);
1324 }
1325 t!("EDGENGRAM") => {
1326 let open_span = expected!(self, t!("(")).span;
1327 let a = self.next_token_value()?;
1328 expected!(self, t!(","));
1329 let b = self.next_token_value()?;
1330 self.expect_closing_delimiter(t!(")"), open_span)?;
1331 filters.push(Filter::EdgeNgram(a, b));
1332 }
1333 t!("NGRAM") => {
1334 let open_span = expected!(self, t!("(")).span;
1335 let a = self.next_token_value()?;
1336 expected!(self, t!(","));
1337 let b = self.next_token_value()?;
1338 self.expect_closing_delimiter(t!(")"), open_span)?;
1339 filters.push(Filter::Ngram(a, b));
1340 }
1341 t!("SNOWBALL") => {
1342 let open_span = expected!(self, t!("(")).span;
1343 let language = self.next_token_value()?;
1344 self.expect_closing_delimiter(t!(")"), open_span)?;
1345 filters.push(Filter::Snowball(language))
1346 }
1347 t!("MAPPER") => {
1348 let open_span = expected!(self, t!("(")).span;
1349 let path: Strand = self.next_token_value()?;
1350 self.expect_closing_delimiter(t!(")"), open_span)?;
1351 filters.push(Filter::Mapper(path.into()))
1352 }
1353 _ => unexpected!(self, next, "a filter"),
1354 }
1355 if !self.eat(t!(",")) {
1356 break;
1357 }
1358 }
1359 res.filters = Some(filters);
1360 }
1361 t!("TOKENIZERS") => {
1362 self.pop_peek();
1363 let mut tokenizers = Vec::new();
1364
1365 loop {
1366 let next = self.next();
1367 let tokenizer = match next.kind {
1368 t!("BLANK") => Tokenizer::Blank,
1369 t!("CAMEL") => Tokenizer::Camel,
1370 t!("CLASS") => Tokenizer::Class,
1371 t!("PUNCT") => Tokenizer::Punct,
1372 _ => unexpected!(self, next, "a tokenizer"),
1373 };
1374 tokenizers.push(tokenizer);
1375 if !self.eat(t!(",")) {
1376 break;
1377 }
1378 }
1379 res.tokenizers = Some(tokenizers);
1380 }
1381
1382 t!("FUNCTION") => {
1383 self.pop_peek();
1384 expected!(self, t!("fn"));
1385 expected!(self, t!("::"));
1386 let mut ident = self.next_token_value::<Ident>()?;
1387 while self.eat(t!("::")) {
1388 let value = self.next_token_value::<Ident>()?;
1389 ident.0.push_str("::");
1390 ident.0.push_str(&value);
1391 }
1392 res.function = Some(ident);
1393 }
1394 t!("COMMENT") => {
1395 self.pop_peek();
1396 res.comment = Some(self.next_token_value()?);
1397 }
1398 _ => break,
1399 }
1400 }
1401 Ok(res)
1402 }
1403
1404 pub async fn parse_define_config(
1405 &mut self,
1406 stk: &mut Stk,
1407 ) -> ParseResult<DefineConfigStatement> {
1408 let (if_not_exists, overwrite) = if self.eat(t!("IF")) {
1409 expected!(self, t!("NOT"));
1410 expected!(self, t!("EXISTS"));
1411 (true, false)
1412 } else if self.eat(t!("OVERWRITE")) {
1413 (false, true)
1414 } else {
1415 (false, false)
1416 };
1417
1418 let next = self.next();
1419 let inner = match next.kind {
1420 t!("API") => self.parse_api_config(stk).await.map(ConfigInner::Api)?,
1421 t!("GRAPHQL") => self.parse_graphql_config().map(ConfigInner::GraphQL)?,
1422 _ => unexpected!(self, next, "a type of config"),
1423 };
1424
1425 Ok(DefineConfigStatement {
1426 inner,
1427 if_not_exists,
1428 overwrite,
1429 })
1430 }
1431
1432 pub async fn parse_api_config(&mut self, stk: &mut Stk) -> ParseResult<ApiConfig> {
1433 let mut config = ApiConfig::default();
1434 loop {
1435 match self.peek_kind() {
1436 t!("PERMISSIONS") => {
1437 self.pop_peek();
1438 config.permissions = Some(self.parse_permission_value(stk).await?);
1439 }
1440 t!("MIDDLEWARE") => {
1441 self.pop_peek();
1442
1443 let mut middleware: Vec<(String, Vec<Value>)> = Vec::new();
1444 loop {
1447 let mut name = match self.peek_kind() {
1448 t!("API") => {
1449 self.pop_peek();
1454 expected!(self, t!("::"));
1455 "api::".to_string()
1456 }
1457 t!("fn") => {
1458 bail!("Custom middlewares are not yet supported")
1459 }
1460 _ => {
1461 break;
1462 }
1463 };
1464
1465 let part = self.next_token_value::<Ident>()?;
1466 name.push_str(part.0.to_lowercase().as_str());
1467
1468 while self.eat(t!("::")) {
1469 let part = self.next_token_value::<Ident>()?;
1470 name.push_str("::");
1471 name.push_str(part.0.to_lowercase().as_str());
1472 }
1473
1474 expected!(self, t!("("));
1475 let args = self.parse_function_args(stk).await?;
1476
1477 middleware.push((name, args));
1478
1479 if !self.eat(t!(",")) {
1480 break;
1481 }
1482 }
1483
1484 config.middleware = Some(RequestMiddleware(middleware));
1485 }
1486 _ => {
1487 break;
1488 }
1489 }
1490 }
1491 Ok(config)
1492 }
1493
1494 fn parse_graphql_config(&mut self) -> ParseResult<GraphQLConfig> {
1495 use graphql::{FunctionsConfig, TablesConfig};
1496 let mut tmp_tables = Option::<TablesConfig>::None;
1497 let mut tmp_fncs = Option::<FunctionsConfig>::None;
1498 loop {
1499 match self.peek_kind() {
1500 t!("NONE") => {
1501 self.pop_peek();
1502 tmp_tables = Some(TablesConfig::None);
1503 tmp_fncs = Some(FunctionsConfig::None);
1504 }
1505 t!("AUTO") => {
1506 self.pop_peek();
1507 tmp_tables = Some(TablesConfig::Auto);
1508 tmp_fncs = Some(FunctionsConfig::Auto);
1509 }
1510 t!("TABLES") => {
1511 self.pop_peek();
1512
1513 let next = self.next();
1514 match next.kind {
1515 t!("INCLUDE") => {
1516 tmp_tables =
1517 Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1518 }
1519 t!("EXCLUDE") => {
1520 tmp_tables =
1521 Some(TablesConfig::Include(self.parse_graphql_table_configs()?))
1522 }
1523 t!("NONE") => {
1524 tmp_tables = Some(TablesConfig::None);
1525 }
1526 t!("AUTO") => {
1527 tmp_tables = Some(TablesConfig::Auto);
1528 }
1529 _ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1530 }
1531 }
1532 t!("FUNCTIONS") => {
1533 self.pop_peek();
1534
1535 let next = self.next();
1536 match next.kind {
1537 t!("INCLUDE") => {}
1538 t!("EXCLUDE") => {}
1539 t!("NONE") => {
1540 tmp_fncs = Some(FunctionsConfig::None);
1541 }
1542 t!("AUTO") => {
1543 tmp_fncs = Some(FunctionsConfig::Auto);
1544 }
1545 _ => unexpected!(self, next, "`NONE`, `AUTO`, `INCLUDE` or `EXCLUDE`"),
1546 }
1547 }
1548 _ => break,
1549 }
1550 }
1551
1552 Ok(GraphQLConfig {
1553 tables: tmp_tables.unwrap_or_default(),
1554 functions: tmp_fncs.unwrap_or_default(),
1555 })
1556 }
1557
1558 fn parse_graphql_table_configs(&mut self) -> ParseResult<Vec<graphql::TableConfig>> {
1559 let mut acc = vec![];
1560 loop {
1561 match self.peek_kind() {
1562 x if Self::kind_is_identifier(x) => {
1563 let name: Ident = self.next_token_value()?;
1564 acc.push(TableConfig {
1565 name: name.0,
1566 });
1567 }
1568 _ => unexpected!(self, self.next(), "a table config"),
1569 }
1570 if !self.eat(t!(",")) {
1571 break;
1572 }
1573 }
1574 Ok(acc)
1575 }
1576
1577 pub fn parse_relation_schema(&mut self) -> ParseResult<table_type::Relation> {
1578 let mut res = table_type::Relation {
1579 from: None,
1580 to: None,
1581 enforced: false,
1582 };
1583 loop {
1584 match self.peek_kind() {
1585 t!("FROM") | t!("IN") => {
1586 self.pop_peek();
1587 let from = self.parse_tables()?;
1588 res.from = Some(from);
1589 }
1590 t!("TO") | t!("OUT") => {
1591 self.pop_peek();
1592 let to = self.parse_tables()?;
1593 res.to = Some(to);
1594 }
1595 _ => break,
1596 }
1597 }
1598 if self.eat(t!("ENFORCED")) {
1599 res.enforced = true;
1600 }
1601 Ok(res)
1602 }
1603
1604 pub fn parse_tables(&mut self) -> ParseResult<Kind> {
1605 let mut names = vec![self.next_token_value()?];
1606 while self.eat(t!("|")) {
1607 names.push(self.next_token_value()?);
1608 }
1609 Ok(Kind::Record(names))
1610 }
1611
1612 pub fn parse_jwt(&mut self) -> ParseResult<access_type::JwtAccess> {
1613 let mut res = access_type::JwtAccess {
1614 issue: None,
1616 ..Default::default()
1617 };
1618
1619 let mut iss = access_type::JwtAccessIssue {
1620 ..Default::default()
1621 };
1622
1623 let peek = self.peek();
1624 match peek.kind {
1625 t!("ALGORITHM") => {
1626 self.pop_peek();
1627 let next = self.next();
1628 match next.kind {
1629 TokenKind::Algorithm(alg) => {
1630 let next = self.next();
1631 match next.kind {
1632 t!("KEY") => {
1633 let key = self.next_token_value::<Strand>()?.0;
1634 res.verify = access_type::JwtAccessVerify::Key(
1635 access_type::JwtAccessVerifyKey {
1636 alg,
1637 key: key.to_owned(),
1638 },
1639 );
1640
1641 iss.alg = alg;
1643
1644 if alg.is_symmetric() {
1647 iss.key = key;
1648 res.issue = Some(iss.clone());
1651 }
1652 }
1653 _ => unexpected!(self, next, "a key"),
1654 }
1655 }
1656 _ => unexpected!(self, next, "a valid algorithm"),
1657 }
1658 }
1659 t!("URL") => {
1660 self.pop_peek();
1661 let url = self.next_token_value::<Strand>()?.0;
1662 res.verify = access_type::JwtAccessVerify::Jwks(access_type::JwtAccessVerifyJwks {
1663 url,
1664 });
1665 }
1666 _ => unexpected!(self, peek, "`ALGORITHM`, or `URL`"),
1667 }
1668
1669 if self.eat(t!("WITH")) {
1670 expected!(self, t!("ISSUER"));
1671 loop {
1672 let peek = self.peek();
1673 match peek.kind {
1674 t!("ALGORITHM") => {
1675 self.pop_peek();
1676 let next = self.next();
1677 match next.kind {
1678 TokenKind::Algorithm(alg) => {
1679 if let JwtAccessVerify::Key(ref ver) = res.verify {
1681 if alg != ver.alg {
1682 unexpected!(
1683 self,
1684 next,
1685 "a compatible algorithm or no algorithm"
1686 );
1687 }
1688 }
1689 iss.alg = alg;
1690 }
1691 _ => unexpected!(self, next, "a valid algorithm"),
1692 }
1693 }
1694 t!("KEY") => {
1695 self.pop_peek();
1696 let key = self.next_token_value::<Strand>()?.0;
1697 if let JwtAccessVerify::Key(ref ver) = res.verify {
1699 if ver.alg.is_symmetric() && key != ver.key {
1700 unexpected!(self, peek, "a symmetric key or no key");
1701 }
1702 }
1703 iss.key = key;
1704 }
1705 _ => break,
1706 }
1707 }
1708 res.issue = Some(iss);
1709 }
1710
1711 Ok(res)
1712 }
1713}