shadowplay/puppet_parser/
argument.rs

1use crate::puppet_parser::{common::capture_comment, range::Range, IResult, ParseError, Span};
2use nom::{
3    bytes::complete::tag,
4    combinator::{map, opt},
5    sequence::{pair, preceded, tuple},
6};
7
8pub fn parse(input: Span) -> IResult<crate::puppet_lang::argument::Argument<Range>> {
9    let parser = tuple((
10        super::common::space0_delimimited(opt(crate::puppet_parser::typing::parse_type_specification)),
11        tag("$"),
12        ParseError::protect(
13            |_| "Invalid variable name".to_owned(),
14            crate::puppet_parser::identifier::identifier,
15        ),
16        opt(preceded(
17            crate::puppet_parser::common::space0_delimimited(tag("=")),
18            ParseError::protect(
19                |_| "Expected expression after '='".to_owned(),
20                crate::puppet_parser::expression::parse_expression,
21            ),
22        )),
23    ));
24
25    map(
26        pair(capture_comment, parser),
27        move |(comment, (type_spec, dollar_sign, name, default))| {
28            let start_range = match &type_spec {
29                None => Range::from((dollar_sign, dollar_sign)),
30                Some(v) => v.extra.clone(),
31            };
32            let end_range = match &default {
33                None => Range::from((name, name)),
34                Some(v) => v.extra.clone(),
35            };
36            crate::puppet_lang::argument::Argument {
37                type_spec,
38                extra: Range::from((&start_range, &end_range)),
39                name: name.to_string(),
40                default,
41                comment,
42            }
43        },
44    )(input)
45}
46
47// #[test]
48// fn test_argument() {
49//     assert_eq!(
50//         Argument::parse(Span::new("Any $v   =  1")).unwrap().1,
51//         Marked {
52//             line: 1,
53//             column: 1,
54//             data: Argument {
55//                 type_spec: Some(Marked {
56//                     line: 1,
57//                     column: 1,
58//                     data: super::typing::TypeSpecification::Any
59//                 }),
60//                 name: "v".to_owned(),
61//                 default: Some(Marked {
62//                     line: 1,
63//                     column: 13,
64//                     data: super::expression::Expression::Term(super::expression::Term::Integer(1))
65//                 })
66//             }
67//         }
68//     );
69
70//     assert!(tuple((
71//         super::common::space0_delimimited(opt(super::typing::TypeSpecification::parse)),
72//         tag("$")
73//     ))(Span::new("Hash[String, String] $aaa"))
74//     .is_ok());
75//     assert!(Argument::parse(Span::new("Hash[String, String] $aaa")).is_ok());
76// }