blob: 7628b0a05c6a516012954185fb89c616861f3c38 [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};
David Tolnay078c90f2020-11-01 13:31:08 -08005use std::iter::FromIterator;
David Tolnay754e21c2020-03-29 20:58:46 -07006use std::slice::Iter;
David Tolnayb6cf3142020-04-19 20:56:09 -07007use syn::parse::{Parse, ParseStream, Result};
David Tolnaydd26bd02020-09-06 23:00:17 -07008use syn::{Ident, Token};
David Tolnayb6cf3142020-04-19 20:56:09 -07009
10mod kw {
11 syn::custom_keyword!(namespace);
12}
David Tolnay754e21c2020-03-29 20:58:46 -070013
David Tolnay078c90f2020-11-01 13:31:08 -080014#[derive(Clone, Default)]
David Tolnay754e21c2020-03-29 20:58:46 -070015pub struct Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070016 segments: Vec<Ident>,
David Tolnay754e21c2020-03-29 20:58:46 -070017}
18
19impl Namespace {
David Tolnay4ebde542020-11-01 14:23:31 -080020 pub const ROOT: Self = Namespace {
21 segments: Vec::new(),
22 };
David Tolnay754e21c2020-03-29 20:58:46 -070023
David Tolnay63f92e82020-04-30 20:40:20 -070024 pub fn iter(&self) -> Iter<Ident> {
David Tolnay754e21c2020-03-29 20:58:46 -070025 self.segments.iter()
26 }
Adrian Taylor3e5cff42020-10-29 19:48:45 -070027
28 pub fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Namespace> {
29 if input.is_empty() {
David Tolnay4ebde542020-11-01 14:23:31 -080030 return Ok(Namespace::ROOT);
Adrian Taylor3e5cff42020-10-29 19:48:45 -070031 }
32
33 input.parse::<kw::namespace>()?;
34 input.parse::<Token![=]>()?;
35 let ns = input.parse::<Namespace>()?;
36 input.parse::<Option<Token![,]>>()?;
37 Ok(ns)
38 }
David Tolnay754e21c2020-03-29 20:58:46 -070039}
40
David Tolnay078c90f2020-11-01 13:31:08 -080041impl Default for &Namespace {
42 fn default() -> Self {
43 const ROOT: &Namespace = &Namespace::ROOT;
44 ROOT
45 }
46}
47
David Tolnayb6cf3142020-04-19 20:56:09 -070048impl Parse for Namespace {
49 fn parse(input: ParseStream) -> Result<Self> {
Adrian Taylor3e5cff42020-10-29 19:48:45 -070050 let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;
David Tolnayb6cf3142020-04-19 20:56:09 -070051 Ok(Namespace { segments })
52 }
53}
54
David Tolnay754e21c2020-03-29 20:58:46 -070055impl Display for Namespace {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 for segment in self {
David Tolnay63f92e82020-04-30 20:40:20 -070058 write!(f, "{}$", segment)?;
David Tolnay754e21c2020-03-29 20:58:46 -070059 }
60 Ok(())
61 }
62}
63
David Tolnayb6cf3142020-04-19 20:56:09 -070064impl IdentFragment for Namespace {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66 Display::fmt(self, f)
67 }
68}
69
David Tolnay754e21c2020-03-29 20:58:46 -070070impl<'a> IntoIterator for &'a Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070071 type Item = &'a Ident;
72 type IntoIter = Iter<'a, Ident>;
David Tolnay754e21c2020-03-29 20:58:46 -070073 fn into_iter(self) -> Self::IntoIter {
74 self.iter()
75 }
76}
David Tolnay60e7aa62020-11-01 12:34:51 -080077
David Tolnay078c90f2020-11-01 13:31:08 -080078impl<'a> FromIterator<&'a Ident> for Namespace {
79 fn from_iter<I>(idents: I) -> Self
80 where
81 I: IntoIterator<Item = &'a Ident>,
82 {
83 let segments = idents.into_iter().cloned().collect();
84 Namespace { segments }
85 }
86}
87
David Tolnay60e7aa62020-11-01 12:34:51 -080088impl Api {
David Tolnay68a12182020-11-01 12:41:55 -080089 pub fn namespace(&self) -> Option<&Namespace> {
David Tolnay60e7aa62020-11-01 12:34:51 -080090 match self {
David Tolnay6ec41112020-11-01 12:40:38 -080091 Api::CxxFunction(efn) | Api::RustFunction(efn) => Some(&efn.ident.cxx.ns),
92 Api::CxxType(ety) | Api::RustType(ety) => Some(&ety.ident.cxx.ns),
David Tolnay60e7aa62020-11-01 12:34:51 -080093 Api::Enum(enm) => Some(&enm.ident.cxx.ns),
94 Api::Struct(strct) => Some(&strct.ident.cxx.ns),
David Tolnay60e7aa62020-11-01 12:34:51 -080095 Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => None,
96 }
97 }
98}