blob: 266bbb46e65df85e84013f34548a25b5478f8327 [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!(
David Tolnay6b7aaf02016-09-04 10:39:25 -070033 do_parse!(
34 punct!("#") >>
35 punct!("[") >>
36 meta_item: meta_item >>
37 punct!("]") >>
38 (Attribute {
David Tolnaycef990c2016-09-04 10:17:15 -070039 value: meta_item,
40 is_sugared_doc: false,
David Tolnay6b7aaf02016-09-04 10:39:25 -070041 })
David Tolnaycef990c2016-09-04 10:17:15 -070042 )
43 |
David Tolnay6b7aaf02016-09-04 10:39:25 -070044 do_parse!(
45 punct!("///") >>
46 space: multispace >>
47 content: take_until_s!("\n") >>
48 (Attribute {
David Tolnaycef990c2016-09-04 10:17:15 -070049 value: MetaItem::NameValue(
50 "doc".to_string(),
51 format!("///{}{}", space, content),
52 ),
53 is_sugared_doc: true,
David Tolnay6b7aaf02016-09-04 10:39:25 -070054 })
David Tolnaycef990c2016-09-04 10:17:15 -070055 )
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!(
David Tolnay6b7aaf02016-09-04 10:39:25 -070065 do_parse!(
66 ident: word >>
67 punct!("(") >>
68 inner: separated_list!(punct!(","), meta_item) >>
69 punct!(")") >>
70 (MetaItem::List(ident, inner))
David Tolnayb79ee962016-09-04 09:39:20 -070071 )
72 |
David Tolnay6b7aaf02016-09-04 10:39:25 -070073 do_parse!(
74 ident: word >>
75 punct!("=") >>
76 string: quoted >>
77 (MetaItem::NameValue(ident, string))
David Tolnayb79ee962016-09-04 09:39:20 -070078 )
79 |
80 map!(word, MetaItem::Word)
81));