1use crate::manifest::ast::ValueKind;
2use crate::manifest::ast::*;
3use crate::manifest::compiler::CompileErrorDiagnosticsStyle;
4use crate::manifest::diagnostic_snippets::create_snippet;
5use crate::manifest::manifest_enums::KNOWN_ENUM_DISCRIMINATORS;
6use crate::manifest::token::{Position, Span, Token, TokenWithSpan};
7use crate::manifest::*;
8use radix_common::data::manifest::MANIFEST_SBOR_V1_MAX_DEPTH;
9use sbor::prelude::*;
10
11pub const PARSER_MAX_DEPTH: usize = MANIFEST_SBOR_V1_MAX_DEPTH - 4;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum ParserErrorKind {
17 UnexpectedEof,
18 UnexpectedToken { expected: TokenType, actual: Token },
19 InvalidArgument { expected: TokenType, actual: Token },
20 InvalidNumberOfValues { expected: usize, actual: usize },
21 InvalidNumberOfTypes { expected: usize, actual: usize },
22 UnknownEnumDiscriminator { actual: String },
23 MaxDepthExceeded { actual: usize, max: usize },
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct ParserError {
28 pub error_kind: ParserErrorKind,
29 pub span: Span,
30}
31
32impl ParserError {
33 fn unexpected_token(token: TokenWithSpan, expected: TokenType) -> Self {
34 Self {
35 error_kind: ParserErrorKind::UnexpectedToken {
36 expected,
37 actual: token.token,
38 },
39 span: token.span,
40 }
41 }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub enum TokenType {
46 Instruction,
47 Value,
48 ValueKind,
49 EnumDiscriminator,
50 Exact(Token),
51}
52
53impl fmt::Display for TokenType {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 match self {
56 TokenType::Instruction => write!(f, "an instruction"),
57 TokenType::Value => write!(f, "a manifest SBOR value"),
58 TokenType::ValueKind => write!(f, "a manifest SBOR value kind"),
59 TokenType::EnumDiscriminator => {
60 write!(f, "a u8 enum discriminator or valid discriminator alias")
61 }
62 TokenType::Exact(token) => write!(f, "exactly {}", token),
63 }
64 }
65}
66
67pub enum InstructionIdent {
68 UsePreallocatedAddress,
72 UseChild,
73
74 TakeFromWorktop,
80 TakeNonFungiblesFromWorktop,
81 TakeAllFromWorktop,
82 ReturnToWorktop,
83 BurnResource,
84
85 AssertWorktopContainsAny,
87 AssertWorktopContains,
88 AssertWorktopContainsNonFungibles,
89 AssertWorktopIsEmpty, AssertWorktopResourcesOnly,
91 AssertWorktopResourcesInclude,
92 AssertNextCallReturnsOnly,
93 AssertNextCallReturnsInclude,
94 AssertBucketContents,
95
96 CreateProofFromBucketOfAmount,
98 CreateProofFromBucketOfNonFungibles,
99 CreateProofFromBucketOfAll,
100 CreateProofFromAuthZoneOfAmount,
101 CreateProofFromAuthZoneOfNonFungibles,
102 CreateProofFromAuthZoneOfAll,
103 CloneProof,
104 DropProof,
105 PushToAuthZone,
106 PopFromAuthZone,
107 DropAuthZoneProofs,
108 DropAuthZoneRegularProofs,
109 DropAuthZoneSignatureProofs,
110 DropNamedProofs,
111 DropAllProofs,
112
113 CallFunction,
115 CallMethod,
116 CallRoyaltyMethod,
117 CallMetadataMethod,
118 CallRoleAssignmentMethod,
119 CallDirectVaultMethod,
120
121 AllocateGlobalAddress,
123
124 YieldToParent,
126 YieldToChild,
127 VerifyParent,
128
129 RecallFromVault,
133 FreezeVault,
134 UnfreezeVault,
135 RecallNonFungiblesFromVault,
136
137 PublishPackage,
141 PublishPackageAdvanced,
142 CreateFungibleResource,
143 CreateFungibleResourceWithInitialSupply,
144 CreateNonFungibleResource,
145 CreateNonFungibleResourceWithInitialSupply,
146 CreateAccessController,
147 CreateIdentity,
148 CreateIdentityAdvanced,
149 CreateAccount,
150 CreateAccountAdvanced,
151
152 SetMetadata,
156 RemoveMetadata,
157 LockMetadata,
158 SetComponentRoyalty,
159 LockComponentRoyalty,
160 ClaimComponentRoyalties,
161 SetOwnerRole,
162 LockOwnerRole,
163 SetRole,
164
165 ClaimPackageRoyalties,
169 MintFungible,
170 MintNonFungible,
171 MintRuidNonFungible,
172 CreateValidator,
173}
174
175impl InstructionIdent {
176 pub fn from_ident(ident: &str) -> Option<Self> {
177 let value = match ident {
178 "USE_CHILD" => InstructionIdent::UseChild,
182 "USE_PREALLOCATED_ADDRESS" => InstructionIdent::UsePreallocatedAddress,
183
184 TakeFromWorktop::IDENT => InstructionIdent::TakeFromWorktop,
190 TakeNonFungiblesFromWorktop::IDENT => InstructionIdent::TakeNonFungiblesFromWorktop,
191 TakeAllFromWorktop::IDENT => InstructionIdent::TakeAllFromWorktop,
192 ReturnToWorktop::IDENT => InstructionIdent::ReturnToWorktop,
193 BurnResource::IDENT => InstructionIdent::BurnResource,
194
195 AssertWorktopContains::IDENT => InstructionIdent::AssertWorktopContains,
197 AssertWorktopContainsNonFungibles::IDENT => {
198 InstructionIdent::AssertWorktopContainsNonFungibles
199 }
200 AssertWorktopContainsAny::IDENT => InstructionIdent::AssertWorktopContainsAny,
201 "ASSERT_WORKTOP_IS_EMPTY" => InstructionIdent::AssertWorktopIsEmpty,
202 AssertWorktopResourcesOnly::IDENT => InstructionIdent::AssertWorktopResourcesOnly,
203 AssertWorktopResourcesInclude::IDENT => InstructionIdent::AssertWorktopResourcesInclude,
204 AssertNextCallReturnsOnly::IDENT => InstructionIdent::AssertNextCallReturnsOnly,
205 AssertNextCallReturnsInclude::IDENT => InstructionIdent::AssertNextCallReturnsInclude,
206 AssertBucketContents::IDENT => InstructionIdent::AssertBucketContents,
207
208 CreateProofFromBucketOfAmount::IDENT => InstructionIdent::CreateProofFromBucketOfAmount,
210 CreateProofFromBucketOfNonFungibles::IDENT => {
211 InstructionIdent::CreateProofFromBucketOfNonFungibles
212 }
213 CreateProofFromBucketOfAll::IDENT => InstructionIdent::CreateProofFromBucketOfAll,
214 CreateProofFromAuthZoneOfAmount::IDENT => {
215 InstructionIdent::CreateProofFromAuthZoneOfAmount
216 }
217 CreateProofFromAuthZoneOfNonFungibles::IDENT => {
218 InstructionIdent::CreateProofFromAuthZoneOfNonFungibles
219 }
220 CreateProofFromAuthZoneOfAll::IDENT => InstructionIdent::CreateProofFromAuthZoneOfAll,
221 CloneProof::IDENT => InstructionIdent::CloneProof,
222 DropProof::IDENT => InstructionIdent::DropProof,
223 PushToAuthZone::IDENT => InstructionIdent::PushToAuthZone,
224 PopFromAuthZone::IDENT => InstructionIdent::PopFromAuthZone,
225 DropAuthZoneProofs::IDENT => InstructionIdent::DropAuthZoneProofs,
226 DropAuthZoneSignatureProofs::IDENT => InstructionIdent::DropAuthZoneSignatureProofs,
227 DropAuthZoneRegularProofs::IDENT => InstructionIdent::DropAuthZoneRegularProofs,
228 DropNamedProofs::IDENT => InstructionIdent::DropNamedProofs,
229 DropAllProofs::IDENT => InstructionIdent::DropAllProofs,
230
231 CallFunction::IDENT => InstructionIdent::CallFunction,
233 CallMethod::IDENT => InstructionIdent::CallMethod,
234 CallRoyaltyMethod::IDENT => InstructionIdent::CallRoyaltyMethod,
235 CallMetadataMethod::IDENT => InstructionIdent::CallMetadataMethod,
236 CallRoleAssignmentMethod::IDENT => InstructionIdent::CallRoleAssignmentMethod,
237 CallDirectVaultMethod::IDENT => InstructionIdent::CallDirectVaultMethod,
238
239 AllocateGlobalAddress::IDENT => InstructionIdent::AllocateGlobalAddress,
241
242 YieldToParent::IDENT => InstructionIdent::YieldToParent,
244 YieldToChild::IDENT => InstructionIdent::YieldToChild,
245 VerifyParent::IDENT => InstructionIdent::VerifyParent,
246
247 "RECALL_FROM_VAULT" => InstructionIdent::RecallFromVault,
251 "FREEZE_VAULT" => InstructionIdent::FreezeVault,
252 "UNFREEZE_VAULT" => InstructionIdent::UnfreezeVault,
253 "RECALL_NON_FUNGIBLES_FROM_VAULT" => InstructionIdent::RecallNonFungiblesFromVault,
254
255 "PUBLISH_PACKAGE" => InstructionIdent::PublishPackage,
259 "PUBLISH_PACKAGE_ADVANCED" => InstructionIdent::PublishPackageAdvanced,
260 "CREATE_FUNGIBLE_RESOURCE" => InstructionIdent::CreateFungibleResource,
261 "CREATE_FUNGIBLE_RESOURCE_WITH_INITIAL_SUPPLY" => {
262 InstructionIdent::CreateFungibleResourceWithInitialSupply
263 }
264 "CREATE_NON_FUNGIBLE_RESOURCE" => InstructionIdent::CreateNonFungibleResource,
265 "CREATE_NON_FUNGIBLE_RESOURCE_WITH_INITIAL_SUPPLY" => {
266 InstructionIdent::CreateNonFungibleResourceWithInitialSupply
267 }
268 "CREATE_IDENTITY" => InstructionIdent::CreateIdentity,
269 "CREATE_IDENTITY_ADVANCED" => InstructionIdent::CreateIdentityAdvanced,
270 "CREATE_ACCOUNT" => InstructionIdent::CreateAccount,
271 "CREATE_ACCOUNT_ADVANCED" => InstructionIdent::CreateAccountAdvanced,
272 "CREATE_ACCESS_CONTROLLER" => InstructionIdent::CreateAccessController,
273
274 "SET_METADATA" => InstructionIdent::SetMetadata,
278 "REMOVE_METADATA" => InstructionIdent::RemoveMetadata,
279 "LOCK_METADATA" => InstructionIdent::LockMetadata,
280 "SET_COMPONENT_ROYALTY" => InstructionIdent::SetComponentRoyalty,
281 "LOCK_COMPONENT_ROYALTY" => InstructionIdent::LockComponentRoyalty,
282 "CLAIM_COMPONENT_ROYALTIES" => InstructionIdent::ClaimComponentRoyalties,
283 "SET_OWNER_ROLE" => InstructionIdent::SetOwnerRole,
284 "LOCK_OWNER_ROLE" => InstructionIdent::LockOwnerRole,
285 "SET_ROLE" => InstructionIdent::SetRole,
286
287 "MINT_FUNGIBLE" => InstructionIdent::MintFungible,
291 "MINT_NON_FUNGIBLE" => InstructionIdent::MintNonFungible,
292 "MINT_RUID_NON_FUNGIBLE" => InstructionIdent::MintRuidNonFungible,
293 "CLAIM_PACKAGE_ROYALTIES" => InstructionIdent::ClaimPackageRoyalties,
294 "CREATE_VALIDATOR" => InstructionIdent::CreateValidator,
295
296 _ => {
297 return None;
298 }
299 };
300 Some(value)
301 }
302}
303
304pub enum ManifestValueIdent {
305 Enum,
309 Array,
310 Tuple,
311 Map,
312 Some,
316 None,
317 Ok,
318 Err,
319 Bytes,
320 NonFungibleGlobalId,
321 Address,
325 Bucket,
326 Proof,
327 Expression,
328 Blob,
329 Decimal,
330 PreciseDecimal,
331 NonFungibleLocalId,
332 AddressReservation,
333 NamedAddress,
334 Intent,
335 NamedIntent,
336}
337
338impl ManifestValueIdent {
339 pub fn from_ident(ident: &str) -> Option<Self> {
340 let value = match ident {
341 "Enum" => Self::Enum,
345 "Array" => Self::Array,
346 "Tuple" => Self::Tuple,
347 "Map" => Self::Map,
348 "Some" => Self::Some,
352 "None" => Self::None,
353 "Ok" => Self::Ok,
354 "Err" => Self::Err,
355 "Bytes" => Self::Bytes,
356 "NonFungibleGlobalId" => Self::NonFungibleGlobalId,
357 "Address" => Self::Address,
361 "Bucket" => Self::Bucket,
362 "Proof" => Self::Proof,
363 "Expression" => Self::Expression,
364 "Blob" => Self::Blob,
365 "Decimal" => Self::Decimal,
366 "PreciseDecimal" => Self::PreciseDecimal,
367 "NonFungibleLocalId" => Self::NonFungibleLocalId,
368 "AddressReservation" => Self::AddressReservation,
369 "NamedAddress" => Self::NamedAddress,
370 "Intent" => Self::Intent,
371 "NamedIntent" => Self::NamedIntent,
372 _ => {
373 return None;
374 }
375 };
376 Some(value)
377 }
378}
379
380pub struct Parser {
381 tokens: Vec<TokenWithSpan>,
382 current: usize,
383 max_depth: usize,
384 stack_depth: usize,
385}
386
387impl Parser {
388 pub fn new(tokens: Vec<TokenWithSpan>, max_depth: usize) -> Result<Self, ParserError> {
389 if tokens.is_empty() {
390 Err(ParserError {
391 error_kind: ParserErrorKind::UnexpectedEof,
392 span: Span {
393 start: Position {
394 full_index: 0,
395 line_idx: 0,
396 line_char_index: 0,
397 },
398 end: Position {
399 full_index: 0,
400 line_idx: 0,
401 line_char_index: 0,
402 },
403 },
404 })
405 } else {
406 Ok(Self {
407 tokens,
408 current: 0,
409 max_depth,
410 stack_depth: 0,
411 })
412 }
413 }
414
415 #[inline]
416 fn track_stack_depth_increase(&mut self) -> Result<(), ParserError> {
417 self.stack_depth += 1;
418 if self.stack_depth > self.max_depth {
419 let token = self.peek()?;
420
421 return Err(ParserError {
422 error_kind: ParserErrorKind::MaxDepthExceeded {
423 actual: self.stack_depth,
424 max: self.max_depth,
425 },
426 span: token.span,
427 });
428 }
429 Ok(())
430 }
431
432 #[inline]
433 fn track_stack_depth_decrease(&mut self) -> Result<(), ParserError> {
434 self.stack_depth -= 1;
435 Ok(())
436 }
437
438 pub fn is_eof(&self) -> bool {
439 self.current == self.tokens.len()
440 }
441
442 pub fn peek(&mut self) -> Result<TokenWithSpan, ParserError> {
443 match self.tokens.get(self.current) {
444 Some(token) => Ok(token.clone()),
445 None => Err(ParserError {
446 error_kind: ParserErrorKind::UnexpectedEof,
447 span: {
448 let position = self.tokens[self.current - 1].span.end;
449 Span {
450 start: position,
451 end: position,
452 }
453 },
454 }),
455 }
456 }
457
458 pub fn advance(&mut self) -> Result<TokenWithSpan, ParserError> {
459 let token = self.peek()?;
460 self.current += 1;
461 Ok(token)
462 }
463
464 fn advance_exact(&mut self, expected: Token) -> Result<TokenWithSpan, ParserError> {
465 let token = self.advance()?;
466
467 if token.token != expected {
468 Err(ParserError::unexpected_token(
469 token,
470 TokenType::Exact(expected),
471 ))
472 } else {
473 Ok(token)
474 }
475 }
476
477 pub fn parse_manifest(&mut self) -> Result<Vec<InstructionWithSpan>, ParserError> {
478 let mut instructions = Vec::<InstructionWithSpan>::new();
479
480 while !self.is_eof() {
481 instructions.push(self.parse_instruction()?);
482 }
483
484 Ok(instructions)
485 }
486
487 fn parse_instruction_arguments(&mut self) -> Result<Vec<ValueWithSpan>, ParserError> {
488 let mut args = Vec::new();
489 while self.peek()?.token != Token::Semicolon {
490 let stack_depth = self.stack_depth;
491 let result = self.parse_value();
492 match result {
493 Ok(value) => args.push(value),
494 Err(err) => match err.error_kind {
495 ParserErrorKind::UnexpectedToken { expected, actual }
502 if expected == TokenType::Value
503 && (stack_depth + 1 == self.stack_depth) =>
504 {
505 return Err(ParserError {
506 error_kind: ParserErrorKind::InvalidArgument { expected, actual },
507 span: err.span,
508 })
509 }
510 _ => return Err(err),
511 },
512 }
513 }
514 Ok(args)
515 }
516
517 pub fn parse_instruction(&mut self) -> Result<InstructionWithSpan, ParserError> {
518 let token = self.advance()?;
519 let instruction_ident = match &token.token {
520 Token::Ident(ident_str) => InstructionIdent::from_ident(ident_str).ok_or(
521 ParserError::unexpected_token(token.clone(), TokenType::Instruction),
522 )?,
523 _ => {
524 return Err(ParserError::unexpected_token(token, TokenType::Instruction));
525 }
526 };
527 let instruction_start = token.span.start;
528
529 let instruction = match instruction_ident {
530 InstructionIdent::UsePreallocatedAddress => Instruction::UsePreallocatedAddress {
534 package_address: self.parse_value()?,
535 blueprint_name: self.parse_value()?,
536 address_reservation: self.parse_value()?,
537 preallocated_address: self.parse_value()?,
538 },
539 InstructionIdent::UseChild => Instruction::UseChild {
540 named_intent: self.parse_value()?,
541 subintent_hash: self.parse_value()?,
542 },
543
544 InstructionIdent::TakeFromWorktop => Instruction::TakeFromWorktop {
550 resource_address: self.parse_value()?,
551 amount: self.parse_value()?,
552 new_bucket: self.parse_value()?,
553 },
554 InstructionIdent::TakeNonFungiblesFromWorktop => {
555 Instruction::TakeNonFungiblesFromWorktop {
556 resource_address: self.parse_value()?,
557 ids: self.parse_value()?,
558 new_bucket: self.parse_value()?,
559 }
560 }
561 InstructionIdent::TakeAllFromWorktop => Instruction::TakeAllFromWorktop {
562 resource_address: self.parse_value()?,
563 new_bucket: self.parse_value()?,
564 },
565 InstructionIdent::ReturnToWorktop => Instruction::ReturnToWorktop {
566 bucket: self.parse_value()?,
567 },
568 InstructionIdent::BurnResource => Instruction::BurnResource {
569 bucket: self.parse_value()?,
570 },
571
572 InstructionIdent::AssertWorktopContainsAny => Instruction::AssertWorktopContainsAny {
574 resource_address: self.parse_value()?,
575 },
576 InstructionIdent::AssertWorktopContains => Instruction::AssertWorktopContains {
577 resource_address: self.parse_value()?,
578 amount: self.parse_value()?,
579 },
580 InstructionIdent::AssertWorktopContainsNonFungibles => {
581 Instruction::AssertWorktopContainsNonFungibles {
582 resource_address: self.parse_value()?,
583 ids: self.parse_value()?,
584 }
585 }
586 InstructionIdent::AssertWorktopIsEmpty => Instruction::AssertWorktopIsEmpty,
587 InstructionIdent::AssertWorktopResourcesOnly => {
588 Instruction::AssertWorktopResourcesOnly {
589 constraints: self.parse_value()?,
590 }
591 }
592 InstructionIdent::AssertWorktopResourcesInclude => {
593 Instruction::AssertWorktopResourcesInclude {
594 constraints: self.parse_value()?,
595 }
596 }
597 InstructionIdent::AssertNextCallReturnsOnly => Instruction::AssertNextCallReturnsOnly {
598 constraints: self.parse_value()?,
599 },
600 InstructionIdent::AssertNextCallReturnsInclude => {
601 Instruction::AssertNextCallReturnsInclude {
602 constraints: self.parse_value()?,
603 }
604 }
605 InstructionIdent::AssertBucketContents => Instruction::AssertBucketContents {
606 bucket: self.parse_value()?,
607 constraint: self.parse_value()?,
608 },
609
610 InstructionIdent::CreateProofFromBucketOfAmount => {
612 Instruction::CreateProofFromBucketOfAmount {
613 bucket: self.parse_value()?,
614 amount: self.parse_value()?,
615 new_proof: self.parse_value()?,
616 }
617 }
618 InstructionIdent::CreateProofFromBucketOfNonFungibles => {
619 Instruction::CreateProofFromBucketOfNonFungibles {
620 bucket: self.parse_value()?,
621 ids: self.parse_value()?,
622 new_proof: self.parse_value()?,
623 }
624 }
625 InstructionIdent::CreateProofFromBucketOfAll => {
626 Instruction::CreateProofFromBucketOfAll {
627 bucket: self.parse_value()?,
628 new_proof: self.parse_value()?,
629 }
630 }
631 InstructionIdent::CreateProofFromAuthZoneOfAmount => {
632 Instruction::CreateProofFromAuthZoneOfAmount {
633 resource_address: self.parse_value()?,
634 amount: self.parse_value()?,
635 new_proof: self.parse_value()?,
636 }
637 }
638 InstructionIdent::CreateProofFromAuthZoneOfNonFungibles => {
639 Instruction::CreateProofFromAuthZoneOfNonFungibles {
640 resource_address: self.parse_value()?,
641 ids: self.parse_value()?,
642 new_proof: self.parse_value()?,
643 }
644 }
645 InstructionIdent::CreateProofFromAuthZoneOfAll => {
646 Instruction::CreateProofFromAuthZoneOfAll {
647 resource_address: self.parse_value()?,
648 new_proof: self.parse_value()?,
649 }
650 }
651 InstructionIdent::CloneProof => Instruction::CloneProof {
652 proof: self.parse_value()?,
653 new_proof: self.parse_value()?,
654 },
655 InstructionIdent::DropProof => Instruction::DropProof {
656 proof: self.parse_value()?,
657 },
658 InstructionIdent::PushToAuthZone => Instruction::PushToAuthZone {
659 proof: self.parse_value()?,
660 },
661 InstructionIdent::PopFromAuthZone => Instruction::PopFromAuthZone {
662 new_proof: self.parse_value()?,
663 },
664 InstructionIdent::DropAuthZoneProofs => Instruction::DropAuthZoneProofs,
665 InstructionIdent::DropAuthZoneRegularProofs => Instruction::DropAuthZoneRegularProofs,
666 InstructionIdent::DropAuthZoneSignatureProofs => {
667 Instruction::DropAuthZoneSignatureProofs
668 }
669 InstructionIdent::DropNamedProofs => Instruction::DropNamedProofs,
670 InstructionIdent::DropAllProofs => Instruction::DropAllProofs,
671
672 InstructionIdent::CallFunction => Instruction::CallFunction {
674 package_address: self.parse_value()?,
675 blueprint_name: self.parse_value()?,
676 function_name: self.parse_value()?,
677 args: self.parse_instruction_arguments()?,
678 },
679 InstructionIdent::CallMethod => Instruction::CallMethod {
680 address: self.parse_value()?,
681 method_name: self.parse_value()?,
682 args: self.parse_instruction_arguments()?,
683 },
684 InstructionIdent::CallRoyaltyMethod => Instruction::CallRoyaltyMethod {
685 address: self.parse_value()?,
686 method_name: self.parse_value()?,
687 args: self.parse_instruction_arguments()?,
688 },
689 InstructionIdent::CallMetadataMethod => Instruction::CallMetadataMethod {
690 address: self.parse_value()?,
691 method_name: self.parse_value()?,
692 args: self.parse_instruction_arguments()?,
693 },
694 InstructionIdent::CallRoleAssignmentMethod => Instruction::CallRoleAssignmentMethod {
695 address: self.parse_value()?,
696 method_name: self.parse_value()?,
697 args: self.parse_instruction_arguments()?,
698 },
699 InstructionIdent::CallDirectVaultMethod => Instruction::CallDirectVaultMethod {
700 address: self.parse_value()?,
701 method_name: self.parse_value()?,
702 args: self.parse_instruction_arguments()?,
703 },
704
705 InstructionIdent::AllocateGlobalAddress => Instruction::AllocateGlobalAddress {
707 package_address: self.parse_value()?,
708 blueprint_name: self.parse_value()?,
709 address_reservation: self.parse_value()?,
710 named_address: self.parse_value()?,
711 },
712
713 InstructionIdent::YieldToParent => Instruction::YieldToParent {
715 args: self.parse_instruction_arguments()?,
716 },
717 InstructionIdent::YieldToChild => Instruction::YieldToChild {
718 child: self.parse_value()?,
719 args: self.parse_instruction_arguments()?,
720 },
721 InstructionIdent::VerifyParent => Instruction::VerifyParent {
722 access_rule: self.parse_value()?,
723 },
724
725 InstructionIdent::RecallFromVault => Instruction::RecallFromVault {
729 vault_id: self.parse_value()?,
730 args: self.parse_instruction_arguments()?,
731 },
732 InstructionIdent::FreezeVault => Instruction::FreezeVault {
733 vault_id: self.parse_value()?,
734 args: self.parse_instruction_arguments()?,
735 },
736 InstructionIdent::UnfreezeVault => Instruction::UnfreezeVault {
737 vault_id: self.parse_value()?,
738 args: self.parse_instruction_arguments()?,
739 },
740 InstructionIdent::RecallNonFungiblesFromVault => {
741 Instruction::RecallNonFungiblesFromVault {
742 vault_id: self.parse_value()?,
743 args: self.parse_instruction_arguments()?,
744 }
745 }
746
747 InstructionIdent::PublishPackage => Instruction::PublishPackage {
751 args: self.parse_instruction_arguments()?,
752 },
753 InstructionIdent::PublishPackageAdvanced => Instruction::PublishPackageAdvanced {
754 args: self.parse_instruction_arguments()?,
755 },
756 InstructionIdent::CreateFungibleResource => Instruction::CreateFungibleResource {
757 args: self.parse_instruction_arguments()?,
758 },
759 InstructionIdent::CreateFungibleResourceWithInitialSupply => {
760 Instruction::CreateFungibleResourceWithInitialSupply {
761 args: self.parse_instruction_arguments()?,
762 }
763 }
764 InstructionIdent::CreateNonFungibleResource => Instruction::CreateNonFungibleResource {
765 args: self.parse_instruction_arguments()?,
766 },
767 InstructionIdent::CreateNonFungibleResourceWithInitialSupply => {
768 Instruction::CreateNonFungibleResourceWithInitialSupply {
769 args: self.parse_instruction_arguments()?,
770 }
771 }
772 InstructionIdent::CreateAccessController => Instruction::CreateAccessController {
773 args: self.parse_instruction_arguments()?,
774 },
775 InstructionIdent::CreateIdentity => Instruction::CreateIdentity {
776 args: self.parse_instruction_arguments()?,
777 },
778 InstructionIdent::CreateIdentityAdvanced => Instruction::CreateIdentityAdvanced {
779 args: self.parse_instruction_arguments()?,
780 },
781 InstructionIdent::CreateAccount => Instruction::CreateAccount {
782 args: self.parse_instruction_arguments()?,
783 },
784 InstructionIdent::CreateAccountAdvanced => Instruction::CreateAccountAdvanced {
785 args: self.parse_instruction_arguments()?,
786 },
787
788 InstructionIdent::SetMetadata => Instruction::SetMetadata {
792 address: self.parse_value()?,
793 args: self.parse_instruction_arguments()?,
794 },
795 InstructionIdent::RemoveMetadata => Instruction::RemoveMetadata {
796 address: self.parse_value()?,
797 args: self.parse_instruction_arguments()?,
798 },
799 InstructionIdent::LockMetadata => Instruction::LockMetadata {
800 address: self.parse_value()?,
801 args: self.parse_instruction_arguments()?,
802 },
803 InstructionIdent::SetComponentRoyalty => Instruction::SetComponentRoyalty {
804 address: self.parse_value()?,
805 args: self.parse_instruction_arguments()?,
806 },
807 InstructionIdent::LockComponentRoyalty => Instruction::LockComponentRoyalty {
808 address: self.parse_value()?,
809 args: self.parse_instruction_arguments()?,
810 },
811 InstructionIdent::ClaimComponentRoyalties => Instruction::ClaimComponentRoyalties {
812 address: self.parse_value()?,
813 args: self.parse_instruction_arguments()?,
814 },
815 InstructionIdent::SetOwnerRole => Instruction::SetOwnerRole {
816 address: self.parse_value()?,
817 args: self.parse_instruction_arguments()?,
818 },
819 InstructionIdent::LockOwnerRole => Instruction::LockOwnerRole {
820 address: self.parse_value()?,
821 args: self.parse_instruction_arguments()?,
822 },
823 InstructionIdent::SetRole => Instruction::SetRole {
824 address: self.parse_value()?,
825 args: self.parse_instruction_arguments()?,
826 },
827
828 InstructionIdent::MintFungible => Instruction::MintFungible {
832 address: self.parse_value()?,
833 args: self.parse_instruction_arguments()?,
834 },
835 InstructionIdent::MintNonFungible => Instruction::MintNonFungible {
836 address: self.parse_value()?,
837 args: self.parse_instruction_arguments()?,
838 },
839 InstructionIdent::MintRuidNonFungible => Instruction::MintRuidNonFungible {
840 address: self.parse_value()?,
841 args: self.parse_instruction_arguments()?,
842 },
843 InstructionIdent::ClaimPackageRoyalties => Instruction::ClaimPackageRoyalties {
844 address: self.parse_value()?,
845 args: self.parse_instruction_arguments()?,
846 },
847 InstructionIdent::CreateValidator => Instruction::CreateValidator {
848 args: self.parse_instruction_arguments()?,
849 },
850 };
851
852 let instruction_end = self.advance_exact(Token::Semicolon)?.span.end;
853
854 Ok(InstructionWithSpan {
855 instruction,
856 span: Span {
857 start: instruction_start,
858 end: instruction_end,
859 },
860 })
861 }
862
863 pub fn parse_value(&mut self) -> Result<ValueWithSpan, ParserError> {
864 self.track_stack_depth_increase()?;
865 let token = self.advance()?;
866 let value = match &token.token {
867 Token::BoolLiteral(value) => Value::Bool(*value),
871 Token::U8Literal(value) => Value::U8(*value),
872 Token::U16Literal(value) => Value::U16(*value),
873 Token::U32Literal(value) => Value::U32(*value),
874 Token::U64Literal(value) => Value::U64(*value),
875 Token::U128Literal(value) => Value::U128(*value),
876 Token::I8Literal(value) => Value::I8(*value),
877 Token::I16Literal(value) => Value::I16(*value),
878 Token::I32Literal(value) => Value::I32(*value),
879 Token::I64Literal(value) => Value::I64(*value),
880 Token::I128Literal(value) => Value::I128(*value),
881 Token::StringLiteral(value) => Value::String(value.clone()),
882 Token::Ident(ident_str) => {
883 let value_ident = ManifestValueIdent::from_ident(ident_str).ok_or(
884 ParserError::unexpected_token(token.clone(), TokenType::Value),
885 )?;
886 match value_ident {
887 ManifestValueIdent::Enum => self.parse_enum_content()?,
888 ManifestValueIdent::Array => self.parse_array_content()?,
889 ManifestValueIdent::Tuple => self.parse_tuple_content()?,
890 ManifestValueIdent::Map => self.parse_map_content()?,
891
892 ManifestValueIdent::Some => Value::Some(Box::new(self.parse_values_one()?)),
896 ManifestValueIdent::None => Value::None,
897 ManifestValueIdent::Ok => Value::Ok(Box::new(self.parse_values_one()?)),
898 ManifestValueIdent::Err => Value::Err(Box::new(self.parse_values_one()?)),
899 ManifestValueIdent::Bytes => Value::Bytes(Box::new(self.parse_values_one()?)),
900 ManifestValueIdent::NonFungibleGlobalId => {
901 Value::NonFungibleGlobalId(Box::new(self.parse_values_one()?))
902 }
903
904 ManifestValueIdent::Address => Value::Address(self.parse_values_one()?.into()),
908 ManifestValueIdent::Bucket => Value::Bucket(self.parse_values_one()?.into()),
909 ManifestValueIdent::Proof => Value::Proof(self.parse_values_one()?.into()),
910 ManifestValueIdent::Expression => {
911 Value::Expression(self.parse_values_one()?.into())
912 }
913 ManifestValueIdent::Blob => Value::Blob(self.parse_values_one()?.into()),
914 ManifestValueIdent::Decimal => Value::Decimal(self.parse_values_one()?.into()),
915 ManifestValueIdent::PreciseDecimal => {
916 Value::PreciseDecimal(self.parse_values_one()?.into())
917 }
918 ManifestValueIdent::NonFungibleLocalId => {
919 Value::NonFungibleLocalId(self.parse_values_one()?.into())
920 }
921 ManifestValueIdent::AddressReservation => {
922 Value::AddressReservation(self.parse_values_one()?.into())
923 }
924 ManifestValueIdent::NamedAddress => {
925 Value::NamedAddress(self.parse_values_one()?.into())
926 }
927 ManifestValueIdent::Intent => Value::Intent(self.parse_values_one()?.into()),
928 ManifestValueIdent::NamedIntent => {
929 Value::NamedIntent(self.parse_values_one()?.into())
930 }
931 }
932 }
933 _ => {
934 return Err(ParserError::unexpected_token(token, TokenType::Value));
935 }
936 };
937 self.track_stack_depth_decrease()?;
938 Ok(ValueWithSpan {
939 value,
940 span: token.span,
941 })
942 }
943
944 pub fn parse_enum_content(&mut self) -> Result<Value, ParserError> {
945 self.advance_exact(Token::LessThan)?;
946
947 let discriminator_token = self.advance()?;
948 let discriminator = match discriminator_token.token {
949 Token::U8Literal(discriminator) => discriminator,
950 Token::Ident(discriminator) => KNOWN_ENUM_DISCRIMINATORS
951 .get(discriminator.as_str())
952 .cloned()
953 .ok_or(ParserError {
954 error_kind: ParserErrorKind::UnknownEnumDiscriminator {
955 actual: discriminator.clone(),
956 },
957 span: discriminator_token.span,
958 })?,
959 _ => {
960 return Err(ParserError::unexpected_token(
961 discriminator_token,
962 TokenType::EnumDiscriminator,
963 ))
964 }
965 };
966 self.advance_exact(Token::GreaterThan)?;
967
968 let fields = self.parse_values_any(Token::OpenParenthesis, Token::CloseParenthesis)?;
969
970 Ok(Value::Enum(discriminator, fields))
971 }
972
973 pub fn parse_array_content(&mut self) -> Result<Value, ParserError> {
974 let generics = self.parse_generics(1)?;
975 Ok(Value::Array(
976 generics[0].clone(),
977 self.parse_values_any(Token::OpenParenthesis, Token::CloseParenthesis)?,
978 ))
979 }
980
981 pub fn parse_tuple_content(&mut self) -> Result<Value, ParserError> {
982 Ok(Value::Tuple(self.parse_values_any(
983 Token::OpenParenthesis,
984 Token::CloseParenthesis,
985 )?))
986 }
987
988 pub fn parse_map_content(&mut self) -> Result<Value, ParserError> {
989 let generics = self.parse_generics(2)?;
990 self.advance_exact(Token::OpenParenthesis)?;
991 let mut entries = Vec::new();
992
993 while self.peek()?.token != Token::CloseParenthesis {
994 let key = self.parse_value()?;
995 self.advance_exact(Token::FatArrow)?;
996 let value = self.parse_value()?;
997 entries.push((key, value));
998 if self.peek()?.token != Token::CloseParenthesis {
999 self.advance_exact(Token::Comma)?;
1000 }
1001 }
1002 self.advance_exact(Token::CloseParenthesis)?;
1003 Ok(Value::Map(
1004 generics[0].clone(),
1005 generics[1].clone(),
1006 entries,
1007 ))
1008 }
1009
1010 fn parse_values_any(
1012 &mut self,
1013 open: Token,
1014 close: Token,
1015 ) -> Result<Vec<ValueWithSpan>, ParserError> {
1016 self.parse_values_any_with_open_close_spans(open, close)
1017 .map(|(values, _, _)| values)
1018 }
1019
1020 fn parse_values_any_with_open_close_spans(
1023 &mut self,
1024 open: Token,
1025 close: Token,
1026 ) -> Result<(Vec<ValueWithSpan>, Span, Span), ParserError> {
1027 let open_token = self.advance_exact(open)?;
1028 let mut values = Vec::new();
1029 while self.peek()?.token != close {
1030 values.push(self.parse_value()?);
1031 if self.peek()?.token != close {
1032 self.advance_exact(Token::Comma)?;
1033 }
1034 }
1035 let close_token = self.advance_exact(close)?;
1036 Ok((values, open_token.span, close_token.span))
1037 }
1038
1039 fn parse_values_one(&mut self) -> Result<ValueWithSpan, ParserError> {
1040 let (values, open_span, close_span) = self.parse_values_any_with_open_close_spans(
1041 Token::OpenParenthesis,
1042 Token::CloseParenthesis,
1043 )?;
1044 match values.len() {
1045 1 => Ok(values[0].clone()),
1046 _ => Err(ParserError {
1047 error_kind: ParserErrorKind::InvalidNumberOfValues {
1048 actual: values.len(),
1049 expected: 1,
1050 },
1051 span: Span {
1052 start: open_span.end,
1053 end: close_span.start,
1054 },
1055 }),
1056 }
1057 }
1058
1059 fn parse_generics(&mut self, n: usize) -> Result<Vec<ValueKindWithSpan>, ParserError> {
1060 let mut span_start = self.advance_exact(Token::LessThan)?.span.start;
1061 let mut value_kinds = Vec::new();
1062
1063 while self.peek()?.token != Token::GreaterThan {
1064 let token_value_kind = self.parse_value_kind()?;
1065 value_kinds.push(token_value_kind);
1066 if self.peek()?.token != Token::GreaterThan {
1067 self.advance_exact(Token::Comma)?;
1068 }
1069 }
1070
1071 let mut span_end = self.advance_exact(Token::GreaterThan)?.span.end;
1072
1073 if value_kinds.len() != 0 {
1074 span_start = value_kinds[0].span.start;
1075 span_end = value_kinds[value_kinds.len() - 1].span.end;
1076 }
1077
1078 if value_kinds.len() != n {
1079 Err(ParserError {
1080 error_kind: ParserErrorKind::InvalidNumberOfTypes {
1081 expected: n,
1082 actual: value_kinds.len(),
1083 },
1084 span: Span {
1085 start: span_start,
1086 end: span_end,
1087 },
1088 })
1089 } else {
1090 Ok(value_kinds)
1091 }
1092 }
1093
1094 fn parse_value_kind(&mut self) -> Result<ValueKindWithSpan, ParserError> {
1095 let token = self.advance()?;
1096 let value_kind = match &token.token {
1097 Token::Ident(ident_str) => ValueKind::from_ident(&ident_str).ok_or(
1098 ParserError::unexpected_token(token.clone(), TokenType::ValueKind),
1099 )?,
1100 _ => {
1101 return Err(ParserError::unexpected_token(token, TokenType::ValueKind));
1102 }
1103 };
1104 Ok(ValueKindWithSpan {
1105 value_kind,
1106 span: token.span,
1107 })
1108 }
1109}
1110
1111pub fn parser_error_diagnostics(
1112 s: &str,
1113 err: ParserError,
1114 style: CompileErrorDiagnosticsStyle,
1115) -> String {
1116 let (title, label) = match err.error_kind {
1117 ParserErrorKind::UnexpectedEof => (
1118 "unexpected end of file".to_string(),
1119 "unexpected end of file".to_string(),
1120 ),
1121 ParserErrorKind::UnexpectedToken { expected, actual } => {
1122 let title = format!("expected {}, found {}", expected, actual);
1123 let label = format!("expected {}", expected);
1124 (title, label)
1125 }
1126 ParserErrorKind::InvalidArgument { expected, actual } => {
1127 let title = format!(
1128 "expected {} or ';' to end an argument list, found {}",
1129 expected, actual
1130 );
1131 let label = format!("expected {} or ';' to end an argument list", expected);
1132 (title, label)
1133 }
1134 ParserErrorKind::InvalidNumberOfValues { expected, actual } => {
1135 let title = format!("expected {} number of values, found {}", expected, actual);
1136 let label = format!("expected {} number of values", expected);
1137 (title, label)
1138 }
1139 ParserErrorKind::InvalidNumberOfTypes { expected, actual } => {
1140 let title = format!("expected {} number of types, found {}", expected, actual);
1141 let label = format!("expected {} number of types", expected);
1142 (title, label)
1143 }
1144 ParserErrorKind::MaxDepthExceeded { actual, max } => {
1145 let title = format!("manifest actual depth {} exceeded max {}", actual, max);
1146 (title, "max depth exceeded".to_string())
1147 }
1148 ParserErrorKind::UnknownEnumDiscriminator { actual } => {
1149 let title = format!("unknown enum discriminator found '{}'", actual);
1150 (title, "unknown enum discriminator".to_string())
1151 }
1152 };
1153
1154 create_snippet(s, &err.span, &title, &label, style)
1155}
1156
1157#[cfg(test)]
1158mod tests {
1159 use super::*;
1160 use crate::manifest::lexer::tokenize;
1161 use crate::{position, span};
1162
1163 #[macro_export]
1164 macro_rules! parse_instruction_ok {
1165 ( $s:expr, $expected:expr ) => {{
1166 let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1167 assert_eq!(parser.parse_instruction(), Ok($expected));
1168 assert!(parser.is_eof());
1169 }};
1170 }
1171
1172 #[macro_export]
1173 macro_rules! parse_value_ok {
1174 ( $s:expr, $expected:expr ) => {{
1175 let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1176 assert_eq!(parser.parse_value().map(|tv| tv.value), Ok($expected));
1177 assert!(parser.is_eof());
1178 }};
1179 }
1180
1181 #[macro_export]
1182 macro_rules! parse_value_error {
1183 ( $s:expr, $expected:expr ) => {{
1184 let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1185 match parser.parse_value() {
1186 Ok(_) => {
1187 panic!("Expected {:?} but no error is thrown", $expected);
1188 }
1189 Err(e) => {
1190 assert_eq!(e, $expected);
1191 }
1192 }
1193 }};
1194 }
1195
1196 #[test]
1197 fn test_literals() {
1198 parse_value_ok!(r#"true"#, Value::Bool(true));
1199 parse_value_ok!(r#"false"#, Value::Bool(false));
1200 parse_value_ok!(r#"1i8"#, Value::I8(1));
1201 parse_value_ok!(r#"1i16"#, Value::I16(1));
1202 parse_value_ok!(r#"1i32"#, Value::I32(1));
1203 parse_value_ok!(r#"1i64"#, Value::I64(1));
1204 parse_value_ok!(r#"1i128"#, Value::I128(1));
1205 parse_value_ok!(r#"1u8"#, Value::U8(1));
1206 parse_value_ok!(r#"1u16"#, Value::U16(1));
1207 parse_value_ok!(r#"1u32"#, Value::U32(1));
1208 parse_value_ok!(r#"1u64"#, Value::U64(1));
1209 parse_value_ok!(r#"1u128"#, Value::U128(1));
1210 parse_value_ok!(r#""test""#, Value::String("test".into()));
1211 }
1212
1213 #[test]
1214 fn test_enum() {
1215 parse_value_ok!(
1216 r#"Enum<0u8>("Hello", 123u8)"#,
1217 Value::Enum(
1218 0,
1219 vec![
1220 ValueWithSpan {
1221 value: Value::String("Hello".into()),
1222 span: span!(start = (10, 0, 10), end = (17, 0, 17)),
1223 },
1224 ValueWithSpan {
1225 value: Value::U8(123),
1226 span: span!(start = (19, 0, 19), end = (24, 0, 24)),
1227 },
1228 ],
1229 )
1230 );
1231 parse_value_ok!(r#"Enum<0u8>()"#, Value::Enum(0, Vec::new()));
1232 parse_value_ok!(
1233 r#"Enum<PublicKey::Secp256k1>()"#,
1234 Value::Enum(0, Vec::new())
1235 );
1236 parse_value_ok!(
1238 r#"Enum<0u8>("Hello", 123u8,)"#,
1239 Value::Enum(
1240 0,
1241 vec![
1242 ValueWithSpan {
1243 value: Value::String("Hello".into()),
1244 span: span!(start = (10, 0, 10), end = (17, 0, 17)),
1245 },
1246 ValueWithSpan {
1247 value: Value::U8(123),
1248 span: span!(start = (19, 0, 19), end = (24, 0, 24)),
1249 },
1250 ],
1251 )
1252 );
1253 }
1254
1255 #[test]
1256 fn test_array() {
1257 parse_value_ok!(
1258 r#"Array<U8>(1u8, 2u8)"#,
1259 Value::Array(
1260 ValueKindWithSpan {
1261 value_kind: ValueKind::U8,
1262 span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1263 },
1264 vec![
1265 ValueWithSpan {
1266 value: Value::U8(1),
1267 span: span!(start = (10, 0, 10), end = (13, 0, 13)),
1268 },
1269 ValueWithSpan {
1270 value: Value::U8(2),
1271 span: span!(start = (15, 0, 15), end = (18, 0, 18)),
1272 }
1273 ],
1274 )
1275 );
1276 parse_value_ok!(
1277 r#"Array<U8>()"#,
1278 Value::Array(
1279 ValueKindWithSpan {
1280 value_kind: ValueKind::U8,
1281 span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1282 },
1283 vec![]
1284 )
1285 );
1286 parse_value_ok!(
1288 r#"Array<U8>(1u8, 2u8,)"#,
1289 Value::Array(
1290 ValueKindWithSpan {
1291 value_kind: ValueKind::U8,
1292 span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1293 },
1294 vec![
1295 ValueWithSpan {
1296 value: Value::U8(1),
1297 span: span!(start = (10, 0, 10), end = (13, 0, 13)),
1298 },
1299 ValueWithSpan {
1300 value: Value::U8(2),
1301 span: span!(start = (15, 0, 15), end = (18, 0, 18)),
1302 }
1303 ],
1304 )
1305 );
1306 }
1307
1308 #[test]
1309 fn test_tuple() {
1310 parse_value_ok!(r#"Tuple()"#, Value::Tuple(vec![]));
1311 parse_value_ok!(
1312 r#"Tuple("Hello", 123u8)"#,
1313 Value::Tuple(vec![
1314 ValueWithSpan {
1315 value: Value::String("Hello".into()),
1316 span: span!(start = (6, 0, 6), end = (13, 0, 13)),
1317 },
1318 ValueWithSpan {
1319 value: Value::U8(123),
1320 span: span!(start = (15, 0, 15), end = (20, 0, 20)),
1321 },
1322 ])
1323 );
1324 parse_value_ok!(
1325 r#"Tuple(1u8, 2u8)"#,
1326 Value::Tuple(vec![
1327 ValueWithSpan {
1328 value: Value::U8(1),
1329 span: span!(start = (6, 0, 6), end = (9, 0, 9)),
1330 },
1331 ValueWithSpan {
1332 value: Value::U8(2),
1333 span: span!(start = (11, 0, 11), end = (14, 0, 14)),
1334 },
1335 ])
1336 );
1337
1338 parse_value_ok!(
1340 r#"Tuple(1u8, 2u8,)"#,
1341 Value::Tuple(vec![
1342 ValueWithSpan {
1343 value: Value::U8(1),
1344 span: span!(start = (6, 0, 6), end = (9, 0, 9)),
1345 },
1346 ValueWithSpan {
1347 value: Value::U8(2),
1348 span: span!(start = (11, 0, 11), end = (14, 0, 14)),
1349 },
1350 ])
1351 );
1352 }
1353
1354 #[test]
1355 fn test_map() {
1356 parse_value_ok!(
1357 r#"Map<String, U8>("Hello" => 123u8)"#,
1358 Value::Map(
1359 ValueKindWithSpan {
1360 value_kind: ValueKind::String,
1361 span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1362 },
1363 ValueKindWithSpan {
1364 value_kind: ValueKind::U8,
1365 span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1366 },
1367 vec![(
1368 ValueWithSpan {
1369 value: Value::String("Hello".into()),
1370 span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1371 },
1372 ValueWithSpan {
1373 value: Value::U8(123),
1374 span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1375 }
1376 )]
1377 )
1378 );
1379 parse_value_ok!(
1380 r#"Map<String, U8>("Hello" => 123u8, "world!" => 1u8)"#,
1381 Value::Map(
1382 ValueKindWithSpan {
1383 value_kind: ValueKind::String,
1384 span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1385 },
1386 ValueKindWithSpan {
1387 value_kind: ValueKind::U8,
1388 span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1389 },
1390 vec![
1391 (
1392 ValueWithSpan {
1393 value: Value::String("Hello".into()),
1394 span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1395 },
1396 ValueWithSpan {
1397 value: Value::U8(123),
1398 span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1399 }
1400 ),
1401 (
1402 ValueWithSpan {
1403 value: Value::String("world!".into()),
1404 span: span!(start = (34, 0, 34), end = (42, 0, 42)),
1405 },
1406 ValueWithSpan {
1407 value: Value::U8(1),
1408 span: span!(start = (46, 0, 46), end = (49, 0, 49)),
1409 }
1410 )
1411 ]
1412 )
1413 );
1414
1415 parse_value_ok!(
1417 r#"Map<String, U8>("Hello" => 123u8, "world!" => 1u8,)"#,
1418 Value::Map(
1419 ValueKindWithSpan {
1420 value_kind: ValueKind::String,
1421 span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1422 },
1423 ValueKindWithSpan {
1424 value_kind: ValueKind::U8,
1425 span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1426 },
1427 vec![
1428 (
1429 ValueWithSpan {
1430 value: Value::String("Hello".into()),
1431 span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1432 },
1433 ValueWithSpan {
1434 value: Value::U8(123),
1435 span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1436 }
1437 ),
1438 (
1439 ValueWithSpan {
1440 value: Value::String("world!".into()),
1441 span: span!(start = (34, 0, 34), end = (42, 0, 42)),
1442 },
1443 ValueWithSpan {
1444 value: Value::U8(1),
1445 span: span!(start = (46, 0, 46), end = (49, 0, 49)),
1446 }
1447 )
1448 ]
1449 )
1450 );
1451 }
1452
1453 #[test]
1454 fn test_failures() {
1455 parse_value_error!(
1456 r#"Enum<0u8"#,
1457 ParserError {
1458 error_kind: ParserErrorKind::UnexpectedEof,
1459 span: span!(start = (8, 0, 8), end = (8, 0, 8))
1460 }
1461 );
1462 parse_value_error!(
1463 r#"Enum<0u8)"#,
1464 ParserError {
1465 error_kind: ParserErrorKind::UnexpectedToken {
1466 expected: TokenType::Exact(Token::GreaterThan),
1467 actual: Token::CloseParenthesis,
1468 },
1469 span: span!(start = (8, 0, 8), end = (9, 0, 9))
1470 }
1471 );
1472 parse_value_error!(
1473 r#"Address("abc", "def")"#,
1474 ParserError {
1475 error_kind: ParserErrorKind::InvalidNumberOfValues {
1476 actual: 2,
1477 expected: 1,
1478 },
1479 span: span!(start = (8, 0, 8), end = (20, 0, 20)),
1480 }
1481 );
1482 parse_value_error!(
1483 r#"Address()"#,
1484 ParserError {
1485 error_kind: ParserErrorKind::InvalidNumberOfValues {
1486 actual: 0,
1487 expected: 1,
1488 },
1489 span: span!(start = (8, 0, 8), end = (8, 0, 8)),
1490 }
1491 );
1492 parse_value_error!(
1493 r#"Address( )"#,
1494 ParserError {
1495 error_kind: ParserErrorKind::InvalidNumberOfValues {
1496 actual: 0,
1497 expected: 1,
1498 },
1499 span: span!(start = (8, 0, 8), end = (11, 0, 11)),
1500 }
1501 );
1502 }
1503
1504 #[test]
1505 fn test_deep_value_does_not_panic_with_stack_overflow() {
1506 let depth: usize = 1000;
1507 let mut value_string = "".to_string();
1508 for _ in 0..depth {
1509 value_string.push_str("Tuple(");
1510 }
1511 value_string.push_str("0u8");
1512 for _ in 0..depth {
1513 value_string.push_str(")");
1514 }
1515
1516 parse_value_error!(
1518 &value_string,
1519 ParserError {
1520 error_kind: ParserErrorKind::MaxDepthExceeded {
1521 actual: 21,
1522 max: 20,
1523 },
1524 span: span!(start = (120, 0, 120), end = (125, 0, 125))
1525 }
1526 );
1527 }
1528
1529 }