1use crate::attribute::ExtendedAttributeList;
2use crate::common::{Default, Identifier, Punctuated};
3use crate::types::{AttributedType, Type};
4
5pub type ArgumentList<'a> = Punctuated<Argument<'a>, term!(,)>;
7
8ast_types! {
9 enum Argument<'a> {
11 Single(struct SingleArgument<'a> {
15 attributes: Option<ExtendedAttributeList<'a>>,
16 optional: Option<term!(optional)>,
17 type_: AttributedType<'a>,
18 identifier: Identifier<'a>,
19 default: Option<Default<'a>> = nom::combinator::map(
20 nom::combinator::cond(optional.is_some(), weedle!(Option<Default<'a>>)),
21 |default| default.unwrap_or(None)
22 ),
23 }),
24 Variadic(struct VariadicArgument<'a> {
26 attributes: Option<ExtendedAttributeList<'a>>,
27 type_: Type<'a>,
28 ellipsis: term!(...),
29 identifier: Identifier<'a>,
30 }),
31 }
32}
33
34#[cfg(test)]
35mod test {
36 use super::*;
37 use crate::literal::{DecLit, DefaultValue, IntegerLit};
38 use crate::Parse;
39
40 test!(should_parse_single_argument { "short a" =>
41 "";
42 SingleArgument;
43 attributes.is_none();
44 optional.is_none();
45 identifier.0 == "a";
46 default.is_none();
47 });
48
49 test!(should_parse_variadic_argument { "short... a" =>
50 "";
51 VariadicArgument;
52 attributes.is_none();
53 identifier.0 == "a";
54 });
55
56 test!(should_parse_optional_single_argument { "optional short a" =>
57 "";
58 SingleArgument;
59 attributes.is_none();
60 optional.is_some();
61 identifier.0 == "a";
62 default.is_none();
63 });
64
65 test!(should_parse_optional_single_argument_with_default { "optional short a = 5" =>
66 "";
67 SingleArgument;
68 attributes.is_none();
69 optional.is_some();
70 identifier.0 == "a";
71 default == Some(Default {
72 assign: term!(=),
73 value: DefaultValue::Integer(IntegerLit::Dec(DecLit("5"))),
74 });
75 });
76}