Unify Namespace parsing code
diff --git a/syntax/namespace.rs b/syntax/namespace.rs
index 557e331..d26bb9e 100644
--- a/syntax/namespace.rs
+++ b/syntax/namespace.rs
@@ -1,5 +1,13 @@
+use crate::syntax::ident;
+use quote::IdentFragment;
use std::fmt::{self, Display};
use std::slice::Iter;
+use syn::parse::{Parse, ParseStream, Result};
+use syn::{Path, Token};
+
+mod kw {
+ syn::custom_keyword!(namespace);
+}
#[derive(Clone)]
pub struct Namespace {
@@ -7,8 +15,10 @@
}
impl Namespace {
- pub fn new(segments: Vec<String>) -> Self {
- Namespace { segments }
+ pub fn none() -> Self {
+ Namespace {
+ segments: Vec::new(),
+ }
}
pub fn iter(&self) -> Iter<String> {
@@ -16,6 +26,23 @@
}
}
+impl Parse for Namespace {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut segments = Vec::new();
+ if !input.is_empty() {
+ input.parse::<kw::namespace>()?;
+ input.parse::<Token![=]>()?;
+ let path = input.call(Path::parse_mod_style)?;
+ for segment in path.segments {
+ ident::check(&segment.ident)?;
+ segments.push(segment.ident.to_string());
+ }
+ input.parse::<Option<Token![,]>>()?;
+ }
+ Ok(Namespace { segments })
+ }
+}
+
impl Display for Namespace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for segment in self {
@@ -26,6 +53,12 @@
}
}
+impl IdentFragment for Namespace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(self, f)
+ }
+}
+
impl<'a> IntoIterator for &'a Namespace {
type Item = &'a String;
type IntoIter = Iter<'a, String>;