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>;