use argument::ArgumentList;
use attribute::ExtendedAttributeList;
use common::{Braced, Generics, Identifier};
use literal::ConstValue;
use types::{AttributedType, ConstType, ReturnType};
pub type InterfaceMembers<'a> = Vec<InterfaceMember<'a>>;
ast_types! {
#[derive(Copy)]
struct Inheritance<'a> {
colon: term!(:),
identifier: Identifier<'a>,
}
enum InterfaceMember<'a> {
Const(struct ConstMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
const_: term!(const),
const_type: ConstType<'a>,
identifier: Identifier<'a>,
assign: term!(=),
const_value: ConstValue<'a>,
semi_colon: term!(;),
}),
Attribute(struct AttributeInterfaceMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
modifier: Option<StringifierOrInheritOrStatic>,
readonly: Option<term!(readonly)>,
attribute: term!(attribute),
type_: AttributedType<'a>,
identifier: Identifier<'a>,
semi_colon: term!(;),
}),
Operation(struct OperationInterfaceMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
modifier: Option<StringifierOrStatic>,
special: Option<Special>,
return_type: ReturnType<'a>,
identifier: Option<Identifier<'a>>,
args: Braced<ArgumentList<'a>>,
semi_colon: term!(;),
}),
Iterable(enum IterableInterfaceMember<'a> {
Single(struct SingleTypedIterable<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
iterable: term!(iterable),
generics: Generics<AttributedType<'a>>,
semi_colon: term!(;),
}),
Double(struct DoubleTypedIterable<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
iterable: term!(iterable),
generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>,
semi_colon: term!(;),
}),
}),
Maplike(struct MaplikeInterfaceMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
readonly: Option<term!(readonly)>,
maplike: term!(maplike),
generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>,
semi_colon: term!(;),
}),
Setlike(struct SetlikeInterfaceMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
readonly: Option<term!(readonly)>,
setlike: term!(setlike),
generics: Generics<AttributedType<'a>>,
semi_colon: term!(;),
}),
#[derive(Default)]
Stringifier(struct StringifierMember<'a> {
attributes: Option<ExtendedAttributeList<'a>>,
stringifier: term!(stringifier),
semi_colon: term!(;),
}),
}
#[derive(Copy)]
enum Special {
Getter(term!(getter)),
Setter(term!(setter)),
Deleter(term!(deleter)),
LegacyCaller(term!(legacycaller)),
}
#[derive(Copy)]
enum StringifierOrInheritOrStatic {
Stringifier(term!(stringifier)),
Inherit(term!(inherit)),
Static(term!(static)),
}
#[derive(Copy)]
enum StringifierOrStatic {
Stringifier(term!(stringifier)),
Static(term!(static)),
}
}
#[cfg(test)]
mod test {
use super::*;
use Parse;
test!(should_parse_stringifier_member { "stringifier;" =>
"";
StringifierMember;
});
test!(should_parse_stringifier_or_static { "static" =>
"";
StringifierOrStatic;
});
test!(should_parse_stringifier_or_inherit_or_static { "inherit" =>
"";
StringifierOrInheritOrStatic;
});
test!(should_parse_setlike_interface_member { "readonly setlike<long>;" =>
"";
SetlikeInterfaceMember;
attributes.is_none();
readonly == Some(term!(readonly));
});
test!(should_parse_maplike_interface_member { "readonly maplike<long, short>;" =>
"";
MaplikeInterfaceMember;
attributes.is_none();
readonly == Some(term!(readonly));
});
test!(should_parse_attribute_interface_member { "readonly attribute unsigned long width;" =>
"";
AttributeInterfaceMember;
attributes.is_none();
readonly == Some(term!(readonly));
identifier.0 == "width";
});
test!(should_parse_double_typed_iterable { "iterable<long, long>;" =>
"";
DoubleTypedIterable;
attributes.is_none();
});
test!(should_parse_single_typed_iterable { "iterable<long>;" =>
"";
SingleTypedIterable;
attributes.is_none();
});
test!(should_parse_operation_interface_member { "void readString(long a, long b);" =>
"";
OperationInterfaceMember;
attributes.is_none();
modifier.is_none();
special.is_none();
identifier.is_some();
});
test!(should_parse_const_member { "const long name = 5;" =>
"";
ConstMember;
attributes.is_none();
identifier.0 == "name";
});
}