Move qualified path parsing to module
diff --git a/syntax/mod.rs b/syntax/mod.rs
index e2356e1..d6db7cb 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -13,6 +13,7 @@
 pub mod mangle;
 pub mod namespace;
 mod parse;
+mod qualified;
 pub mod report;
 pub mod set;
 pub mod symbol;
diff --git a/syntax/namespace.rs b/syntax/namespace.rs
index e2dce18..bdfb845 100644
--- a/syntax/namespace.rs
+++ b/syntax/namespace.rs
@@ -1,8 +1,9 @@
+use crate::syntax::qualified::QualifiedName;
 use quote::IdentFragment;
 use std::fmt::{self, Display};
 use std::slice::Iter;
 use syn::parse::{Parse, ParseStream, Result};
-use syn::{Ident, Path, Token};
+use syn::{Ident, Token};
 
 mod kw {
     syn::custom_keyword!(namespace);
@@ -31,10 +32,7 @@
         if !input.is_empty() {
             input.parse::<kw::namespace>()?;
             input.parse::<Token![=]>()?;
-            let path = input.call(Path::parse_mod_style)?;
-            for segment in path.segments {
-                segments.push(segment.ident);
-            }
+            segments = input.call(QualifiedName::parse_unquoted)?.segments;
             input.parse::<Option<Token![,]>>()?;
         }
         Ok(Namespace { segments })
diff --git a/syntax/qualified.rs b/syntax/qualified.rs
new file mode 100644
index 0000000..c876fa8
--- /dev/null
+++ b/syntax/qualified.rs
@@ -0,0 +1,17 @@
+use syn::parse::{ParseStream, Result};
+use syn::{Ident, Path};
+
+pub struct QualifiedName {
+    pub segments: Vec<Ident>,
+}
+
+impl QualifiedName {
+    pub fn parse_unquoted(input: ParseStream) -> Result<Self> {
+        let path = input.call(Path::parse_mod_style)?;
+        let mut segments = Vec::with_capacity(path.segments.len());
+        for segment in path.segments {
+            segments.push(segment.ident);
+        }
+        Ok(QualifiedName { segments })
+    }
+}