Split into modules
diff --git a/src/attr.rs b/src/attr.rs
new file mode 100644
index 0000000..1f329c7
--- /dev/null
+++ b/src/attr.rs
@@ -0,0 +1,65 @@
+use super::*;
+
+use common::word;
+use helper::escaped_string;
+
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct Attribute {
+ pub value: MetaItem,
+ pub is_sugared_doc: bool,
+}
+
+/// A compile-time attribute item.
+///
+/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum MetaItem {
+ /// Word meta item.
+ ///
+ /// E.g. `test` as in `#[test]`
+ Word(Ident),
+ /// List meta item.
+ ///
+ /// E.g. `derive(..)` as in `#[derive(..)]`
+ List(Ident, Vec<MetaItem>),
+ /// Name value meta item.
+ ///
+ /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
+ NameValue(Ident, String),
+}
+
+named!(pub attribute<&str, Attribute>, chain!(
+ punct!("#") ~
+ punct!("[") ~
+ meta_item: meta_item ~
+ punct!("]"),
+ move || Attribute {
+ value: meta_item,
+ is_sugared_doc: false,
+ }
+));
+
+named!(quoted<&str, String>, delimited!(
+ punct!("\""),
+ escaped_string,
+ tag_s!("\"")
+));
+
+named!(meta_item<&str, MetaItem>, alt!(
+ chain!(
+ ident: word ~
+ punct!("(") ~
+ inner: separated_list!(punct!(","), meta_item) ~
+ punct!(")"),
+ move || MetaItem::List(ident, inner)
+ )
+ |
+ chain!(
+ ident: word ~
+ punct!("=") ~
+ string: quoted,
+ move || MetaItem::NameValue(ident, string)
+ )
+ |
+ map!(word, MetaItem::Word)
+));