xref: /linux/rust/macros/helpers.rs (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 use proc_macro2::TokenStream;
4 use quote::ToTokens;
5 use syn::{
6     parse::{
7         Parse,
8         ParseStream, //
9     },
10     Attribute,
11     Error,
12     LitStr,
13     Result, //
14 };
15 
16 /// A string literal that is required to have ASCII value only.
17 pub(crate) struct AsciiLitStr(LitStr);
18 
19 impl Parse for AsciiLitStr {
20     fn parse(input: ParseStream<'_>) -> Result<Self> {
21         let s: LitStr = input.parse()?;
22         if !s.value().is_ascii() {
23             return Err(Error::new_spanned(s, "expected ASCII-only string literal"));
24         }
25         Ok(Self(s))
26     }
27 }
28 
29 impl ToTokens for AsciiLitStr {
30     fn to_tokens(&self, ts: &mut TokenStream) {
31         self.0.to_tokens(ts);
32     }
33 }
34 
35 impl AsciiLitStr {
36     pub(crate) fn value(&self) -> String {
37         self.0.value()
38     }
39 }
40 
41 pub(crate) fn file() -> String {
42     #[cfg(not(CONFIG_RUSTC_HAS_SPAN_FILE))]
43     {
44         proc_macro::Span::call_site()
45             .source_file()
46             .path()
47             .to_string_lossy()
48             .into_owned()
49     }
50 
51     #[cfg(CONFIG_RUSTC_HAS_SPAN_FILE)]
52     #[allow(clippy::incompatible_msrv)]
53     {
54         proc_macro::Span::call_site().file()
55     }
56 }
57 
58 /// Obtain all `#[cfg]` attributes.
59 pub(crate) fn gather_cfg_attrs(attr: &[Attribute]) -> impl Iterator<Item = &Attribute> + '_ {
60     attr.iter().filter(|a| a.path().is_ident("cfg"))
61 }
62