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