Unify Namespace parsing code
diff --git a/gen/mod.rs b/gen/mod.rs
index 998cd14..4c3a292 100644
--- a/gen/mod.rs
+++ b/gen/mod.rs
@@ -8,13 +8,12 @@
use self::error::format_err;
use crate::syntax::namespace::Namespace;
-use crate::syntax::{self, check, ident, Types};
+use crate::syntax::{self, check, Types};
use quote::quote;
use std::fs;
use std::io;
use std::path::Path;
-use syn::parse::ParseStream;
-use syn::{Attribute, File, Item, Token};
+use syn::{Attribute, File, Item};
use thiserror::Error;
pub(super) type Result<T, E = Error> = std::result::Result<T, E>;
@@ -86,8 +85,7 @@
)));
}
};
- let namespace_segments = parse_args(attr)?;
- let namespace = Namespace::new(namespace_segments);
+ let namespace = parse_args(attr)?;
return Ok(Input { namespace, module });
}
}
@@ -96,24 +94,10 @@
Err(Error::NoBridgeMod)
}
-fn parse_args(attr: &Attribute) -> syn::Result<Vec<String>> {
+fn parse_args(attr: &Attribute) -> syn::Result<Namespace> {
if attr.tokens.is_empty() {
- return Ok(Vec::new());
+ Ok(Namespace::none())
+ } else {
+ attr.parse_args()
}
- attr.parse_args_with(|input: ParseStream| {
- mod kw {
- syn::custom_keyword!(namespace);
- }
- input.parse::<kw::namespace>()?;
- input.parse::<Token![=]>()?;
- let path = syn::Path::parse_mod_style(input)?;
- input.parse::<Option<Token![,]>>()?;
- path.segments
- .into_iter()
- .map(|seg| {
- ident::check(&seg.ident)?;
- Ok(seg.ident.to_string())
- })
- .collect()
- })
}
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
index 49c4f42..b56f58e 100644
--- a/macro/src/lib.rs
+++ b/macro/src/lib.rs
@@ -10,7 +10,6 @@
extern crate proc_macro;
mod expand;
-mod namespace;
mod syntax;
use crate::syntax::namespace::Namespace;
diff --git a/macro/src/namespace.rs b/macro/src/namespace.rs
deleted file mode 100644
index 2d14aa2..0000000
--- a/macro/src/namespace.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-use crate::syntax::ident;
-use crate::syntax::namespace::Namespace;
-use quote::IdentFragment;
-use std::fmt::{self, Display};
-use syn::parse::{Parse, ParseStream, Result};
-use syn::{Path, Token};
-
-mod kw {
- syn::custom_keyword!(namespace);
-}
-
-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::new(segments))
- }
-}
-
-impl IdentFragment for Namespace {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(self, f)
- }
-}
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>;