diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs new file mode 100644 index 00000000000000..5431f65fe16ffe --- /dev/null +++ b/rust/macros/helpers.rs @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 + +use proc_macro::{token_stream, Group, TokenTree}; + +pub fn try_ident(it: &mut token_stream::IntoIter) -> Option { + if let Some(TokenTree::Ident(ident)) = it.next() { + Some(ident.to_string()) + } else { + None + } +} + +pub fn try_literal(it: &mut token_stream::IntoIter) -> Option { + if let Some(TokenTree::Literal(literal)) = it.next() { + Some(literal.to_string()) + } else { + None + } +} + +pub fn try_byte_string(it: &mut token_stream::IntoIter) -> Option { + try_literal(it).and_then(|byte_string| { + if byte_string.starts_with("b\"") && byte_string.ends_with('\"') { + Some(byte_string[2..byte_string.len() - 1].to_string()) + } else { + None + } + }) +} + +pub fn expect_ident(it: &mut token_stream::IntoIter) -> String { + try_ident(it).expect("Expected Ident") +} + +pub fn expect_punct(it: &mut token_stream::IntoIter) -> char { + if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") { + punct.as_char() + } else { + panic!("Expected Punct"); + } +} + +pub fn expect_literal(it: &mut token_stream::IntoIter) -> String { + try_literal(it).expect("Expected Literal") +} + +pub fn expect_group(it: &mut token_stream::IntoIter) -> Group { + if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") { + group + } else { + panic!("Expected Group"); + } +} + +pub fn expect_byte_string(it: &mut token_stream::IntoIter) -> String { + try_byte_string(it).expect("Expected byte string") +} + +pub fn expect_end(it: &mut token_stream::IntoIter) { + if it.next().is_some() { + panic!("Expected end"); + } +} + +pub fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String { + assert_eq!(expect_ident(it), expected_name); + assert_eq!(expect_punct(it), ':'); + let literal = expect_literal(it); + assert_eq!(expect_punct(it), ','); + literal +} + +pub fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String { + assert_eq!(expect_ident(it), expected_name); + assert_eq!(expect_punct(it), ':'); + let byte_string = expect_byte_string(it); + assert_eq!(expect_punct(it), ','); + byte_string +} diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs index cb7a4f12f3b4dc..f8b818a83ac4c6 100644 --- a/rust/macros/lib.rs +++ b/rust/macros/lib.rs @@ -2,6 +2,7 @@ //! Crate for all kernel procedural macros. +mod helpers; mod module; use proc_macro::TokenStream; diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 1389c53aa228f3..1b445b958913a2 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -2,59 +2,7 @@ use proc_macro::{token_stream, Delimiter, Group, Literal, TokenStream, TokenTree}; -fn try_ident(it: &mut token_stream::IntoIter) -> Option { - if let Some(TokenTree::Ident(ident)) = it.next() { - Some(ident.to_string()) - } else { - None - } -} - -fn try_literal(it: &mut token_stream::IntoIter) -> Option { - if let Some(TokenTree::Literal(literal)) = it.next() { - Some(literal.to_string()) - } else { - None - } -} - -fn try_byte_string(it: &mut token_stream::IntoIter) -> Option { - try_literal(it).and_then(|byte_string| { - if byte_string.starts_with("b\"") && byte_string.ends_with('\"') { - Some(byte_string[2..byte_string.len() - 1].to_string()) - } else { - None - } - }) -} - -fn expect_ident(it: &mut token_stream::IntoIter) -> String { - try_ident(it).expect("Expected Ident") -} - -fn expect_punct(it: &mut token_stream::IntoIter) -> char { - if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") { - punct.as_char() - } else { - panic!("Expected Punct"); - } -} - -fn expect_literal(it: &mut token_stream::IntoIter) -> String { - try_literal(it).expect("Expected Literal") -} - -fn expect_group(it: &mut token_stream::IntoIter) -> Group { - if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") { - group - } else { - panic!("Expected Group"); - } -} - -fn expect_byte_string(it: &mut token_stream::IntoIter) -> String { - try_byte_string(it).expect("Expected byte string") -} +use crate::helpers::*; #[derive(Clone, PartialEq)] enum ParamType { @@ -88,28 +36,6 @@ fn expect_type(it: &mut token_stream::IntoIter) -> ParamType { } } -fn expect_end(it: &mut token_stream::IntoIter) { - if it.next().is_some() { - panic!("Expected end"); - } -} - -fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String { - assert_eq!(expect_ident(it), expected_name); - assert_eq!(expect_punct(it), ':'); - let literal = expect_literal(it); - assert_eq!(expect_punct(it), ','); - literal -} - -fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String { - assert_eq!(expect_ident(it), expected_name); - assert_eq!(expect_punct(it), ':'); - let byte_string = expect_byte_string(it); - assert_eq!(expect_punct(it), ','); - byte_string -} - struct ModInfoBuilder<'a> { module: &'a str, counter: usize,