Skip to main content

wasm_wave/
parser.rs

1//! Parsing types
2
3use core::{error::Error, fmt::Display};
4
5use alloc::{
6    boxed::Box,
7    collections::{BTreeMap, btree_set::BTreeSet},
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
22/// A Web Assembly Value Encoding parser.
23pub struct Parser<'source> {
24    lex: Lexer<'source>,
25    curr: Option<Token>,
26    depth: usize,
27}
28
29impl<'source> Parser<'source> {
30    /// Returns a new Parser of the given source.
31    pub fn new(source: &'source str) -> Self {
32        Self::with_lexer(Lexer::new(source))
33    }
34
35    /// Returns a new Parser with the given [`Lexer`].
36    pub fn with_lexer(lexer: Lexer<'source>) -> Self {
37        Self {
38            lex: lexer,
39            curr: None,
40            depth: 0,
41        }
42    }
43
44    /// Parses a WAVE-encoded value of the given [`crate::wasm::WasmType`] into a
45    /// corresponding [`WasmValue`].
46    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    /// Parses a WAVE-encoded value into an [`UntypedValue`].
52    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    /// Returns an error if any significant input remains unparsed.
58    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_record_or_flags()?,
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_record_or_flags(&mut self) -> Result<Node, ParserError> {
125        let start = self.span().start;
126        self.advance()?;
127
128        match self.token() {
129            // Handle empty record (`{:}`)
130            Token::Colon => {
131                self.advance()?; // Advance to `}`
132                self.expect_token(Token::BraceClose)?;
133                return Ok(Node::new(NodeType::Record, start..self.span().end, []));
134            }
135            // Handle empty flags (`{}`)
136            Token::BraceClose => return Ok(Node::new(NodeType::Flags, start..self.span().end, [])),
137            _ => (),
138        }
139
140        // Check for a following `:` to distinguish records from flags
141        if self.next_is(Token::Colon) {
142            self.finish_record(start)
143        } else {
144            self.finish_flags(start)
145        }
146    }
147
148    fn finish_record(&mut self, start: usize) -> Result<Node, ParserError> {
149        let mut seen = BTreeSet::new();
150        let mut children = Vec::with_capacity(2);
151        loop {
152            // Parse field label
153            let label = self.parse_label()?;
154            // Check for duplicate fields
155            let field = self.slice().trim_start_matches('%');
156            if !seen.insert(field) {
157                return Err(ParserError::with_detail(
158                    ParserErrorKind::DuplicateField,
159                    label.span(),
160                    format!("{field:?}"),
161                ));
162            }
163            // Parse colon
164            self.advance()?;
165            self.expect_token(Token::Colon)?;
166            // Parse value
167            let value = self.parse_node()?;
168            children.extend([label, value]);
169            // Parse comma and/or end of record
170            if self.advance()? == Token::Comma {
171                self.advance()?;
172            }
173            if self.token() == Token::BraceClose {
174                break;
175            }
176        }
177        Ok(Node::new(
178            NodeType::Record,
179            start..self.span().end,
180            children,
181        ))
182    }
183
184    fn finish_flags(&mut self, start: usize) -> Result<Node, ParserError> {
185        let mut flags = BTreeMap::new();
186        loop {
187            // Parse flag label
188            let label = self.parse_label()?;
189            // Insert and check for duplicate flags
190            let span = label.span();
191            let flag = self.slice().trim_start_matches('%');
192            if flags.insert(flag, label).is_some() {
193                return Err(ParserError::with_detail(
194                    ParserErrorKind::DuplicateFlag,
195                    span,
196                    format!("{flag:?}"),
197                ));
198            }
199            // Parse comma and/or end of flags
200            if self.advance()? == Token::Comma {
201                self.advance()?;
202            }
203            if self.token() == Token::BraceClose {
204                break;
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 advance(&mut self) -> Result<Token, ParserError> {
268        let token = match self.lex.next() {
269            Some(Ok(token)) => token,
270            Some(Err(span)) => {
271                let span = span.unwrap_or_else(|| self.lex.span());
272                return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
273            }
274            None => {
275                return Err(ParserError::new(
276                    ParserErrorKind::UnexpectedEnd,
277                    self.lex.span(),
278                ));
279            }
280        };
281        self.curr = Some(token);
282        Ok(token)
283    }
284
285    fn token(&self) -> Token {
286        self.curr.unwrap()
287    }
288
289    fn span(&self) -> Span {
290        self.lex.span()
291    }
292
293    fn slice(&self) -> &'source str {
294        &self.lex.source()[self.span()]
295    }
296
297    fn next_is(&mut self, token: Token) -> bool {
298        self.lex.clone().next().and_then(|res| res.ok()) == Some(token)
299    }
300
301    fn expect_token(&self, token: Token) -> Result<(), ParserError> {
302        if self.token() == token {
303            Ok(())
304        } else {
305            Err(self.unexpected_token())
306        }
307    }
308
309    fn unexpected_token(&self) -> ParserError {
310        ParserError::with_detail(ParserErrorKind::UnexpectedToken, self.span(), self.token())
311    }
312
313    fn parse_comma_separated_nodes(&mut self, end_token: Token) -> Result<Vec<Node>, ParserError> {
314        let mut nodes = Vec::new();
315        if self.next_is(end_token) {
316            self.advance()?;
317            return Ok(nodes);
318        }
319        loop {
320            nodes.push(self.parse_node()?);
321
322            match self.advance()? {
323                Token::Comma => {
324                    if self.next_is(end_token) {
325                        self.advance()?;
326                        break;
327                    }
328                }
329                _ => {
330                    self.expect_token(end_token)?;
331                    break;
332                }
333            }
334        }
335        Ok(nodes)
336    }
337
338    fn leaf_node(&self, ty: NodeType) -> Node {
339        Node::new(ty, self.span(), [])
340    }
341}
342
343/// A WAVE parsing error.
344#[derive(Debug)]
345pub struct ParserError {
346    kind: ParserErrorKind,
347    span: Span,
348    detail: Option<String>,
349    source: Option<Box<dyn Error + Send + Sync + 'static>>,
350}
351
352impl ParserError {
353    pub(crate) fn new(kind: ParserErrorKind, span: Span) -> Self {
354        Self {
355            kind,
356            span,
357            detail: None,
358            source: None,
359        }
360    }
361
362    pub(crate) fn with_detail(kind: ParserErrorKind, span: Span, detail: impl Display) -> Self {
363        Self {
364            kind,
365            span,
366            detail: Some(detail.to_string()),
367            source: None,
368        }
369    }
370
371    pub(crate) fn with_source(
372        kind: ParserErrorKind,
373        span: Span,
374        source: impl Into<Box<dyn Error + Send + Sync>>,
375    ) -> Self {
376        Self {
377            kind,
378            span,
379            detail: None,
380            source: Some(source.into()),
381        }
382    }
383
384    /// Returns the [`ParserErrorKind`] of this error.
385    pub fn kind(&self) -> ParserErrorKind {
386        self.kind
387    }
388
389    /// Returns the [`Span`] of this error.
390    pub fn span(&self) -> Span {
391        self.span.clone()
392    }
393
394    /// Returns any detail string for this error.
395    pub fn detail(&self) -> Option<&str> {
396        self.detail.as_deref()
397    }
398}
399
400impl Display for ParserError {
401    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
402        if let Some(source) = &self.source {
403            write!(f, "{}: {} at {:?}", self.kind, source, self.span)
404        } else if let Some(detail) = &self.detail {
405            write!(f, "{}: {} at {:?}", self.kind, detail, self.span)
406        } else {
407            write!(f, "{} at {:?}", self.kind, self.span)
408        }
409    }
410}
411
412impl Error for ParserError {
413    fn source(&self) -> Option<&(dyn Error + 'static)> {
414        Some(self.source.as_deref()? as _)
415    }
416}
417
418/// Parses a function name followed by a WAVE-encoded, parenthesized,
419/// comma-separated sequence of values into an [`UntypedFuncCall`].
420pub fn parse_raw_func_call<'source>(
421    source: &'source str,
422) -> Result<UntypedFuncCall<'source>, ParserError> {
423    let mut name_parser = FuncNameParser::with_lexer(FuncNameLexer::new(source));
424    let _func_name = name_parser.advance()?;
425    let name = name_parser.lex.span();
426
427    let mut params_parser = Parser::with_lexer(name_parser.lex.morph());
428    params_parser.advance()?;
429    params_parser.expect_token(Token::ParenOpen)?;
430
431    let params = if params_parser.next_is(Token::ParenClose) {
432        params_parser.advance()?;
433        None
434    } else {
435        Some(params_parser.parse_tuple()?)
436    };
437    params_parser.finish()?;
438    Ok(UntypedFuncCall::new(source, name, params))
439}
440
441struct FuncNameParser<'source> {
442    lex: FuncNameLexer<'source>,
443    curr: Option<FuncNameToken>,
444}
445impl<'source> FuncNameParser<'source> {
446    fn with_lexer(lex: FuncNameLexer<'source>) -> Self {
447        Self { lex, curr: None }
448    }
449    fn advance(&mut self) -> Result<FuncNameToken, ParserError> {
450        let token = match self.lex.next() {
451            Some(Ok(token)) => token,
452            Some(Err(span)) => {
453                let span = span.unwrap_or_else(|| self.lex.span());
454                return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
455            }
456            None => {
457                return Err(ParserError::new(
458                    ParserErrorKind::UnexpectedEnd,
459                    self.lex.span(),
460                ));
461            }
462        };
463        self.curr = Some(token);
464        Ok(token)
465    }
466}
467/// The kind of a WAVE parsing error.
468#[derive(Clone, Copy, Debug, PartialEq)]
469#[non_exhaustive]
470#[allow(missing_docs)]
471pub enum ParserErrorKind {
472    EmptyTuple,
473    MultipleChars,
474    InvalidEscape,
475    InvalidMultilineString,
476    InvalidParams,
477    InvalidToken,
478    InvalidType,
479    InvalidValue,
480    TrailingCharacters,
481    UnexpectedEnd,
482    UnexpectedToken,
483    DuplicateField,
484    DuplicateFlag,
485    WasmValueError,
486    NestingTooDeep,
487}
488
489impl Display for ParserErrorKind {
490    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
491        let msg = match self {
492            ParserErrorKind::EmptyTuple => "empty tuple",
493            ParserErrorKind::MultipleChars => "multiple characters in char value",
494            ParserErrorKind::InvalidEscape => "invalid character escape",
495            ParserErrorKind::InvalidMultilineString => "invalid multiline string",
496            ParserErrorKind::InvalidParams => "invalid params",
497            ParserErrorKind::InvalidToken => "invalid token",
498            ParserErrorKind::InvalidType => "invalid value type",
499            ParserErrorKind::InvalidValue => "invalid value",
500            ParserErrorKind::TrailingCharacters => "trailing characters after value",
501            ParserErrorKind::UnexpectedEnd => "unexpected end of input",
502            ParserErrorKind::UnexpectedToken => "unexpected token",
503            ParserErrorKind::DuplicateField => "duplicate field",
504            ParserErrorKind::DuplicateFlag => "duplicate flag",
505            ParserErrorKind::WasmValueError => "error converting Wasm value",
506            ParserErrorKind::NestingTooDeep => "value nesting too deep",
507        };
508        write!(f, "{msg}")
509    }
510}
511
512#[cfg(test)]
513mod tests {
514    use super::*;
515    use crate::value::{Type, Value};
516
517    #[test]
518    fn parse_option_or_result() {
519        let ty = Type::option(Type::BOOL);
520        assert_eq!(
521            parse_value("some(true)", &ty),
522            Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
523        );
524        let ty = Type::result(Some(Type::BOOL), None);
525        assert_eq!(
526            parse_value("ok(false)", &ty),
527            Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
528        );
529    }
530
531    #[test]
532    fn parse_flat_option_or_result() {
533        let ty = Type::option(Type::BOOL);
534        assert_eq!(
535            parse_value("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("false", &ty),
541            Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
542        );
543    }
544
545    #[test]
546    fn parse_record_reordering() {
547        let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
548        // Parse the fields in the order they appear in the type.
549        assert_eq!(
550            parse_value("{red: 0, green: 'a'}", &ty),
551            Value::make_record(
552                &ty,
553                [
554                    ("red", Value::make_s32(0)),
555                    ("green", Value::make_char('a'))
556                ]
557            )
558            .unwrap()
559        );
560        // Parse the fields in reverse order.
561        assert_eq!(
562            parse_value("{green: 'a', red: 0}", &ty),
563            Value::make_record(
564                &ty,
565                [
566                    ("red", Value::make_s32(0)),
567                    ("green", Value::make_char('a'))
568                ]
569            )
570            .unwrap()
571        );
572    }
573
574    #[test]
575    fn parse_record_with_optional_fields() {
576        let field_ty = Type::option(Type::CHAR);
577        let ty = Type::record([("red", Type::S32), ("green", field_ty.clone())]).unwrap();
578        // Explicit `some`.
579        assert_eq!(
580            parse_value("{red: 0, green: some('a')}", &ty),
581            Value::make_record(
582                &ty,
583                [
584                    ("red", Value::make_s32(0)),
585                    (
586                        "green",
587                        Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
588                    )
589                ]
590            )
591            .unwrap()
592        );
593        // Flattened `some`.
594        assert_eq!(
595            parse_value("{red: 0, green: 'a'}", &ty),
596            Value::make_record(
597                &ty,
598                [
599                    ("red", Value::make_s32(0)),
600                    (
601                        "green",
602                        Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
603                    )
604                ]
605            )
606            .unwrap()
607        );
608        // Explicit `none`.
609        assert_eq!(
610            parse_value("{red: 0, green: none}", &ty),
611            Value::make_record(
612                &ty,
613                [
614                    ("red", Value::make_s32(0)),
615                    ("green", Value::make_option(&field_ty, None).unwrap())
616                ]
617            )
618            .unwrap()
619        );
620        // Implied `none`.
621        assert_eq!(
622            parse_value("{red: 0}", &ty),
623            Value::make_record(
624                &ty,
625                [
626                    ("red", Value::make_s32(0)),
627                    ("green", Value::make_option(&field_ty, None).unwrap())
628                ]
629            )
630            .unwrap()
631        );
632    }
633
634    #[test]
635    fn parse_flag_reordering() {
636        let ty = Type::flags(["hot", "cold"]).unwrap();
637        // Parse the flags in the order they appear in the type.
638        assert_eq!(
639            parse_value("{hot, cold}", &ty),
640            Value::make_flags(&ty, ["hot", "cold"]).unwrap()
641        );
642        // Parse the flags in reverse order.
643        assert_eq!(
644            parse_value("{cold, hot}", &ty),
645            Value::make_flags(&ty, ["hot", "cold"]).unwrap()
646        );
647    }
648
649    #[test]
650    fn parse_percent_identifiers() {
651        let ty = Type::record([
652            ("red", Type::S32),
653            ("green", Type::CHAR),
654            ("color-42-2A-5d", Type::BOOL),
655        ])
656        .unwrap();
657        // Test identifiers with '%' prefixes.
658        assert_eq!(
659            parse_value("{ %red: 0, %green: 'a', %color-42-2A-5d: true }", &ty),
660            Value::make_record(
661                &ty,
662                [
663                    ("red", Value::make_s32(0)),
664                    ("green", Value::make_char('a')),
665                    ("color-42-2A-5d", Value::make_bool(true))
666                ]
667            )
668            .unwrap()
669        );
670    }
671
672    #[test]
673    fn parse_prefixed_keyword_variant_cases() {
674        let ty = Type::list(
675            Type::variant([
676                ("true", Some(Type::U8)),
677                ("false", None),
678                ("inf", Some(Type::U8)),
679                ("nan", None),
680                ("some", Some(Type::U8)),
681                ("none", None),
682                ("ok", Some(Type::U8)),
683                ("err", None),
684            ])
685            .unwrap(),
686        );
687        parse_value(
688            "[%true(1), %false, %inf(1), %nan, %some(1), %none, %ok(1), %err]",
689            &ty,
690        );
691    }
692
693    #[test]
694    fn reject_unprefixed_keyword_enum_cases() {
695        let cases = ["true", "false", "inf", "nan", "none", "ok", "err"];
696        let ty = Type::enum_ty(cases).unwrap();
697        for case in cases {
698            let err = Parser::new(case).parse_value::<Value>(&ty).unwrap_err();
699            assert_eq!(err.kind(), ParserErrorKind::InvalidType);
700        }
701    }
702
703    #[test]
704    fn parse_unprefixed_keyword_fields() {
705        let ty = Type::record([
706            ("true", Type::U8),
707            ("false", Type::U8),
708            ("inf", Type::U8),
709            ("nan", Type::U8),
710            ("some", Type::U8),
711            ("none", Type::U8),
712            ("ok", Type::U8),
713            ("err", Type::U8),
714        ])
715        .unwrap();
716        parse_value(
717            "{true: 1, false: 1, inf: 1, nan: 1, some: 1, none: 1, ok: 1, err: 1}",
718            &ty,
719        );
720    }
721
722    #[test]
723    fn parse_unprefixed_keyword_flags() {
724        let ty = Type::flags(["true", "false", "inf", "nan", "some", "none", "ok", "err"]).unwrap();
725        parse_value("{true, false, inf, nan, some, none, ok, err}", &ty);
726    }
727
728    #[test]
729    fn reject_unprefixed_some_variant_case() {
730        let ty = Type::variant([("some", Some(Type::U8))]).unwrap();
731        let err = Parser::new("some(1)")
732            .parse_value::<Value>(&ty)
733            .unwrap_err();
734        assert_eq!(err.kind(), ParserErrorKind::InvalidType);
735    }
736
737    #[test]
738    fn reject_deeply_nested_values() {
739        let deep = MAX_DEPTH + 1;
740        let cases = [
741            ("[".repeat(deep) + &"]".repeat(deep), "nested lists"),
742            ("(".repeat(deep) + "0" + &")".repeat(deep), "nested tuples"),
743            (
744                "some(".repeat(deep) + "0" + &")".repeat(deep),
745                "nested some()",
746            ),
747            ("ok(".repeat(deep) + "0" + &")".repeat(deep), "nested ok()"),
748            (
749                "{a:".repeat(deep) + "0" + &"}".repeat(deep),
750                "nested records",
751            ),
752            (
753                "v(".repeat(deep) + "0" + &")".repeat(deep),
754                "nested variant payloads",
755            ),
756        ];
757        for (input, desc) in cases {
758            let err = UntypedValue::parse(&input)
759                .expect_err(&alloc::format!("{desc} should be rejected"));
760            assert_eq!(
761                err.kind(),
762                ParserErrorKind::NestingTooDeep,
763                "wrong error kind for {desc}"
764            );
765        }
766    }
767
768    #[test]
769    fn reject_deeply_nested_func_call_params() {
770        let deep = MAX_DEPTH + 1;
771        let input = alloc::format!("f({}0{})", "some(".repeat(deep), ")".repeat(deep));
772        let err = match UntypedFuncCall::parse(&input) {
773            Ok(_) => panic!("deeply nested func call params should be rejected"),
774            Err(err) => err,
775        };
776        assert_eq!(err.kind(), ParserErrorKind::NestingTooDeep);
777    }
778
779    fn parse_value(input: &str, ty: &Type) -> Value {
780        Parser::new(input)
781            .parse_value(ty)
782            .unwrap_or_else(|err| panic!("error decoding {input:?}: {err}"))
783    }
784}