blob: 834a1d5933b6c2bb2d953252e2e2750dcc6100b7 [file] [log] [blame]
David Tolnaydd26bd02020-09-06 23:00:17 -07001use crate::syntax::qualified::QualifiedName;
David Tolnay60e7aa62020-11-01 12:34:51 -08002use crate::syntax::Api;
David Tolnayb6cf3142020-04-19 20:56:09 -07003use quote::IdentFragment;
David Tolnay754e21c2020-03-29 20:58:46 -07004use std::fmt::{self, Display};
5use std::slice::Iter;
David Tolnayb6cf3142020-04-19 20:56:09 -07006use syn::parse::{Parse, ParseStream, Result};
David Tolnaydd26bd02020-09-06 23:00:17 -07007use syn::{Ident, Token};
David Tolnayb6cf3142020-04-19 20:56:09 -07008
9mod kw {
10 syn::custom_keyword!(namespace);
11}
David Tolnay754e21c2020-03-29 20:58:46 -070012
13#[derive(Clone)]
14pub struct Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070015 segments: Vec<Ident>,
David Tolnay754e21c2020-03-29 20:58:46 -070016}
17
18impl Namespace {
David Tolnay4ebde542020-11-01 14:23:31 -080019 pub const ROOT: Self = Namespace {
20 segments: Vec::new(),
21 };
David Tolnay754e21c2020-03-29 20:58:46 -070022
David Tolnay63f92e82020-04-30 20:40:20 -070023 pub fn iter(&self) -> Iter<Ident> {
David Tolnay754e21c2020-03-29 20:58:46 -070024 self.segments.iter()
25 }
Adrian Taylor3e5cff42020-10-29 19:48:45 -070026
27 pub fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Namespace> {
28 if input.is_empty() {
David Tolnay4ebde542020-11-01 14:23:31 -080029 return Ok(Namespace::ROOT);
Adrian Taylor3e5cff42020-10-29 19:48:45 -070030 }
31
32 input.parse::<kw::namespace>()?;
33 input.parse::<Token![=]>()?;
34 let ns = input.parse::<Namespace>()?;
35 input.parse::<Option<Token![,]>>()?;
36 Ok(ns)
37 }
David Tolnay754e21c2020-03-29 20:58:46 -070038}
39
David Tolnayb6cf3142020-04-19 20:56:09 -070040impl Parse for Namespace {
41 fn parse(input: ParseStream) -> Result<Self> {
Adrian Taylor3e5cff42020-10-29 19:48:45 -070042 let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;
David Tolnayb6cf3142020-04-19 20:56:09 -070043 Ok(Namespace { segments })
44 }
45}
46
David Tolnay754e21c2020-03-29 20:58:46 -070047impl Display for Namespace {
48 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49 for segment in self {
David Tolnay63f92e82020-04-30 20:40:20 -070050 write!(f, "{}$", segment)?;
David Tolnay754e21c2020-03-29 20:58:46 -070051 }
52 Ok(())
53 }
54}
55
David Tolnayb6cf3142020-04-19 20:56:09 -070056impl IdentFragment for Namespace {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 Display::fmt(self, f)
59 }
60}
61
David Tolnay754e21c2020-03-29 20:58:46 -070062impl<'a> IntoIterator for &'a Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070063 type Item = &'a Ident;
64 type IntoIter = Iter<'a, Ident>;
David Tolnay754e21c2020-03-29 20:58:46 -070065 fn into_iter(self) -> Self::IntoIter {
66 self.iter()
67 }
68}
David Tolnay60e7aa62020-11-01 12:34:51 -080069
70impl Api {
David Tolnay68a12182020-11-01 12:41:55 -080071 pub fn namespace(&self) -> Option<&Namespace> {
David Tolnay60e7aa62020-11-01 12:34:51 -080072 match self {
David Tolnay6ec41112020-11-01 12:40:38 -080073 Api::CxxFunction(efn) | Api::RustFunction(efn) => Some(&efn.ident.cxx.ns),
74 Api::CxxType(ety) | Api::RustType(ety) => Some(&ety.ident.cxx.ns),
David Tolnay60e7aa62020-11-01 12:34:51 -080075 Api::Enum(enm) => Some(&enm.ident.cxx.ns),
76 Api::Struct(strct) => Some(&strct.ident.cxx.ns),
David Tolnay60e7aa62020-11-01 12:34:51 -080077 Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => None,
78 }
79 }
80}