blob: d26bb9ec756e5a968ba996fe00282abd556c074c [file] [log] [blame]
David Tolnayb6cf3142020-04-19 20:56:09 -07001use crate::syntax::ident;
2use quote::IdentFragment;
David Tolnay754e21c2020-03-29 20:58:46 -07003use std::fmt::{self, Display};
4use std::slice::Iter;
David Tolnayb6cf3142020-04-19 20:56:09 -07005use syn::parse::{Parse, ParseStream, Result};
6use syn::{Path, Token};
7
8mod kw {
9 syn::custom_keyword!(namespace);
10}
David Tolnay754e21c2020-03-29 20:58:46 -070011
12#[derive(Clone)]
13pub struct Namespace {
14 segments: Vec<String>,
15}
16
17impl Namespace {
David Tolnayb6cf3142020-04-19 20:56:09 -070018 pub fn none() -> Self {
19 Namespace {
20 segments: Vec::new(),
21 }
David Tolnay754e21c2020-03-29 20:58:46 -070022 }
23
24 pub fn iter(&self) -> Iter<String> {
25 self.segments.iter()
26 }
27}
28
David Tolnayb6cf3142020-04-19 20:56:09 -070029impl Parse for Namespace {
30 fn parse(input: ParseStream) -> Result<Self> {
31 let mut segments = Vec::new();
32 if !input.is_empty() {
33 input.parse::<kw::namespace>()?;
34 input.parse::<Token![=]>()?;
35 let path = input.call(Path::parse_mod_style)?;
36 for segment in path.segments {
37 ident::check(&segment.ident)?;
38 segments.push(segment.ident.to_string());
39 }
40 input.parse::<Option<Token![,]>>()?;
41 }
42 Ok(Namespace { segments })
43 }
44}
45
David Tolnay754e21c2020-03-29 20:58:46 -070046impl Display for Namespace {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 for segment in self {
49 f.write_str(segment)?;
50 f.write_str("$")?;
51 }
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 {
63 type Item = &'a String;
64 type IntoIter = Iter<'a, String>;
65 fn into_iter(self) -> Self::IntoIter {
66 self.iter()
67 }
68}