blob: e08d9c7fd120db53a5079bf318da49b9cf7f547b [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"]`
David Tolnayf4bbbd92016-09-23 14:41:55 -070025 NameValue(Ident, Lit),
David Tolnayb79ee962016-09-04 09:39:20 -070026}
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 Tolnay55337722016-09-11 12:58:56 -070031 use ident::parsing::ident;
David Tolnayf4bbbd92016-09-23 14:41:55 -070032 use lit::{Lit, StrStyle};
33 use lit::parsing::lit;
David Tolnay9d8f1972016-09-04 11:58:48 -070034 use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -070035
David Tolnayb5a7b142016-09-13 22:46:39 -070036 named!(pub attribute -> Attribute, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -070037 do_parse!(
38 punct!("#") >>
39 punct!("[") >>
40 meta_item: meta_item >>
41 punct!("]") >>
42 (Attribute {
43 value: meta_item,
44 is_sugared_doc: false,
45 })
46 )
47 |
48 do_parse!(
49 punct!("///") >>
50 space: multispace >>
David Tolnayb5a7b142016-09-13 22:46:39 -070051 content: take_until!("\n") >>
David Tolnay9d8f1972016-09-04 11:58:48 -070052 (Attribute {
53 value: MetaItem::NameValue(
David Tolnay42f50292016-09-04 13:54:21 -070054 "doc".into(),
David Tolnayf4bbbd92016-09-23 14:41:55 -070055 Lit::Str(
56 format!("///{}{}", space, content),
57 StrStyle::Cooked,
58 ),
David Tolnay9d8f1972016-09-04 11:58:48 -070059 ),
60 is_sugared_doc: true,
61 })
62 )
63 ));
David Tolnayb79ee962016-09-04 09:39:20 -070064
David Tolnayb5a7b142016-09-13 22:46:39 -070065 named!(meta_item -> MetaItem, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -070066 do_parse!(
David Tolnay55337722016-09-11 12:58:56 -070067 id: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070068 punct!("(") >>
69 inner: separated_list!(punct!(","), meta_item) >>
70 punct!(")") >>
David Tolnay55337722016-09-11 12:58:56 -070071 (MetaItem::List(id, inner))
David Tolnay9d8f1972016-09-04 11:58:48 -070072 )
73 |
74 do_parse!(
David Tolnayf4bbbd92016-09-23 14:41:55 -070075 name: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070076 punct!("=") >>
David Tolnayf4bbbd92016-09-23 14:41:55 -070077 value: lit >>
78 (MetaItem::NameValue(name, value))
David Tolnay9d8f1972016-09-04 11:58:48 -070079 )
80 |
David Tolnay55337722016-09-11 12:58:56 -070081 map!(ident, MetaItem::Word)
David Tolnay9d8f1972016-09-04 11:58:48 -070082 ));
83}
David Tolnay87d0b442016-09-04 11:52:12 -070084
85#[cfg(feature = "printing")]
86mod printing {
87 use super::*;
88 use quote::{Tokens, ToTokens};
89
90 impl ToTokens for Attribute {
91 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayfbef2342016-09-04 14:42:34 -070092 tokens.append("#");
93 tokens.append("[");
David Tolnay87d0b442016-09-04 11:52:12 -070094 self.value.to_tokens(tokens);
95 tokens.append("]");
96 }
97 }
98
99 impl ToTokens for MetaItem {
100 fn to_tokens(&self, tokens: &mut Tokens) {
101 match *self {
David Tolnay26469072016-09-04 13:59:48 -0700102 MetaItem::Word(ref ident) => {
103 ident.to_tokens(tokens);
104 }
David Tolnay87d0b442016-09-04 11:52:12 -0700105 MetaItem::List(ref ident, ref inner) => {
David Tolnay26469072016-09-04 13:59:48 -0700106 ident.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700107 tokens.append("(");
David Tolnay94ebdf92016-09-04 13:33:16 -0700108 tokens.append_separated(inner, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700109 tokens.append(")");
110 }
111 MetaItem::NameValue(ref name, ref value) => {
David Tolnay26469072016-09-04 13:59:48 -0700112 name.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700113 tokens.append("=");
114 value.to_tokens(tokens);
115 }
116 }
117 }
118 }
119}