blob: a5d7c7dfcac7b4f42c71937fff481b33144be6c4 [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
3use common::word;
4use helper::escaped_string;
David Tolnaycef990c2016-09-04 10:17:15 -07005use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -07006
7#[derive(Debug, Clone, Eq, PartialEq)]
8pub struct Attribute {
9 pub value: MetaItem,
10 pub is_sugared_doc: bool,
11}
12
13/// A compile-time attribute item.
14///
15/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
16#[derive(Debug, Clone, Eq, PartialEq)]
17pub enum MetaItem {
18 /// Word meta item.
19 ///
20 /// E.g. `test` as in `#[test]`
21 Word(Ident),
22 /// List meta item.
23 ///
24 /// E.g. `derive(..)` as in `#[derive(..)]`
25 List(Ident, Vec<MetaItem>),
26 /// Name value meta item.
27 ///
28 /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
29 NameValue(Ident, String),
30}
31
David Tolnaycef990c2016-09-04 10:17:15 -070032named!(pub attribute<&str, Attribute>, alt!(
33 chain!(
34 punct!("#") ~
35 punct!("[") ~
36 meta_item: meta_item ~
37 punct!("]"),
38 move || Attribute {
39 value: meta_item,
40 is_sugared_doc: false,
41 }
42 )
43 |
44 chain!(
45 punct!("///") ~
46 space: multispace ~
47 content: take_until_s!("\n"),
48 move || Attribute {
49 value: MetaItem::NameValue(
50 "doc".to_string(),
51 format!("///{}{}", space, content),
52 ),
53 is_sugared_doc: true,
54 }
55 )
David Tolnayb79ee962016-09-04 09:39:20 -070056));
57
58named!(quoted<&str, String>, delimited!(
59 punct!("\""),
60 escaped_string,
61 tag_s!("\"")
62));
63
64named!(meta_item<&str, MetaItem>, alt!(
65 chain!(
66 ident: word ~
67 punct!("(") ~
68 inner: separated_list!(punct!(","), meta_item) ~
69 punct!(")"),
70 move || MetaItem::List(ident, inner)
71 )
72 |
73 chain!(
74 ident: word ~
75 punct!("=") ~
76 string: quoted,
77 move || MetaItem::NameValue(ident, string)
78 )
79 |
80 map!(word, MetaItem::Word)
81));