cxx_gen/syntax/
namespace.rs

1use crate::syntax::qualified::QualifiedName;
2use std::slice::Iter;
3use syn::parse::{Error, Parse, ParseStream, Result};
4use syn::{Expr, Ident, Lit, Meta, Token};
5
6mod kw {
7    #[allow(non_camel_case_types)]
pub struct namespace {
    #[allow(dead_code)]
    pub span: ::syn::__private::Span,
}
#[doc(hidden)]
#[allow(dead_code, non_snake_case)]
pub fn namespace<__S: ::syn::__private::IntoSpans<::syn::__private::Span>>(span:
        __S) -> namespace {
    namespace { span: ::syn::__private::IntoSpans::into_spans(span) }
}
const _: () =
    {
        impl ::syn::__private::Default for namespace {
            fn default() -> Self {
                namespace { span: ::syn::__private::Span::call_site() }
            }
        }
        impl ::syn::__private::CustomToken for namespace {
            fn peek(cursor: ::syn::buffer::Cursor) -> ::syn::__private::bool {
                if let ::syn::__private::Some((ident, _rest)) = cursor.ident()
                    {
                    ident == "namespace"
                } else { false }
            }
            fn display() -> &'static ::syn::__private::str { "`namespace`" }
        }
        impl ::syn::parse::Parse for namespace {
            fn parse(input: ::syn::parse::ParseStream)
                -> ::syn::parse::Result<namespace> {
                input.step(|cursor|
                        {
                            if let ::syn::__private::Some((ident, rest)) =
                                    cursor.ident() {
                                if ident == "namespace" {
                                    return ::syn::__private::Ok((namespace {
                                                    span: ident.span(),
                                                }, rest));
                                }
                            }
                            ::syn::__private::Err(cursor.error("expected `namespace`"))
                        })
            }
        }
        impl ::syn::__private::ToTokens for namespace {
            fn to_tokens(&self, tokens: &mut ::syn::__private::TokenStream2) {
                let ident = ::syn::Ident::new("namespace", self.span);
                ::syn::__private::TokenStreamExt::append(tokens, ident);
            }
        }
        impl ::syn::__private::Copy for namespace {}
        #[allow(clippy :: expl_impl_clone_on_copy)]
        impl ::syn::__private::Clone for namespace {
            fn clone(&self) -> Self { *self }
        }
        ;
    };syn::custom_keyword!(namespace);
8}
9
10#[derive(#[automatically_derived]
impl ::core::clone::Clone for Namespace {
    #[inline]
    fn clone(&self) -> Namespace {
        Namespace { segments: ::core::clone::Clone::clone(&self.segments) }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for Namespace {
    #[inline]
    fn default() -> Namespace {
        Namespace { segments: ::core::default::Default::default() }
    }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for Namespace {
    #[inline]
    fn eq(&self, other: &Namespace) -> bool {
        self.segments == other.segments
    }
}PartialEq)]
11pub(crate) struct Namespace {
12    segments: Vec<Ident>,
13}
14
15impl Namespace {
16    pub(crate) const ROOT: Self = Namespace {
17        segments: Vec::new(),
18    };
19
20    pub(crate) fn iter(&self) -> Iter<Ident> {
21        self.segments.iter()
22    }
23
24    pub(crate) fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Self> {
25        if input.is_empty() {
26            return Ok(Namespace::ROOT);
27        }
28
29        input.parse::<kw::namespace>()?;
30        input.parse::<Token![=]>()?;
31        let namespace = input.parse::<Namespace>()?;
32        input.parse::<Option<Token![,]>>()?;
33        Ok(namespace)
34    }
35
36    pub(crate) fn parse_meta(meta: &Meta) -> Result<Self> {
37        if let Meta::NameValue(meta) = meta {
38            match &meta.value {
39                Expr::Lit(expr) => {
40                    if let Lit::Str(lit) = &expr.lit {
41                        let segments = QualifiedName::parse_quoted(lit)?.segments;
42                        return Ok(Namespace { segments });
43                    }
44                }
45                Expr::Path(expr)
46                    if expr.qself.is_none()
47                        && expr
48                            .path
49                            .segments
50                            .iter()
51                            .all(|segment| segment.arguments.is_none()) =>
52                {
53                    let segments = expr
54                        .path
55                        .segments
56                        .iter()
57                        .map(|segment| segment.ident.clone())
58                        .collect();
59                    return Ok(Namespace { segments });
60                }
61                _ => {}
62            }
63        }
64        Err(Error::new_spanned(meta, "unsupported namespace attribute"))
65    }
66}
67
68impl Default for &Namespace {
69    fn default() -> Self {
70        const ROOT: &Namespace = &Namespace::ROOT;
71        ROOT
72    }
73}
74
75impl Parse for Namespace {
76    fn parse(input: ParseStream) -> Result<Self> {
77        let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;
78        Ok(Namespace { segments })
79    }
80}
81
82impl<'a> IntoIterator for &'a Namespace {
83    type Item = &'a Ident;
84    type IntoIter = Iter<'a, Ident>;
85    fn into_iter(self) -> Self::IntoIter {
86        self.iter()
87    }
88}
89
90impl<'a> FromIterator<&'a Ident> for Namespace {
91    fn from_iter<I>(idents: I) -> Self
92    where
93        I: IntoIterator<Item = &'a Ident>,
94    {
95        let segments = idents.into_iter().cloned().collect();
96        Namespace { segments }
97    }
98}