Skip to content

Commit 81fea68

Browse files
authored
Merge pull request #241 from ojeda/module
rust: module: improve parsing and errors
2 parents 1df65b6 + 7af2210 commit 81fea68

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed

rust/module.rs

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -321,81 +321,82 @@ struct ModuleInfo {
321321
impl ModuleInfo {
322322
fn parse(it: &mut token_stream::IntoIter) -> Self {
323323
let mut info = ModuleInfo::default();
324-
// The first allowed position is 1, to prevent setting something twice.
325-
let mut pos = 0u8;
324+
325+
const EXPECTED_KEYS: &[&str] = &[
326+
"type",
327+
"name",
328+
"author",
329+
"description",
330+
"license",
331+
"alias",
332+
"alias_rtnl_link",
333+
"params",
334+
];
335+
const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
336+
let mut seen_keys = Vec::new();
326337

327338
loop {
328-
let name = match it.next() {
339+
let key = match it.next() {
329340
Some(TokenTree::Ident(ident)) => ident.to_string(),
330341
Some(_) => panic!("Expected Ident or end"),
331342
None => break,
332343
};
333344

345+
if seen_keys.contains(&key) {
346+
panic!(
347+
"Duplicated key \"{}\". Keys can only be specified once.",
348+
key
349+
);
350+
}
351+
334352
assert_eq!(expect_punct(it), ':');
335353

336-
if name == "type" {
337-
Self::allowed_pos(&mut pos, 1, &name);
338-
let type_ = expect_ident(it);
339-
info.type_ = type_;
340-
} else if name == "params" {
341-
Self::allowed_pos(&mut pos, 7, &name);
342-
let params = expect_group(it);
343-
info.params = Some(params);
344-
} else {
345-
let value = expect_byte_string(it);
346-
347-
match name.as_str() {
348-
"name" => {
349-
Self::allowed_pos(&mut pos, 2, &name);
350-
info.name = value;
351-
}
352-
"author" => {
353-
Self::allowed_pos(&mut pos, 3, &name);
354-
info.author = Some(value);
355-
}
356-
"description" => {
357-
Self::allowed_pos(&mut pos, 4, &name);
358-
info.description = Some(value);
359-
}
360-
"license" => {
361-
Self::allowed_pos(&mut pos, 5, &name);
362-
info.license = value;
363-
}
364-
"alias" => {
365-
Self::allowed_pos(&mut pos, 6, &name);
366-
info.alias = Some(value);
367-
}
368-
"alias_rtnl_link" => {
369-
Self::allowed_pos(&mut pos, 6, &name);
370-
info.alias = Some(format!("rtnl-link-{}", value));
371-
}
372-
_ => panic!("field '{}' is not supported by module", name),
354+
match key.as_str() {
355+
"type" => info.type_ = expect_ident(it),
356+
"name" => info.name = expect_byte_string(it),
357+
"author" => info.author = Some(expect_byte_string(it)),
358+
"description" => info.description = Some(expect_byte_string(it)),
359+
"license" => info.license = expect_byte_string(it),
360+
"alias" => info.alias = Some(expect_byte_string(it)),
361+
"alias_rtnl_link" => {
362+
info.alias = Some(format!("rtnl-link-{}", expect_byte_string(it)))
373363
}
364+
"params" => info.params = Some(expect_group(it)),
365+
_ => panic!(
366+
"Unknown key \"{}\". Valid keys are: {:?}.",
367+
key, EXPECTED_KEYS
368+
),
374369
}
370+
375371
assert_eq!(expect_punct(it), ',');
372+
373+
seen_keys.push(key);
376374
}
377375

378376
expect_end(it);
379377

380-
if info.type_.is_empty() {
381-
panic!("'type' not specified in module macro");
378+
for key in REQUIRED_KEYS {
379+
if !seen_keys.iter().any(|e| e == key) {
380+
panic!("Missing required key \"{}\".", key);
381+
}
382382
}
383-
if info.license.is_empty() {
384-
panic!("'license' not specified in module macro");
383+
384+
let mut ordered_keys: Vec<&str> = Vec::new();
385+
for key in EXPECTED_KEYS {
386+
if seen_keys.iter().any(|e| e == key) {
387+
ordered_keys.push(key);
388+
}
385389
}
386-
if info.name.is_empty() {
387-
panic!("'name' not specified in module macro");
390+
391+
if seen_keys != ordered_keys {
392+
panic!(
393+
"Keys are not ordered as expected. Order them like: {:?}.",
394+
ordered_keys
395+
);
388396
}
389397

390398
info
391399
}
392-
393-
fn allowed_pos(pos: &mut u8, allowed_pos: u8, name: &str) {
394-
if *pos > allowed_pos {
395-
panic!("'{}' is not allowed at this position", name);
396-
}
397-
*pos = allowed_pos;
398-
}
399400
}
400401

401402
/// Declares a kernel module.

0 commit comments

Comments
 (0)