blob: 07185e18779696f012e98639abca8e6c9a3d4c46 [file] [log] [blame]
David Tolnaydd26bd02020-09-06 23:00:17 -07001use crate::syntax::qualified::QualifiedName;
David Tolnayb6cf3142020-04-19 20:56:09 -07002use quote::IdentFragment;
David Tolnay754e21c2020-03-29 20:58:46 -07003use std::fmt::{self, Display};
David Tolnay078c90f2020-11-01 13:31:08 -08004use std::iter::FromIterator;
David Tolnay754e21c2020-03-29 20:58:46 -07005use 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
David Tolnay078c90f2020-11-01 13:31:08 -080013#[derive(Clone, Default)]
David Tolnay754e21c2020-03-29 20:58:46 -070014pub 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![=]>()?;
David Tolnayd7a3a182020-11-01 20:45:14 -080034 let namespace = input.parse::<Namespace>()?;
Adrian Taylor3e5cff42020-10-29 19:48:45 -070035 input.parse::<Option<Token![,]>>()?;
David Tolnayd7a3a182020-11-01 20:45:14 -080036 Ok(namespace)
Adrian Taylor3e5cff42020-10-29 19:48:45 -070037 }
David Tolnay754e21c2020-03-29 20:58:46 -070038}
39
David Tolnay078c90f2020-11-01 13:31:08 -080040impl Default for &Namespace {
41 fn default() -> Self {
42 const ROOT: &Namespace = &Namespace::ROOT;
43 ROOT
44 }
45}
46
David Tolnayb6cf3142020-04-19 20:56:09 -070047impl Parse for Namespace {
48 fn parse(input: ParseStream) -> Result<Self> {
Adrian Taylor3e5cff42020-10-29 19:48:45 -070049 let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;
David Tolnayb6cf3142020-04-19 20:56:09 -070050 Ok(Namespace { segments })
51 }
52}
53
David Tolnay754e21c2020-03-29 20:58:46 -070054impl Display for Namespace {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 for segment in self {
David Tolnay63f92e82020-04-30 20:40:20 -070057 write!(f, "{}$", segment)?;
David Tolnay754e21c2020-03-29 20:58:46 -070058 }
59 Ok(())
60 }
61}
62
David Tolnayb6cf3142020-04-19 20:56:09 -070063impl IdentFragment for Namespace {
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 Display::fmt(self, f)
66 }
67}
68
David Tolnay754e21c2020-03-29 20:58:46 -070069impl<'a> IntoIterator for &'a Namespace {
David Tolnay63f92e82020-04-30 20:40:20 -070070 type Item = &'a Ident;
71 type IntoIter = Iter<'a, Ident>;
David Tolnay754e21c2020-03-29 20:58:46 -070072 fn into_iter(self) -> Self::IntoIter {
73 self.iter()
74 }
75}
David Tolnay60e7aa62020-11-01 12:34:51 -080076
David Tolnay078c90f2020-11-01 13:31:08 -080077impl<'a> FromIterator<&'a Ident> for Namespace {
78 fn from_iter<I>(idents: I) -> Self
79 where
80 I: IntoIterator<Item = &'a Ident>,
81 {
82 let segments = idents.into_iter().cloned().collect();
83 Namespace { segments }
84 }
85}