Skip to content

Commit c677a79

Browse files
committed
rust: module! macro cleanup using buffer
Make use of `syn` buffer's lookahead capability to remove `try_*` parsing functions. Signed-off-by: Gary Guo <gary@garyguo.net>
1 parent fc7c60f commit c677a79

File tree

1 file changed

+103
-117
lines changed

1 file changed

+103
-117
lines changed

rust/macros/module.rs

Lines changed: 103 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -5,70 +5,55 @@
55
#![deny(clippy::perf)]
66
#![deny(clippy::style)]
77

8-
use crate::syn::Lit;
9-
use proc_macro::{token_stream, Delimiter, Group, Literal, TokenStream, TokenTree};
10-
11-
fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
12-
if let Some(TokenTree::Ident(ident)) = it.next() {
13-
Some(ident.to_string())
14-
} else {
15-
None
16-
}
17-
}
18-
19-
fn try_literal(it: &mut token_stream::IntoIter) -> Option<Literal> {
20-
if let Some(TokenTree::Literal(literal)) = it.next() {
21-
Some(literal)
22-
} else {
23-
None
24-
}
25-
}
26-
27-
fn try_string(it: &mut token_stream::IntoIter) -> Option<String> {
28-
try_literal(it).and_then(|literal| match Lit::new(literal) {
29-
Lit::Str(s) => {
30-
assert!(s.suffix().is_empty(), "Unexpected suffix");
31-
Some(s.value())
32-
}
33-
_ => None,
34-
})
8+
use crate::syn::{
9+
buffer::{Cursor, TokenBuffer},
10+
Lit,
11+
};
12+
use proc_macro::{Delimiter, Literal, TokenStream};
13+
14+
fn expect_ident(it: &mut Cursor<'_>) -> String {
15+
let (ident, next) = it.ident().expect("Expected Ident");
16+
*it = next;
17+
ident.to_string()
3518
}
3619

37-
fn expect_ident(it: &mut token_stream::IntoIter) -> String {
38-
try_ident(it).expect("Expected Ident")
20+
fn expect_punct(it: &mut Cursor<'_>) -> char {
21+
let (punct, next) = it.punct().expect("Expected Punct");
22+
*it = next;
23+
punct.as_char()
3924
}
4025

41-
fn expect_punct(it: &mut token_stream::IntoIter) -> char {
42-
if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
43-
punct.as_char()
44-
} else {
45-
panic!("Expected Punct");
46-
}
26+
fn expect_literal(it: &mut Cursor<'_>) -> Literal {
27+
let (lit, next) = it.literal().expect("Expected Literal");
28+
*it = next;
29+
lit
4730
}
4831

49-
fn expect_literal(it: &mut token_stream::IntoIter) -> Literal {
50-
try_literal(it).expect("Expected Literal")
32+
fn expect_group<'a>(it: &mut Cursor<'a>, delim: Delimiter) -> Cursor<'a> {
33+
let (inner, _, next) = it.group(delim).expect("Expected Group");
34+
*it = next;
35+
inner
5136
}
5237

53-
fn expect_group(it: &mut token_stream::IntoIter) -> Group {
54-
if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
55-
group
56-
} else {
57-
panic!("Expected Group");
38+
fn expect_string(it: &mut Cursor<'_>) -> String {
39+
let lit = expect_literal(it);
40+
let lit = Lit::new(lit);
41+
match &lit {
42+
Lit::Str(s) => {
43+
assert!(s.suffix().is_empty(), "Unexpected suffix");
44+
s.value()
45+
}
46+
_ => panic!("Expected string"),
5847
}
5948
}
6049

61-
fn expect_string(it: &mut token_stream::IntoIter) -> String {
62-
try_string(it).expect("Expected string")
63-
}
64-
6550
#[derive(Clone, PartialEq)]
6651
enum ParamType {
6752
Ident(String),
6853
Array { vals: String, max_length: usize },
6954
}
7055

71-
fn expect_array_fields(it: &mut token_stream::IntoIter) -> ParamType {
56+
fn expect_array_fields(it: &mut Cursor<'_>) -> ParamType {
7257
assert_eq!(expect_punct(it), '<');
7358
let vals = expect_ident(it);
7459
assert_eq!(expect_punct(it), ',');
@@ -80,35 +65,47 @@ fn expect_array_fields(it: &mut token_stream::IntoIter) -> ParamType {
8065
ParamType::Array { vals, max_length }
8166
}
8267

83-
fn expect_type(it: &mut token_stream::IntoIter) -> ParamType {
84-
if let TokenTree::Ident(ident) = it
85-
.next()
86-
.expect("Reached end of token stream for param type")
87-
{
88-
match ident.to_string().as_ref() {
89-
"ArrayParam" => expect_array_fields(it),
90-
_ => ParamType::Ident(ident.to_string()),
91-
}
92-
} else {
93-
panic!("Expected Param Type")
68+
fn expect_type(it: &mut Cursor<'_>) -> ParamType {
69+
let (ident, next) = it.ident().expect("Expected Param Type");
70+
*it = next;
71+
match ident.to_string().as_ref() {
72+
"ArrayParam" => expect_array_fields(it),
73+
_ => ParamType::Ident(ident.to_string()),
9474
}
9575
}
9676

97-
fn expect_end(it: &mut token_stream::IntoIter) {
98-
if it.next().is_some() {
99-
panic!("Expected end");
77+
fn expect_end(it: &mut Cursor<'_>) {
78+
assert!(it.eof(), "Expected end");
79+
}
80+
81+
fn parse_list<T>(
82+
it: &mut Cursor<'_>,
83+
delim: Delimiter,
84+
f: impl Fn(&mut Cursor<'_>) -> T,
85+
) -> Vec<T> {
86+
let mut inner = expect_group(it, delim);
87+
let mut vec = Vec::new();
88+
while !inner.eof() {
89+
let item = f(&mut inner);
90+
vec.push(item);
91+
if inner.eof() {
92+
break;
93+
}
94+
assert_eq!(expect_punct(&mut inner), ',');
10095
}
96+
assert!(inner.eof(), "Expected end");
97+
vec
10198
}
10299

103-
fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
100+
fn get_literal(it: &mut Cursor<'_>, expected_name: &str) -> String {
104101
assert_eq!(expect_ident(it), expected_name);
105102
assert_eq!(expect_punct(it), ':');
106103
let literal = expect_literal(it).to_string();
107104
assert_eq!(expect_punct(it), ',');
108105
literal
109106
}
110107

111-
fn get_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
108+
fn get_string(it: &mut Cursor<'_>, expected_name: &str) -> String {
112109
assert_eq!(expect_ident(it), expected_name);
113110
assert_eq!(expect_punct(it), ':');
114111
let byte_string = expect_string(it);
@@ -237,53 +234,45 @@ fn param_ops_path(param_type: &str) -> &'static str {
237234
}
238235
}
239236

240-
fn try_simple_param_val(
241-
param_type: &str,
242-
) -> Box<dyn Fn(&mut token_stream::IntoIter) -> Option<String>> {
237+
fn expect_simple_param_val(param_type: &str) -> Box<dyn Fn(&mut Cursor<'_>) -> String> {
243238
match param_type {
244-
"bool" => Box::new(|param_it| try_ident(param_it)),
239+
"bool" => Box::new(|param_it| {
240+
let (ident, next) = param_it.ident().expect("Expected ident");
241+
*param_it = next;
242+
ident.to_string()
243+
}),
245244
"str" => Box::new(|param_it| {
246-
try_string(param_it).map(|s| {
247-
format!(
248-
"kernel::module_param::StringParam::Ref({})",
249-
Literal::byte_string(s.as_bytes())
250-
)
251-
})
245+
let s = expect_string(param_it);
246+
format!(
247+
"kernel::module_param::StringParam::Ref({})",
248+
Literal::byte_string(s.as_bytes())
249+
)
250+
}),
251+
_ => Box::new(|param_it| {
252+
let (lit, next) = param_it.literal().expect("Expected literal");
253+
*param_it = next;
254+
lit.to_string()
252255
}),
253-
_ => Box::new(|param_it| try_literal(param_it).map(|x| x.to_string())),
254256
}
255257
}
256258

257-
fn get_default(param_type: &ParamType, param_it: &mut token_stream::IntoIter) -> String {
258-
let try_param_val = match param_type {
259+
fn get_default(param_type: &ParamType, param_it: &mut Cursor<'_>) -> String {
260+
let expect_param_val = match param_type {
259261
ParamType::Ident(ref param_type)
260262
| ParamType::Array {
261263
vals: ref param_type,
262264
max_length: _,
263-
} => try_simple_param_val(param_type),
265+
} => expect_simple_param_val(param_type),
264266
};
265267
assert_eq!(expect_ident(param_it), "default");
266268
assert_eq!(expect_punct(param_it), ':');
267269
let default = match param_type {
268-
ParamType::Ident(_) => try_param_val(param_it).expect("Expected default param value"),
270+
ParamType::Ident(_) => expect_param_val(param_it),
269271
ParamType::Array {
270272
vals: _,
271273
max_length: _,
272274
} => {
273-
let group = expect_group(param_it);
274-
assert_eq!(group.delimiter(), Delimiter::Bracket);
275-
let mut default_vals = Vec::new();
276-
let mut it = group.stream().into_iter();
277-
278-
while let Some(default_val) = try_param_val(&mut it) {
279-
default_vals.push(default_val);
280-
match it.next() {
281-
Some(TokenTree::Punct(punct)) => assert_eq!(punct.as_char(), ','),
282-
None => break,
283-
_ => panic!("Expected ',' or end of array default values"),
284-
}
285-
}
286-
275+
let default_vals = parse_list(param_it, Delimiter::Bracket, expect_param_val);
287276
let mut default_array = "kernel::module_param::ArrayParam::create(&[".to_string();
288277
default_array.push_str(
289278
&default_vals
@@ -308,19 +297,19 @@ fn generated_array_ops_name(vals: &str, max_length: usize) -> String {
308297
)
309298
}
310299

311-
#[derive(Debug, Default)]
312-
struct ModuleInfo {
300+
#[derive(Default)]
301+
struct ModuleInfo<'a> {
313302
type_: String,
314303
license: String,
315304
name: String,
316305
author: Option<String>,
317306
description: Option<String>,
318307
alias: Option<String>,
319-
params: Option<Group>,
308+
params: Option<Cursor<'a>>,
320309
}
321310

322-
impl ModuleInfo {
323-
fn parse(it: &mut token_stream::IntoIter) -> Self {
311+
impl<'a> ModuleInfo<'a> {
312+
fn parse(it: &mut Cursor<'a>) -> Self {
324313
let mut info = ModuleInfo::default();
325314

326315
const EXPECTED_KEYS: &[&str] = &[
@@ -337,11 +326,11 @@ impl ModuleInfo {
337326
let mut seen_keys = Vec::new();
338327

339328
loop {
340-
let key = match it.next() {
341-
Some(TokenTree::Ident(ident)) => ident.to_string(),
342-
Some(_) => panic!("Expected Ident or end"),
343-
None => break,
344-
};
329+
if it.eof() {
330+
break;
331+
}
332+
333+
let key = expect_ident(it);
345334

346335
if seen_keys.contains(&key) {
347336
panic!(
@@ -360,7 +349,7 @@ impl ModuleInfo {
360349
"license" => info.license = expect_string(it),
361350
"alias" => info.alias = Some(expect_string(it)),
362351
"alias_rtnl_link" => info.alias = Some(format!("rtnl-link-{}", expect_string(it))),
363-
"params" => info.params = Some(expect_group(it)),
352+
"params" => info.params = Some(expect_group(it, Delimiter::Brace)),
364353
_ => panic!(
365354
"Unknown key \"{}\". Valid keys are: {:?}.",
366355
key, EXPECTED_KEYS
@@ -399,7 +388,8 @@ impl ModuleInfo {
399388
}
400389

401390
pub fn module(ts: TokenStream) -> TokenStream {
402-
let mut it = ts.into_iter();
391+
let buffer = TokenBuffer::new(ts);
392+
let mut it = buffer.begin();
403393

404394
let info = ModuleInfo::parse(&mut it);
405395

@@ -408,25 +398,20 @@ pub fn module(ts: TokenStream) -> TokenStream {
408398
let mut array_types_to_generate = Vec::new();
409399
let mut params_modinfo = String::new();
410400
if let Some(params) = info.params {
411-
assert_eq!(params.delimiter(), Delimiter::Brace);
412-
413-
let mut it = params.stream().into_iter();
401+
let mut it = params;
414402

415403
loop {
416-
let param_name = match it.next() {
417-
Some(TokenTree::Ident(ident)) => ident.to_string(),
418-
Some(_) => panic!("Expected Ident or end"),
419-
None => break,
420-
};
404+
if it.eof() {
405+
break;
406+
}
407+
408+
let param_name = expect_ident(&mut it);
421409

422410
assert_eq!(expect_punct(&mut it), ':');
423411
let param_type = expect_type(&mut it);
424-
let group = expect_group(&mut it);
412+
let mut param_it = expect_group(&mut it, Delimiter::Brace);
425413
assert_eq!(expect_punct(&mut it), ',');
426414

427-
assert_eq!(group.delimiter(), Delimiter::Brace);
428-
429-
let mut param_it = group.stream().into_iter();
430415
let param_default = get_default(&param_type, &mut param_it);
431416
let param_permissions = get_literal(&mut param_it, "permissions");
432417
let param_description = get_string(&mut param_it, "description");
@@ -695,7 +680,8 @@ pub fn module(ts: TokenStream) -> TokenStream {
695680
}
696681

697682
pub fn module_misc_device(ts: TokenStream) -> TokenStream {
698-
let mut it = ts.into_iter();
683+
let buffer = TokenBuffer::new(ts);
684+
let mut it = buffer.begin();
699685

700686
let info = ModuleInfo::parse(&mut it);
701687

0 commit comments

Comments
 (0)