Skip to main content

pin_init_internal/
util.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use proc_macro2::{Ident, TokenStream};
4use quote::format_ident;
5use syn::{Attribute, Index, Member};
6
7pub(crate) trait AttrListExt {
8    fn extract_cfg_attrs(&mut self) -> Vec<TokenStream>;
9}
10
11impl AttrListExt for Vec<Attribute> {
12    fn extract_cfg_attrs(&mut self) -> Vec<TokenStream> {
13        let cfg: Vec<_> = self
14            .iter()
15            .filter(|a| a.path().is_ident("cfg"))
16            .map(|a| {
17                a.parse_args::<TokenStream>()
18                    .expect("parse as token stream cannot fail")
19            })
20            .collect();
21
22        if !cfg.is_empty() {
23            self.retain(|a| !a.path().is_ident("cfg"));
24        }
25
26        cfg
27    }
28}
29
30pub(crate) trait MemberExt {
31    /// Returns an identifier for the member.
32    ///
33    /// Tuple fields have no name of their own, so they are named `_0`, `_1`, ... instead.
34    fn as_ident(&self) -> Ident;
35
36    /// Obtain a display name for the member in diagnostics.
37    fn display_name(&self) -> String;
38}
39
40impl MemberExt for Member {
41    fn as_ident(&self) -> Ident {
42        match self {
43            Member::Named(ident) => ident.clone(),
44            Member::Unnamed(Index { index, span }) => format_ident!("_{index}", span = *span),
45        }
46    }
47
48    fn display_name(&self) -> String {
49        match self {
50            Member::Named(ident) => format!("`{ident}`"),
51            Member::Unnamed(Index { index, .. }) => format!("index `{index}`"),
52        }
53    }
54}