use crate::argument::ArgumentList;
use crate::common::{Bracketed, Identifier, Parenthesized, Punctuated};
use crate::literal::StringLit;
pub type ExtendedAttributeList<'a> = Bracketed<Punctuated<ExtendedAttribute<'a>, term!(,)>>;
pub type IdentifierList<'a> = Punctuated<Identifier<'a>, term!(,)>;
ast_types! {
enum ExtendedAttribute<'a> {
ArgList(struct ExtendedAttributeArgList<'a> {
identifier: Identifier<'a>,
args: Parenthesized<ArgumentList<'a>>,
}),
NamedArgList(struct ExtendedAttributeNamedArgList<'a> {
lhs_identifier: Identifier<'a>,
assign: term!(=),
rhs_identifier: Identifier<'a>,
args: Parenthesized<ArgumentList<'a>>,
}),
IdentList(struct ExtendedAttributeIdentList<'a> {
identifier: Identifier<'a>,
assign: term!(=),
list: Parenthesized<IdentifierList<'a>>,
}),
#[derive(Copy)]
Ident(struct ExtendedAttributeIdent<'a> {
lhs_identifier: Identifier<'a>,
assign: term!(=),
rhs: IdentifierOrString<'a>,
}),
#[derive(Copy)]
NoArgs(struct ExtendedAttributeNoArgs<'a>(
Identifier<'a>,
)),
}
#[derive(Copy)]
enum IdentifierOrString<'a> {
Identifier(Identifier<'a>),
String(StringLit<'a>),
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Parse;
test!(should_parse_attribute_no_args { "Replaceable" =>
"";
ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable"))
});
test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" =>
"";
ExtendedAttributeArgList;
identifier.0 == "Constructor";
args.body.list.len() == 2;
});
test!(should_parse_attribute_ident { "PutForwards=name" =>
"";
ExtendedAttributeIdent;
lhs_identifier.0 == "PutForwards";
rhs == IdentifierOrString::Identifier(Identifier("name"));
});
test!(should_parse_ident_list { "Exposed=(Window,Worker)" =>
"";
ExtendedAttributeIdentList;
identifier.0 == "Exposed";
list.body.list.len() == 2;
});
test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" =>
"";
ExtendedAttributeNamedArgList;
lhs_identifier.0 == "NamedConstructor";
rhs_identifier.0 == "Image";
args.body.list.len() == 1;
});
}