blob: 5eb203ab6d4a27901058f71e78ff38567954fe00 [file] [log] [blame]
David Tolnaydd26bd02020-09-06 23:00:17 -07001use crate::syntax::qualified::QualifiedName;
Adrian Taylor7827d782020-10-29 22:03:34 -07002#[cfg(test)]
3use proc_macro2::Span;
David Tolnayb6cf3142020-04-19 20:56:09 -07004use quote::IdentFragment;
David Tolnay754e21c2020-03-29 20:58:46 -07005use std::fmt::{self, Display};
6use 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
14#[derive(Clone)]
15pub 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 Tolnayb6cf3142020-04-19 20:56:09 -070020 pub fn none() -> Self {
21 Namespace {
22 segments: Vec::new(),
23 }
David Tolnay754e21c2020-03-29 20:58:46 -070024 }
25
David Tolnay63f92e82020-04-30 20:40:20 -070026 pub fn iter(&self) -> Iter<Ident> {
David Tolnay754e21c2020-03-29 20:58:46 -070027 self.segments.iter()
28 }
Adrian Taylor3e5cff42020-10-29 19:48:45 -070029
30 pub fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Namespace> {
31 if input.is_empty() {
32 return Ok(Namespace::none());
33 }
34
35 input.parse::<kw::namespace>()?;
36 input.parse::<Token![=]>()?;
37 let ns = input.parse::<Namespace>()?;
38 input.parse::<Option<Token![,]>>()?;
39 Ok(ns)
40 }
Adrian Taylor7827d782020-10-29 22:03:34 -070041
42 #[cfg(test)]
43 pub fn from_str(ns: &str) -> Self {
44 Namespace {
45 segments: ns
46 .split("::")
47 .map(|x| Ident::new(x, Span::call_site()))
48 .collect(),
49 }
50 }
David Tolnay754e21c2020-03-29 20:58:46 -070051}
52
David Tolnayb6cf3142020-04-19 20:56:09 -070053impl Parse for Namespace {
54 fn parse(input: ParseStream) -> Result<Self> {
Adrian Taylor3e5cff42020-10-29 19:48:45 -070055 let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;
David Tolnayb6cf3142020-04-19 20:56:09 -070056 Ok(Namespace { segments })
57 }
58}
59
David Tolnay754e21c2020-03-29 20:58:46 -070060impl Display for Namespace {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 for segment in self {
David Tolnay63f92e82020-04-30 20:40:20 -070063 write!(f, "{}$", segment)?;
David Tolnay754e21c2020-03-29 20:58:46 -070064 }
65 Ok(())
66 }
67}
68
David Tolnayb6cf3142020-04-19 20:56:09 -070069impl IdentFragment for Namespace {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 Display::fmt(self, f)
72 }
73}
74
David Tolnay754e21c2020-03-29 20:58:46 -070075impl<'a> IntoIterator for &'a Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070076 type Item = &'a Ident;
77 type IntoIter = Iter<'a, Ident>;
David Tolnay754e21c2020-03-29 20:58:46 -070078 fn into_iter(self) -> Self::IntoIter {
79 self.iter()
80 }
81}