1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use weedle::attribute::{ExtendedAttributeIdent, ExtendedAttributeNamedArgList};
use weedle::{ImplementsDefinition, IncludesStatementDefinition};

/// A WebIDL symbol with 2 identifiers on the left and right side
pub trait SymbolWithIdentifier2<'a>:
	SymbolWithIdentifierLhs<'a> + SymbolWithIdentifierRhs<'a>
{
}

/// A WebIDL symbol with a left-hand side identifier
pub trait SymbolWithIdentifierRhs<'a> {
	fn rhs_identifier(&self) -> weedle::common::Identifier<'a>;
}

/// A WebIDL symbol with a right-hand side identifier
pub trait SymbolWithIdentifierLhs<'a> {
	fn lhs_identifier(&self) -> weedle::common::Identifier<'a>;
}

macro_rules! impl_symbol_with_identifier_lhs {
	($($sym:ident),+ $(,)?) => {
		$(
			impl<'a> SymbolWithIdentifierLhs<'a> for $sym<'a> {
				fn lhs_identifier(&self) -> weedle::common::Identifier<'a> {
					self.lhs_identifier
				}
			}
		)+
	}
}

macro_rules! impl_symbol_with_identifier_rhs {
	($($sym:ident),+ $(,)?) => {
		$(
			impl<'a> SymbolWithIdentifierRhs<'a> for $sym<'a> {
				fn rhs_identifier(&self) -> weedle::common::Identifier<'a> {
					self.rhs_identifier
				}
			}
		)+
	}
}

impl_symbol_with_identifier_lhs!(
	ImplementsDefinition,
	IncludesStatementDefinition,
	ExtendedAttributeNamedArgList,
	ExtendedAttributeIdent,
);

impl_symbol_with_identifier_rhs!(
	ImplementsDefinition,
	IncludesStatementDefinition,
	ExtendedAttributeNamedArgList
);

impl<'a> SymbolWithIdentifier2<'a> for ImplementsDefinition<'a> {}
impl<'a> SymbolWithIdentifier2<'a> for IncludesStatementDefinition<'a> {}
impl<'a> SymbolWithIdentifier2<'a> for ExtendedAttributeNamedArgList<'a> {}

#[cfg(test)]
mod test_identifier2 {
	use crate::symbol::{SymbolWithIdentifierLhs, SymbolWithIdentifierRhs};
	use weedle::common::Identifier;
	use weedle::{ImplementsDefinition, Parse};

	#[rustfmt::skip]
	#[test]
	fn test_implements_definition() {
		let (_, implements) = ImplementsDefinition::parse("FooBar implements Foo;")
			.expect("WebIDL content parsed with an error");

		assert_eq!(implements.lhs_identifier(), Identifier("FooBar"));
		assert_eq!(implements.rhs_identifier(), Identifier("Foo"));
	}
}