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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::*;
#[derive(Debug, Default, Clone)]
pub struct ExtensionRequirement {
pub api: Option<String>,
pub profile: Option<String>,
pub items: Vec<FeatureRequirement>,
}
#[derive(Debug, Default, Clone)]
pub struct Extension {
pub name: String,
pub supported: String,
pub requirements: Vec<ExtensionRequirement>,
}
#[derive(Debug, Default, Clone)]
pub struct Extensions(pub(crate) Vec<Extension>);
#[must_use]
pub fn pull_extensions(
it: &mut XmlIterator<'_>,
extensions: &mut Extensions,
) -> Option<()> {
loop {
match it.next()? {
EndTag { name: "extensions" } => return Some(()),
StartTag { name: "extension", attrs } => {
let mut name = None;
let mut supported = None;
for (k, v) in AttributeIterator::new(attrs) {
match k {
"name" => name = Some(v.to_owned()),
"supported" => supported = Some(v.to_owned()),
"comment" => (),
_ => panic!("unknown extension attr: {}", attrs),
}
}
let name = name.unwrap();
let supported = supported.unwrap();
let mut requirements: Vec<ExtensionRequirement> = vec![];
'gather_extension: loop {
match it.next()? {
EndTag { name: "extension" } => break 'gather_extension,
StartTag { name: "require", attrs } => {
let mut api = None;
let mut profile = None;
let mut items = vec![];
for (k, v) in AttributeIterator::new(attrs) {
match k {
"comment" => (),
"api" => api = Some(v.to_owned()),
"profile" => profile = Some(v.to_owned()),
_ => panic!("unknown `require` attrs: {}", attrs),
}
}
'gather_require: loop {
match it.next()? {
EndTag { name: "require" } => break 'gather_require,
EmptyTag { name: "type", attrs } => {
let name = match AttributeIterator::new(attrs).next() {
Some(("name", v)) => v.to_owned(),
_ => panic!("unexpected attrs: {}", attrs),
};
items.push(FeatureRequirement::Type { name });
}
EmptyTag { name: "enum", attrs } => {
let name = match AttributeIterator::new(attrs).next() {
Some(("name", v)) => v.to_owned(),
_ => panic!("unexpected attrs: {}", attrs),
};
items.push(FeatureRequirement::Enum { name });
}
EmptyTag { name: "command", attrs } => {
let name = match AttributeIterator::new(attrs).next() {
Some(("name", v)) => v.to_owned(),
_ => panic!("unexpected attrs: {}", attrs),
};
items.push(FeatureRequirement::Command { name });
}
other => panic!(
"unhandled in extensions/extension/require: {:?}",
other
),
}
}
requirements.push(ExtensionRequirement { api, profile, items });
}
other => panic!("unhandled in extensions/extension: {:?}", other),
}
}
extensions.0.push(Extension { name, supported, requirements });
}
EmptyTag { name: "extension", attrs } => {
let mut name = None;
let mut supported = None;
for (k, v) in AttributeIterator::new(attrs) {
match k {
"name" => name = Some(v.to_owned()),
"supported" => supported = Some(v.to_owned()),
_ => panic!("unknown `extension` attr: {}", attrs),
}
}
let name = name.unwrap();
let supported = supported.unwrap();
let requirements = vec![];
extensions.0.push(Extension { name, supported, requirements });
}
other => panic!("unhandled in extensions: {:?}", other),
}
}
}