blob: 4bfba2270362037edc0b9dd4d3b72731183f97d9 [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnayb79ee962016-09-04 09:39:20 -07003#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct Attribute {
5 pub value: MetaItem,
6 pub is_sugared_doc: bool,
7}
8
9/// A compile-time attribute item.
10///
11/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
12#[derive(Debug, Clone, Eq, PartialEq)]
13pub enum MetaItem {
14 /// Word meta item.
15 ///
16 /// E.g. `test` as in `#[test]`
17 Word(Ident),
18 /// List meta item.
19 ///
20 /// E.g. `derive(..)` as in `#[derive(..)]`
21 List(Ident, Vec<MetaItem>),
22 /// Name value meta item.
23 ///
24 /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
25 NameValue(Ident, String),
26}
27
David Tolnay86eca752016-09-04 11:26:41 -070028#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -070029pub mod parsing {
30 use super::*;
David Tolnay9d8f1972016-09-04 11:58:48 -070031 use helper::escaped_string;
David Tolnay55337722016-09-11 12:58:56 -070032 use ident::parsing::ident;
David Tolnay9d8f1972016-09-04 11:58:48 -070033 use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -070034
David Tolnayf6ccb832016-09-04 15:00:56 -070035 named!(pub attribute<&str, Attribute>, alt_complete!(
David Tolnay9d8f1972016-09-04 11:58:48 -070036 do_parse!(
37 punct!("#") >>
38 punct!("[") >>
39 meta_item: meta_item >>
40 punct!("]") >>
41 (Attribute {
42 value: meta_item,
43 is_sugared_doc: false,
44 })
45 )
46 |
47 do_parse!(
48 punct!("///") >>
49 space: multispace >>
50 content: take_until_s!("\n") >>
51 (Attribute {
52 value: MetaItem::NameValue(
David Tolnay42f50292016-09-04 13:54:21 -070053 "doc".into(),
David Tolnay9d8f1972016-09-04 11:58:48 -070054 format!("///{}{}", space, content),
55 ),
56 is_sugared_doc: true,
57 })
58 )
59 ));
David Tolnayb79ee962016-09-04 09:39:20 -070060
David Tolnayf6ccb832016-09-04 15:00:56 -070061 named!(meta_item<&str, MetaItem>, alt_complete!(
David Tolnay9d8f1972016-09-04 11:58:48 -070062 do_parse!(
David Tolnay55337722016-09-11 12:58:56 -070063 id: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070064 punct!("(") >>
65 inner: separated_list!(punct!(","), meta_item) >>
66 punct!(")") >>
David Tolnay55337722016-09-11 12:58:56 -070067 (MetaItem::List(id, inner))
David Tolnay9d8f1972016-09-04 11:58:48 -070068 )
69 |
70 do_parse!(
David Tolnay55337722016-09-11 12:58:56 -070071 id: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070072 punct!("=") >>
73 string: quoted >>
David Tolnay55337722016-09-11 12:58:56 -070074 (MetaItem::NameValue(id, string))
David Tolnay9d8f1972016-09-04 11:58:48 -070075 )
76 |
David Tolnay55337722016-09-11 12:58:56 -070077 map!(ident, MetaItem::Word)
David Tolnay9d8f1972016-09-04 11:58:48 -070078 ));
David Tolnayc94c38a2016-09-05 17:02:03 -070079
80 named!(quoted<&str, String>, delimited!(
81 punct!("\""),
82 escaped_string,
83 tag_s!("\"")
84 ));
David Tolnay9d8f1972016-09-04 11:58:48 -070085}
David Tolnay87d0b442016-09-04 11:52:12 -070086
87#[cfg(feature = "printing")]
88mod printing {
89 use super::*;
90 use quote::{Tokens, ToTokens};
91
92 impl ToTokens for Attribute {
93 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayfbef2342016-09-04 14:42:34 -070094 tokens.append("#");
95 tokens.append("[");
David Tolnay87d0b442016-09-04 11:52:12 -070096 self.value.to_tokens(tokens);
97 tokens.append("]");
98 }
99 }
100
101 impl ToTokens for MetaItem {
102 fn to_tokens(&self, tokens: &mut Tokens) {
103 match *self {
David Tolnay26469072016-09-04 13:59:48 -0700104 MetaItem::Word(ref ident) => {
105 ident.to_tokens(tokens);
106 }
David Tolnay87d0b442016-09-04 11:52:12 -0700107 MetaItem::List(ref ident, ref inner) => {
David Tolnay26469072016-09-04 13:59:48 -0700108 ident.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700109 tokens.append("(");
David Tolnay94ebdf92016-09-04 13:33:16 -0700110 tokens.append_separated(inner, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700111 tokens.append(")");
112 }
113 MetaItem::NameValue(ref name, ref value) => {
David Tolnay26469072016-09-04 13:59:48 -0700114 name.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700115 tokens.append("=");
116 value.to_tokens(tokens);
117 }
118 }
119 }
120 }
121}