Add a Namespace type in gen
diff --git a/gen/mod.rs b/gen/mod.rs
index 9a34705..8006898 100644
--- a/gen/mod.rs
+++ b/gen/mod.rs
@@ -3,10 +3,12 @@
 
 mod error;
 pub(super) mod include;
+mod namespace;
 pub(super) mod out;
 mod write;
 
 use self::error::format_err;
+use self::namespace::Namespace;
 use self::out::OutFile;
 use crate::syntax::{self, check, ident, Types};
 use quote::quote;
@@ -32,7 +34,7 @@
 }
 
 struct Input {
-    namespace: Vec<String>,
+    namespace: Namespace,
     module: Vec<Item>,
 }
 
@@ -86,10 +88,9 @@
                             )));
                         }
                     };
-                    return Ok(Input {
-                        namespace: parse_args(attr)?,
-                        module,
-                    });
+                    let namespace_segments = parse_args(attr)?;
+                    let namespace = Namespace::new(namespace_segments);
+                    return Ok(Input { namespace, module });
                 }
             }
         }
diff --git a/gen/namespace.rs b/gen/namespace.rs
new file mode 100644
index 0000000..c644352
--- /dev/null
+++ b/gen/namespace.rs
@@ -0,0 +1,44 @@
+use std::fmt::{self, Display};
+use std::slice::Iter;
+use std::vec::IntoIter;
+
+#[derive(Clone)]
+pub struct Namespace {
+    segments: Vec<String>,
+}
+
+impl Namespace {
+    pub fn new(segments: Vec<String>) -> Self {
+        Namespace { segments }
+    }
+
+    pub fn iter(&self) -> Iter<String> {
+        self.segments.iter()
+    }
+}
+
+impl Display for Namespace {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        for segment in self {
+            f.write_str(segment)?;
+            f.write_str("$")?;
+        }
+        Ok(())
+    }
+}
+
+impl<'a> IntoIterator for &'a Namespace {
+    type Item = &'a String;
+    type IntoIter = Iter<'a, String>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+impl IntoIterator for Namespace {
+    type Item = String;
+    type IntoIter = IntoIter<String>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.segments.into_iter()
+    }
+}
diff --git a/gen/out.rs b/gen/out.rs
index 2a5b17d..8783dc2 100644
--- a/gen/out.rs
+++ b/gen/out.rs
@@ -1,8 +1,9 @@
 use crate::gen::include::Includes;
+use crate::gen::namespace::Namespace;
 use std::fmt::{self, Arguments, Write};
 
 pub(crate) struct OutFile {
-    pub namespace: Vec<String>,
+    pub namespace: Namespace,
     pub header: bool,
     pub include: Includes,
     content: Vec<u8>,
@@ -11,7 +12,7 @@
 }
 
 impl OutFile {
-    pub fn new(namespace: Vec<String>, header: bool) -> Self {
+    pub fn new(namespace: Namespace, header: bool) -> Self {
         OutFile {
             namespace,
             header,
diff --git a/gen/write.rs b/gen/write.rs
index a17f8f7..a1d5748 100644
--- a/gen/write.rs
+++ b/gen/write.rs
@@ -1,3 +1,4 @@
+use crate::gen::namespace::Namespace;
 use crate::gen::out::OutFile;
 use crate::gen::{include, Opt};
 use crate::syntax::atom::Atom::{self, *};
@@ -5,7 +6,7 @@
 use proc_macro2::Ident;
 
 pub(super) fn gen(
-    namespace: Vec<String>,
+    namespace: Namespace,
     apis: &[Api],
     types: &Types,
     opt: Opt,