1use core::{error::Error, fmt::Display};
4
5use alloc::{
6 boxed::Box,
7 collections::BTreeMap,
8 format,
9 string::{String, ToString},
10 vec::Vec,
11};
12
13use crate::{
14 WasmValue,
15 ast::{Node, NodeType},
16 lex::{FuncNameLexer, FuncNameToken, Keyword, Lexer, Span, Token},
17 untyped::{UntypedFuncCall, UntypedValue},
18};
19
20const MAX_DEPTH: usize = 100;
21
22pub struct Parser<'source> {
24 lex: Lexer<'source>,
25 curr: Option<Token>,
26 depth: usize,
27}
28
29impl<'source> Parser<'source> {
30 pub fn new(source: &'source str) -> Self {
32 Self::with_lexer(Lexer::new(source))
33 }
34
35 pub fn with_lexer(lexer: Lexer<'source>) -> Self {
37 Self {
38 lex: lexer,
39 curr: None,
40 depth: 0,
41 }
42 }
43
44 pub fn parse_value<V: WasmValue>(&mut self, ty: &V::Type) -> Result<V, ParserError> {
47 let node = self.parse_node()?;
48 node.to_wasm_value(ty, self.lex.source())
49 }
50
51 pub fn parse_raw_value(&mut self) -> Result<UntypedValue<'source>, ParserError> {
53 let node = self.parse_node()?;
54 Ok(UntypedValue::new(self.lex.source(), node))
55 }
56
57 pub fn finish(&mut self) -> Result<(), ParserError> {
59 match self.lex.clone().spanned().next() {
60 None => Ok(()),
61 Some((_, span)) => Err(ParserError::new(
62 ParserErrorKind::TrailingCharacters,
63 span.clone(),
64 )),
65 }
66 }
67
68 fn parse_node(&mut self) -> Result<Node, ParserError> {
69 if self.depth >= MAX_DEPTH {
70 return Err(ParserError::new(
71 ParserErrorKind::NestingTooDeep,
72 self.lex.span(),
73 ));
74 }
75 self.depth += 1;
76 let result = self.parse_node_inner();
77 self.depth -= 1;
78 result
79 }
80
81 fn parse_node_inner(&mut self) -> Result<Node, ParserError> {
82 Ok(match self.advance()? {
83 Token::Number => self.leaf_node(NodeType::Number),
84 Token::Char => self.leaf_node(NodeType::Char),
85 Token::String => self.leaf_node(NodeType::String),
86 Token::MultilineString => self.leaf_node(NodeType::MultilineString),
87 Token::ParenOpen => self.parse_tuple()?,
88 Token::BracketOpen => self.parse_list()?,
89 Token::BraceOpen => self.parse_braces()?,
90 Token::LabelOrKeyword => match Keyword::decode(self.slice()) {
91 Some(Keyword::True) => self.leaf_node(NodeType::BoolTrue),
92 Some(Keyword::False) => self.leaf_node(NodeType::BoolFalse),
93 Some(Keyword::Some) => self.parse_option(NodeType::OptionSome)?,
94 Some(Keyword::None) => self.parse_option(NodeType::OptionNone)?,
95 Some(Keyword::Ok) => self.parse_result(NodeType::ResultOk)?,
96 Some(Keyword::Err) => self.parse_result(NodeType::ResultErr)?,
97 Some(Keyword::Inf | Keyword::Nan) => self.leaf_node(NodeType::Number),
98 None => self.parse_label_maybe_payload()?,
99 },
100 Token::BraceClose
101 | Token::ParenClose
102 | Token::BracketClose
103 | Token::Colon
104 | Token::Comma => return Err(self.unexpected_token()),
105 })
106 }
107
108 fn parse_tuple(&mut self) -> Result<Node, ParserError> {
109 let start = self.span().start;
110 let children = self.parse_comma_separated_nodes(Token::ParenClose)?;
111 let span = start..self.span().end;
112 if children.is_empty() {
113 return Err(ParserError::new(ParserErrorKind::EmptyTuple, span));
114 }
115 Ok(Node::new(NodeType::Tuple, span, children))
116 }
117
118 fn parse_list(&mut self) -> Result<Node, ParserError> {
119 let start = self.span().start;
120 let children = self.parse_comma_separated_nodes(Token::BracketClose)?;
121 Ok(Node::new(NodeType::List, start..self.span().end, children))
122 }
123
124 fn parse_braces(&mut self) -> Result<Node, ParserError> {
125 let start = self.span().start;
126 self.advance()?;
127
128 match self.token() {
129 Token::Colon => {
131 self.advance()?; self.expect_token(Token::BraceClose)?;
133 return Ok(Node::new(NodeType::TupleSet, start..self.span().end, []));
134 }
135 Token::BraceClose => {
137 return Ok(Node::new(NodeType::EmptySet, start..self.span().end, []));
138 }
139 _ => (),
140 }
141
142 if self.token() != Token::LabelOrKeyword || self.next_is(Token::Colon) {
145 self.finish_tuple_set(start)
146 } else {
147 self.finish_flags(start)
148 }
149 }
150
151 fn finish_tuple_set(&mut self, start: usize) -> Result<Node, ParserError> {
152 let mut children = Vec::with_capacity(2);
153 loop {
154 let key = self.parse_key()?;
156 self.advance()?;
158 self.expect_token(Token::Colon)?;
159 let value = self.parse_node()?;
161 children.extend([key, value]);
162 match self.advance()? {
164 Token::Comma => {
165 self.advance()?;
166 if self.token() == Token::BraceClose {
167 break;
168 }
169 }
170 Token::BraceClose => break,
171 _ => return Err(self.unexpected_token()),
172 }
173 }
174 Ok(Node::new(
175 NodeType::TupleSet,
176 start..self.span().end,
177 children,
178 ))
179 }
180
181 fn finish_flags(&mut self, start: usize) -> Result<Node, ParserError> {
182 let mut flags = BTreeMap::new();
183 loop {
184 let label = self.parse_label()?;
186 let span = label.span();
188 let flag = self.slice().trim_start_matches('%');
189 if flags.insert(flag, label).is_some() {
190 return Err(ParserError::with_detail(
191 ParserErrorKind::DuplicateFlag,
192 span,
193 format!("{flag:?}"),
194 ));
195 }
196 match self.advance()? {
197 Token::Comma => {
198 self.advance()?;
199 if self.token() == Token::BraceClose {
200 break;
201 }
202 }
203 Token::BraceClose => break,
204 _ => return Err(self.unexpected_token()),
205 }
206 }
207 Ok(Node::new(
208 NodeType::Flags,
209 start..self.span().end,
210 flags.into_values(),
211 ))
212 }
213
214 fn parse_label_maybe_payload(&mut self) -> Result<Node, ParserError> {
215 let start = self.span().start;
216 let label = self.parse_label()?;
217 if self.next_is(Token::ParenOpen) {
218 self.advance()?;
219 let payload = self.parse_node()?;
220 self.advance()?;
221 self.expect_token(Token::ParenClose)?;
222 Ok(Node::new(
223 NodeType::VariantWithPayload,
224 start..self.span().end,
225 [label, payload],
226 ))
227 } else {
228 Ok(label)
229 }
230 }
231
232 fn parse_option(&mut self, ty: NodeType) -> Result<Node, ParserError> {
233 let start = self.span().start;
234 let payload = match ty {
235 NodeType::OptionSome => {
236 self.advance()?;
237 self.expect_token(Token::ParenOpen)?;
238 let payload = self.parse_node()?;
239 self.advance()?;
240 self.expect_token(Token::ParenClose)?;
241 Some(payload)
242 }
243 NodeType::OptionNone => None,
244 _ => unreachable!(),
245 };
246 Ok(Node::new(ty, start..self.span().end, payload))
247 }
248
249 fn parse_result(&mut self, ty: NodeType) -> Result<Node, ParserError> {
250 let start = self.span().start;
251 let mut payload = None;
252 if self.next_is(Token::ParenOpen) {
253 self.advance()?;
254 self.expect_token(Token::ParenOpen)?;
255 payload = Some(self.parse_node()?);
256 self.advance()?;
257 self.expect_token(Token::ParenClose)?;
258 }
259 Ok(Node::new(ty, start..self.span().end, payload))
260 }
261
262 fn parse_label(&mut self) -> Result<Node, ParserError> {
263 self.expect_token(Token::LabelOrKeyword)?;
264 Ok(self.leaf_node(NodeType::Label))
265 }
266
267 fn parse_key(&mut self) -> Result<Node, ParserError> {
270 let ty = match self.token() {
271 Token::LabelOrKeyword => NodeType::Label,
272 Token::Number => NodeType::Number,
273 Token::Char => NodeType::Char,
274 Token::String => NodeType::String,
275 Token::MultilineString => NodeType::MultilineString,
276 _ => return Err(self.unexpected_token()),
277 };
278 Ok(self.leaf_node(ty))
279 }
280
281 fn advance(&mut self) -> Result<Token, ParserError> {
282 let token = match self.lex.next() {
283 Some(Ok(token)) => token,
284 Some(Err(span)) => {
285 let span = span.unwrap_or_else(|| self.lex.span());
286 return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
287 }
288 None => {
289 return Err(ParserError::new(
290 ParserErrorKind::UnexpectedEnd,
291 self.lex.span(),
292 ));
293 }
294 };
295 self.curr = Some(token);
296 Ok(token)
297 }
298
299 fn token(&self) -> Token {
300 self.curr.unwrap()
301 }
302
303 fn span(&self) -> Span {
304 self.lex.span()
305 }
306
307 fn slice(&self) -> &'source str {
308 &self.lex.source()[self.span()]
309 }
310
311 fn next_is(&mut self, token: Token) -> bool {
312 self.lex.clone().next().and_then(|res| res.ok()) == Some(token)
313 }
314
315 fn expect_token(&self, token: Token) -> Result<(), ParserError> {
316 if self.token() == token {
317 Ok(())
318 } else {
319 Err(self.unexpected_token())
320 }
321 }
322
323 fn unexpected_token(&self) -> ParserError {
324 ParserError::with_detail(ParserErrorKind::UnexpectedToken, self.span(), self.token())
325 }
326
327 fn parse_comma_separated_nodes(&mut self, end_token: Token) -> Result<Vec<Node>, ParserError> {
328 let mut nodes = Vec::new();
329 if self.next_is(end_token) {
330 self.advance()?;
331 return Ok(nodes);
332 }
333 loop {
334 nodes.push(self.parse_node()?);
335
336 match self.advance()? {
337 Token::Comma => {
338 if self.next_is(end_token) {
339 self.advance()?;
340 break;
341 }
342 }
343 _ => {
344 self.expect_token(end_token)?;
345 break;
346 }
347 }
348 }
349 Ok(nodes)
350 }
351
352 fn leaf_node(&self, ty: NodeType) -> Node {
353 Node::new(ty, self.span(), [])
354 }
355}
356
357#[derive(Debug)]
359pub struct ParserError {
360 kind: ParserErrorKind,
361 span: Span,
362 detail: Option<String>,
363 source: Option<Box<dyn Error + Send + Sync + 'static>>,
364}
365
366impl ParserError {
367 pub(crate) fn new(kind: ParserErrorKind, span: Span) -> Self {
368 Self {
369 kind,
370 span,
371 detail: None,
372 source: None,
373 }
374 }
375
376 pub(crate) fn with_detail(kind: ParserErrorKind, span: Span, detail: impl Display) -> Self {
377 Self {
378 kind,
379 span,
380 detail: Some(detail.to_string()),
381 source: None,
382 }
383 }
384
385 pub(crate) fn with_source(
386 kind: ParserErrorKind,
387 span: Span,
388 source: impl Into<Box<dyn Error + Send + Sync>>,
389 ) -> Self {
390 Self {
391 kind,
392 span,
393 detail: None,
394 source: Some(source.into()),
395 }
396 }
397
398 pub fn kind(&self) -> ParserErrorKind {
400 self.kind
401 }
402
403 pub fn span(&self) -> Span {
405 self.span.clone()
406 }
407
408 pub fn detail(&self) -> Option<&str> {
410 self.detail.as_deref()
411 }
412}
413
414impl Display for ParserError {
415 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
416 if let Some(source) = &self.source {
417 write!(f, "{}: {} at {:?}", self.kind, source, self.span)
418 } else if let Some(detail) = &self.detail {
419 write!(f, "{}: {} at {:?}", self.kind, detail, self.span)
420 } else {
421 write!(f, "{} at {:?}", self.kind, self.span)
422 }
423 }
424}
425
426impl Error for ParserError {
427 fn source(&self) -> Option<&(dyn Error + 'static)> {
428 Some(self.source.as_deref()? as _)
429 }
430}
431
432pub fn parse_raw_func_call<'source>(
435 source: &'source str,
436) -> Result<UntypedFuncCall<'source>, ParserError> {
437 let mut name_parser = FuncNameParser::with_lexer(FuncNameLexer::new(source));
438 let _func_name = name_parser.advance()?;
439 let name = name_parser.lex.span();
440
441 let mut params_parser = Parser::with_lexer(name_parser.lex.morph());
442 params_parser.advance()?;
443 params_parser.expect_token(Token::ParenOpen)?;
444
445 let params = if params_parser.next_is(Token::ParenClose) {
446 params_parser.advance()?;
447 None
448 } else {
449 Some(params_parser.parse_tuple()?)
450 };
451 params_parser.finish()?;
452 Ok(UntypedFuncCall::new(source, name, params))
453}
454
455struct FuncNameParser<'source> {
456 lex: FuncNameLexer<'source>,
457 curr: Option<FuncNameToken>,
458}
459impl<'source> FuncNameParser<'source> {
460 fn with_lexer(lex: FuncNameLexer<'source>) -> Self {
461 Self { lex, curr: None }
462 }
463 fn advance(&mut self) -> Result<FuncNameToken, ParserError> {
464 let token = match self.lex.next() {
465 Some(Ok(token)) => token,
466 Some(Err(span)) => {
467 let span = span.unwrap_or_else(|| self.lex.span());
468 return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
469 }
470 None => {
471 return Err(ParserError::new(
472 ParserErrorKind::UnexpectedEnd,
473 self.lex.span(),
474 ));
475 }
476 };
477 self.curr = Some(token);
478 Ok(token)
479 }
480}
481#[derive(Clone, Copy, Debug, PartialEq)]
483#[non_exhaustive]
484#[allow(missing_docs)]
485pub enum ParserErrorKind {
486 EmptyTuple,
487 MultipleChars,
488 InvalidEscape,
489 InvalidMultilineString,
490 InvalidParams,
491 InvalidToken,
492 InvalidType,
493 InvalidValue,
494 TrailingCharacters,
495 UnexpectedEnd,
496 UnexpectedToken,
497 DuplicateField,
498 DuplicateFlag,
499 WasmValueError,
500 NestingTooDeep,
501}
502
503impl Display for ParserErrorKind {
504 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
505 let msg = match self {
506 ParserErrorKind::EmptyTuple => "empty tuple",
507 ParserErrorKind::MultipleChars => "multiple characters in char value",
508 ParserErrorKind::InvalidEscape => "invalid character escape",
509 ParserErrorKind::InvalidMultilineString => "invalid multiline string",
510 ParserErrorKind::InvalidParams => "invalid params",
511 ParserErrorKind::InvalidToken => "invalid token",
512 ParserErrorKind::InvalidType => "invalid value type",
513 ParserErrorKind::InvalidValue => "invalid value",
514 ParserErrorKind::TrailingCharacters => "trailing characters after value",
515 ParserErrorKind::UnexpectedEnd => "unexpected end of input",
516 ParserErrorKind::UnexpectedToken => "unexpected token",
517 ParserErrorKind::DuplicateField => "duplicate field",
518 ParserErrorKind::DuplicateFlag => "duplicate flag",
519 ParserErrorKind::WasmValueError => "error converting Wasm value",
520 ParserErrorKind::NestingTooDeep => "value nesting too deep",
521 };
522 write!(f, "{msg}")
523 }
524}
525
526#[cfg(test)]
527mod tests {
528 use super::*;
529 use crate::value::{Type, Value};
530
531 #[test]
532 fn parse_option_or_result() {
533 let ty = Type::option(Type::BOOL);
534 assert_eq!(
535 parse_value("some(true)", &ty),
536 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
537 );
538 let ty = Type::result(Some(Type::BOOL), None);
539 assert_eq!(
540 parse_value("ok(false)", &ty),
541 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
542 );
543 }
544
545 #[test]
546 fn parse_flat_option_or_result() {
547 let ty = Type::option(Type::BOOL);
548 assert_eq!(
549 parse_value("true", &ty),
550 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
551 );
552 let ty = Type::result(Some(Type::BOOL), None);
553 assert_eq!(
554 parse_value("false", &ty),
555 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
556 );
557 }
558
559 #[test]
560 fn parse_record_reordering() {
561 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
562 assert_eq!(
564 parse_value("{red: 0, green: 'a'}", &ty),
565 Value::make_record(
566 &ty,
567 [
568 ("red", Value::make_s32(0)),
569 ("green", Value::make_char('a'))
570 ]
571 )
572 .unwrap()
573 );
574 assert_eq!(
576 parse_value("{green: 'a', red: 0}", &ty),
577 Value::make_record(
578 &ty,
579 [
580 ("red", Value::make_s32(0)),
581 ("green", Value::make_char('a'))
582 ]
583 )
584 .unwrap()
585 );
586 }
587
588 #[test]
589 fn parse_record_with_optional_fields() {
590 let field_ty = Type::option(Type::CHAR);
591 let ty = Type::record([("red", Type::S32), ("green", field_ty.clone())]).unwrap();
592 assert_eq!(
594 parse_value("{red: 0, green: some('a')}", &ty),
595 Value::make_record(
596 &ty,
597 [
598 ("red", Value::make_s32(0)),
599 (
600 "green",
601 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
602 )
603 ]
604 )
605 .unwrap()
606 );
607 assert_eq!(
609 parse_value("{red: 0, green: 'a'}", &ty),
610 Value::make_record(
611 &ty,
612 [
613 ("red", Value::make_s32(0)),
614 (
615 "green",
616 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
617 )
618 ]
619 )
620 .unwrap()
621 );
622 assert_eq!(
624 parse_value("{red: 0, green: none}", &ty),
625 Value::make_record(
626 &ty,
627 [
628 ("red", Value::make_s32(0)),
629 ("green", Value::make_option(&field_ty, None).unwrap())
630 ]
631 )
632 .unwrap()
633 );
634 assert_eq!(
636 parse_value("{red: 0}", &ty),
637 Value::make_record(
638 &ty,
639 [
640 ("red", Value::make_s32(0)),
641 ("green", Value::make_option(&field_ty, None).unwrap())
642 ]
643 )
644 .unwrap()
645 );
646 }
647
648 #[test]
649 fn parse_flag_reordering() {
650 let ty = Type::flags(["hot", "cold"]).unwrap();
651 assert_eq!(
653 parse_value("{hot, cold}", &ty),
654 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
655 );
656 assert_eq!(
658 parse_value("{cold, hot}", &ty),
659 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
660 );
661 }
662
663 #[test]
664 fn parse_flags_in_type_order() {
665 #[derive(Clone)]
668 struct Flags(Vec<String>);
669
670 impl WasmValue for Flags {
671 type Type = Type;
672
673 fn kind(&self) -> crate::wasm::WasmTypeKind {
674 crate::wasm::WasmTypeKind::Flags
675 }
676
677 fn make_flags<'a>(
678 _ty: &Type,
679 names: impl IntoIterator<Item = &'a str>,
680 ) -> Result<Self, crate::wasm::WasmValueError> {
681 Ok(Self(names.into_iter().map(String::from).collect()))
682 }
683 }
684
685 let ty = Type::flags(["read", "write", "exec"]).unwrap();
686 for input in ["{write, exec}", "{exec, write}", "{%exec, write}"] {
687 let Flags(names) = Parser::new(input).parse_value(&ty).unwrap();
688 assert_eq!(names, ["write", "exec"], "for {input:?}");
689 }
690 }
691
692 #[test]
693 fn reject_record_missing_commas() {
694 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
695
696 for input in [
697 r#"{"red": 1 "green": 'a'}"#,
698 r#"{"red":1"green":'a'}"#,
699 "{\"red\": 1\n\"green\": 'a'}",
700 ] {
701 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
702 assert_eq!(err.kind(), ParserErrorKind::UnexpectedToken);
703 }
704 }
705
706 #[test]
707 fn reject_map_missing_commas() {
708 let ty = Type::map(Type::STRING, Type::U32).unwrap();
709 for input in [
710 r#"{"a": 1 "b": 2}"#,
711 r#"{"a":1"b":2}"#,
712 "{\"a\": 1\n\"b\": 2}",
713 ] {
714 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
715 assert_eq!(err.kind(), ParserErrorKind::UnexpectedToken);
716 }
717
718 let ty = Type::map(Type::S8, Type::BOOL).unwrap();
719 for input in ["{-1: true 1: false}", "{-1:true-2:false}"] {
720 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
721 assert_eq!(err.kind(), ParserErrorKind::UnexpectedToken);
722 }
723 }
724
725 #[test]
726 fn reject_flags_missing_commas() {
727 let ty = Type::flags(["read", "write", "exec"]).unwrap();
728 for input in [
729 "{read write}",
730 "{read write exec}",
731 "{read, write exec}",
732 "{%read write}",
733 "{read\nwrite}",
734 "{read // comment\nwrite}",
735 ] {
736 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
737 assert_eq!(err.kind(), ParserErrorKind::UnexpectedToken);
738 }
739 }
740
741 #[test]
742 fn reject_missing_commas_untyped() {
743 for input in [
745 "{a: 1 b: 2}",
746 "{a:0b:\"\"}",
747 "{a b}",
748 "{a b c}",
749 r#"{"a": 1 "b": 2}"#,
750 "{1: 2 3: 4}",
751 "{a: {b: 1 c: 2}}",
752 "{a: [{b: 1 c: 2}]}",
753 ] {
754 let err = Parser::new(input).parse_raw_value().unwrap_err();
755 assert_eq!(err.kind(), ParserErrorKind::UnexpectedToken);
756 }
757 }
758
759 #[test]
760 fn accept_commas_between_and_after_entries() {
761 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
762 for input in [
763 "{red: 0, green: 'a'}",
764 "{red: 0, green: 'a',}",
765 "{ red : 0 , green : 'a' , }",
766 "{red: 0 // c\n, green: 'a'}",
767 ] {
768 Parser::new(input).parse_value::<Value>(&ty).unwrap();
769 }
770 let ty = Type::flags(["read", "write"]).unwrap();
771 for input in [
772 "{read, write}",
773 "{read, write,}",
774 "{ read , write , }",
775 "{read}",
776 "{read,}",
777 ] {
778 Parser::new(input).parse_value::<Value>(&ty).unwrap();
779 }
780 }
781
782 #[test]
783 fn reject_record_unknown_fields() {
784 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
785 for input in [
786 "{red: 0, green: 'a', blue: 1}",
787 "{blue: 1, red: 0, green: 'a'}",
788 "{red: 0, green: 'a', blue: 300}",
790 "{red: 0, green: 'a', blue: {x: 1, x: 2}}",
791 ] {
792 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
793 assert_eq!(err.kind(), ParserErrorKind::InvalidValue);
794 }
795 }
796
797 #[test]
798 fn parse_percent_identifiers() {
799 let ty = Type::record([
800 ("red", Type::S32),
801 ("green", Type::CHAR),
802 ("color-42-2A-5d", Type::BOOL),
803 ])
804 .unwrap();
805 assert_eq!(
807 parse_value("{ %red: 0, %green: 'a', %color-42-2A-5d: true }", &ty),
808 Value::make_record(
809 &ty,
810 [
811 ("red", Value::make_s32(0)),
812 ("green", Value::make_char('a')),
813 ("color-42-2A-5d", Value::make_bool(true))
814 ]
815 )
816 .unwrap()
817 );
818 }
819
820 #[test]
821 fn parse_prefixed_keyword_variant_cases() {
822 let ty = Type::list(
823 Type::variant([
824 ("true", Some(Type::U8)),
825 ("false", None),
826 ("inf", Some(Type::U8)),
827 ("nan", None),
828 ("some", Some(Type::U8)),
829 ("none", None),
830 ("ok", Some(Type::U8)),
831 ("err", None),
832 ])
833 .unwrap(),
834 );
835 parse_value(
836 "[%true(1), %false, %inf(1), %nan, %some(1), %none, %ok(1), %err]",
837 &ty,
838 );
839 }
840
841 #[test]
842 fn reject_unprefixed_keyword_enum_cases() {
843 let cases = ["true", "false", "inf", "nan", "none", "ok", "err"];
844 let ty = Type::enum_ty(cases).unwrap();
845 for case in cases {
846 let err = Parser::new(case).parse_value::<Value>(&ty).unwrap_err();
847 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
848 }
849 }
850
851 #[test]
852 fn parse_unprefixed_keyword_fields() {
853 let ty = Type::record([
854 ("true", Type::U8),
855 ("false", Type::U8),
856 ("inf", Type::U8),
857 ("nan", Type::U8),
858 ("some", Type::U8),
859 ("none", Type::U8),
860 ("ok", Type::U8),
861 ("err", Type::U8),
862 ])
863 .unwrap();
864 parse_value(
865 "{true: 1, false: 1, inf: 1, nan: 1, some: 1, none: 1, ok: 1, err: 1}",
866 &ty,
867 );
868 }
869
870 #[test]
871 fn parse_unprefixed_keyword_flags() {
872 let ty = Type::flags(["true", "false", "inf", "nan", "some", "none", "ok", "err"]).unwrap();
873 parse_value("{true, false, inf, nan, some, none, ok, err}", &ty);
874 }
875
876 #[test]
877 fn reject_unprefixed_some_variant_case() {
878 let ty = Type::variant([("some", Some(Type::U8))]).unwrap();
879 let err = Parser::new("some(1)")
880 .parse_value::<Value>(&ty)
881 .unwrap_err();
882 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
883 }
884
885 #[test]
886 fn parse_maps() {
887 let ty = Type::map(Type::STRING, Type::U32).unwrap();
888 let entry =
889 |key: &str, value: u32| (Value::make_string(key.into()), Value::make_u32(value));
890 assert_eq!(parse_value("{}", &ty), Value::make_map(&ty, []).unwrap());
891 assert_eq!(
892 parse_value(r#"{"a": 1}"#, &ty),
893 Value::make_map(&ty, [entry("a", 1)]).unwrap()
894 );
895 assert_eq!(
897 parse_value(r#"{ "b" : 2, "a": 1, }"#, &ty),
898 Value::make_map(&ty, [entry("b", 2), entry("a", 1)]).unwrap()
899 );
900
901 let ty = Type::map(Type::S8, Type::BOOL).unwrap();
902 assert_eq!(
903 parse_value("{-1: true, 1: false}", &ty),
904 Value::make_map(
905 &ty,
906 [
907 (Value::make_s8(-1), Value::make_bool(true)),
908 (Value::make_s8(1), Value::make_bool(false)),
909 ]
910 )
911 .unwrap()
912 );
913
914 let ty = Type::map(Type::BOOL, Type::option(Type::BOOL)).unwrap();
916 assert_eq!(
917 parse_value("{true: none, false: some(false)}", &ty),
918 Value::make_map(
919 &ty,
920 [
921 (
922 Value::make_bool(true),
923 Value::make_option(&Type::option(Type::BOOL), None).unwrap()
924 ),
925 (
926 Value::make_bool(false),
927 Value::make_option(
928 &Type::option(Type::BOOL),
929 Some(Value::make_bool(false))
930 )
931 .unwrap()
932 ),
933 ]
934 )
935 .unwrap()
936 );
937 }
938
939 #[test]
940 fn reject_invalid_maps() {
941 let ty = Type::map(Type::STRING, Type::U32).unwrap();
942 for (input, kind) in [
943 ("{1: 1}", ParserErrorKind::InvalidType),
945 ("{'a': 1}", ParserErrorKind::InvalidType),
946 ("{a: 1}", ParserErrorKind::InvalidType),
947 (r#"{"a": "b"}"#, ParserErrorKind::InvalidType),
949 ("[]", ParserErrorKind::InvalidType),
951 (r#"[("a", 1)]"#, ParserErrorKind::InvalidType),
952 ("{a}", ParserErrorKind::InvalidType),
953 (r#"{"a"}"#, ParserErrorKind::UnexpectedToken),
955 (r#"{"a": 1, b}"#, ParserErrorKind::UnexpectedToken),
956 (r#"{a, "b": 1}"#, ParserErrorKind::UnexpectedToken),
957 (r#"{"a":}"#, ParserErrorKind::UnexpectedToken),
959 ("{: 1}", ParserErrorKind::UnexpectedToken),
960 (r#"{"a": 1: 2}"#, ParserErrorKind::UnexpectedToken),
961 ] {
962 let err = Parser::new(input).parse_value::<Value>(&ty).unwrap_err();
963 assert_eq!(err.kind(), kind, "for {input:?}: {err}");
964 }
965
966 let ty = Type::record([("a", Type::U32)]).unwrap();
968 let err = Parser::new(r#"{"a": 1}"#)
969 .parse_value::<Value>(&ty)
970 .unwrap_err();
971 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
972 }
973
974 #[test]
975 fn reject_deeply_nested_values() {
976 let deep = MAX_DEPTH + 1;
977 let cases = [
978 ("[".repeat(deep) + &"]".repeat(deep), "nested lists"),
979 ("(".repeat(deep) + "0" + &")".repeat(deep), "nested tuples"),
980 (
981 "some(".repeat(deep) + "0" + &")".repeat(deep),
982 "nested some()",
983 ),
984 ("ok(".repeat(deep) + "0" + &")".repeat(deep), "nested ok()"),
985 (
986 "{a:".repeat(deep) + "0" + &"}".repeat(deep),
987 "nested records",
988 ),
989 (
990 "v(".repeat(deep) + "0" + &")".repeat(deep),
991 "nested variant payloads",
992 ),
993 ];
994 for (input, desc) in cases {
995 let err = UntypedValue::parse(&input)
996 .expect_err(&alloc::format!("{desc} should be rejected"));
997 assert_eq!(
998 err.kind(),
999 ParserErrorKind::NestingTooDeep,
1000 "wrong error kind for {desc}"
1001 );
1002 }
1003 }
1004
1005 #[test]
1006 fn reject_deeply_nested_func_call_params() {
1007 let deep = MAX_DEPTH + 1;
1008 let input = alloc::format!("f({}0{})", "some(".repeat(deep), ")".repeat(deep));
1009 let err = match UntypedFuncCall::parse(&input) {
1010 Ok(_) => panic!("deeply nested func call params should be rejected"),
1011 Err(err) => err,
1012 };
1013 assert_eq!(err.kind(), ParserErrorKind::NestingTooDeep);
1014 }
1015
1016 fn parse_value(input: &str, ty: &Type) -> Value {
1017 Parser::new(input)
1018 .parse_value(ty)
1019 .unwrap_or_else(|err| panic!("error decoding {input:?}: {err}"))
1020 }
1021}