rsass/parser/
formalargs.rs1use super::strings::name;
2use super::util::{ignore_comments, opt_spacelike};
3use super::value::space_list;
4use super::{PResult, Span};
5use crate::sass::{CallArgs, FormalArgs, Name};
6use nom::bytes::complete::tag;
7use nom::character::complete::char;
8use nom::combinator::{cut, map, map_res, opt};
9use nom::error::context;
10use nom::multi::separated_list0;
11use nom::sequence::{delimited, pair, preceded, terminated};
12use nom::Parser as _;
13
14pub fn formal_args(input: Span) -> PResult<FormalArgs> {
15 let (input, _) = terminated(char('('), opt_spacelike).parse(input)?;
16 let (input, v) = separated_list0(
17 preceded(tag(","), opt_spacelike),
18 map(
19 pair(
20 delimited(tag("$"), name, opt_spacelike),
21 opt(delimited(
22 terminated(tag(":"), opt_spacelike),
23 cut(context("Expected expression.", space_list)),
24 opt_spacelike,
25 )),
26 ),
27 |(name, d)| (name.into(), d),
28 ),
29 )
30 .parse(input)?;
31 let (input, va) = if !v.is_empty() {
32 terminated(
33 opt(tag("...")),
34 preceded(opt_spacelike, terminated(opt(tag(",")), opt_spacelike)),
35 )
36 .parse(input)?
37 } else {
38 (input, None)
39 };
40 let (input, _) = char(')')(input)?;
41 Ok((
42 input,
43 if va.is_none() {
44 FormalArgs::new(v)
45 } else {
46 FormalArgs::new_va(v)
47 },
48 ))
49}
50
51pub fn call_args(input: Span) -> PResult<CallArgs> {
52 delimited(
53 terminated(char('('), opt_spacelike),
54 map_res(
55 |input| {
56 let (input, args) = separated_list0(
57 terminated(tag(","), opt_spacelike),
58 pair(
59 opt(map(
60 delimited(
61 tag("$"),
62 name,
63 delimited(
64 ignore_comments,
65 char(':'),
66 opt_spacelike,
67 ),
68 ),
69 Name::from,
70 )),
71 terminated(space_list, opt_spacelike),
72 ),
73 )
74 .parse(input)?;
75 let (input, trail) = if !args.is_empty() {
76 opt(terminated(char(','), opt_spacelike)).parse(input)?
77 } else {
78 (input, None)
79 };
80 Ok((input, (args, trail)))
81 },
82 |(args, trail)| CallArgs::new(args, trail.is_some()),
83 ),
84 cut(char(')')),
85 )
86 .parse(input)
87}