blob: 8d36b343aaf0dbdd8b1aa2b6e9996d34ba1784ee [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnayaed77b02016-09-23 20:50:31 -07003/// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
David Tolnayb79ee962016-09-04 09:39:20 -07004#[derive(Debug, Clone, Eq, PartialEq)]
5pub struct Attribute {
6 pub value: MetaItem,
7 pub is_sugared_doc: bool,
8}
9
10/// A compile-time attribute item.
11///
12/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
13#[derive(Debug, Clone, Eq, PartialEq)]
14pub enum MetaItem {
15 /// Word meta item.
16 ///
17 /// E.g. `test` as in `#[test]`
18 Word(Ident),
19 /// List meta item.
20 ///
21 /// E.g. `derive(..)` as in `#[derive(..)]`
22 List(Ident, Vec<MetaItem>),
23 /// Name value meta item.
24 ///
25 /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
David Tolnayf4bbbd92016-09-23 14:41:55 -070026 NameValue(Ident, Lit),
David Tolnayb79ee962016-09-04 09:39:20 -070027}
28
David Tolnay86eca752016-09-04 11:26:41 -070029#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -070030pub mod parsing {
31 use super::*;
David Tolnay55337722016-09-11 12:58:56 -070032 use ident::parsing::ident;
David Tolnayf4bbbd92016-09-23 14:41:55 -070033 use lit::{Lit, StrStyle};
34 use lit::parsing::lit;
David Tolnay9d8f1972016-09-04 11:58:48 -070035 use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -070036
David Tolnayb5a7b142016-09-13 22:46:39 -070037 named!(pub attribute -> Attribute, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -070038 do_parse!(
39 punct!("#") >>
40 punct!("[") >>
41 meta_item: meta_item >>
42 punct!("]") >>
43 (Attribute {
44 value: meta_item,
45 is_sugared_doc: false,
46 })
47 )
48 |
49 do_parse!(
50 punct!("///") >>
51 space: multispace >>
David Tolnayb5a7b142016-09-13 22:46:39 -070052 content: take_until!("\n") >>
David Tolnay9d8f1972016-09-04 11:58:48 -070053 (Attribute {
54 value: MetaItem::NameValue(
David Tolnay42f50292016-09-04 13:54:21 -070055 "doc".into(),
David Tolnayf4bbbd92016-09-23 14:41:55 -070056 Lit::Str(
57 format!("///{}{}", space, content),
58 StrStyle::Cooked,
59 ),
David Tolnay9d8f1972016-09-04 11:58:48 -070060 ),
61 is_sugared_doc: true,
62 })
63 )
64 ));
David Tolnayb79ee962016-09-04 09:39:20 -070065
David Tolnayb5a7b142016-09-13 22:46:39 -070066 named!(meta_item -> MetaItem, alt!(
David Tolnay9d8f1972016-09-04 11:58:48 -070067 do_parse!(
David Tolnay55337722016-09-11 12:58:56 -070068 id: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070069 punct!("(") >>
70 inner: separated_list!(punct!(","), meta_item) >>
71 punct!(")") >>
David Tolnay55337722016-09-11 12:58:56 -070072 (MetaItem::List(id, inner))
David Tolnay9d8f1972016-09-04 11:58:48 -070073 )
74 |
75 do_parse!(
David Tolnayf4bbbd92016-09-23 14:41:55 -070076 name: ident >>
David Tolnay9d8f1972016-09-04 11:58:48 -070077 punct!("=") >>
David Tolnayf4bbbd92016-09-23 14:41:55 -070078 value: lit >>
79 (MetaItem::NameValue(name, value))
David Tolnay9d8f1972016-09-04 11:58:48 -070080 )
81 |
David Tolnay55337722016-09-11 12:58:56 -070082 map!(ident, MetaItem::Word)
David Tolnay9d8f1972016-09-04 11:58:48 -070083 ));
84}
David Tolnay87d0b442016-09-04 11:52:12 -070085
86#[cfg(feature = "printing")]
87mod printing {
88 use super::*;
89 use quote::{Tokens, ToTokens};
90
91 impl ToTokens for Attribute {
92 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnayfbef2342016-09-04 14:42:34 -070093 tokens.append("#");
94 tokens.append("[");
David Tolnay87d0b442016-09-04 11:52:12 -070095 self.value.to_tokens(tokens);
96 tokens.append("]");
97 }
98 }
99
100 impl ToTokens for MetaItem {
101 fn to_tokens(&self, tokens: &mut Tokens) {
102 match *self {
David Tolnay26469072016-09-04 13:59:48 -0700103 MetaItem::Word(ref ident) => {
104 ident.to_tokens(tokens);
105 }
David Tolnay87d0b442016-09-04 11:52:12 -0700106 MetaItem::List(ref ident, ref inner) => {
David Tolnay26469072016-09-04 13:59:48 -0700107 ident.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700108 tokens.append("(");
David Tolnay94ebdf92016-09-04 13:33:16 -0700109 tokens.append_separated(inner, ",");
David Tolnay87d0b442016-09-04 11:52:12 -0700110 tokens.append(")");
111 }
112 MetaItem::NameValue(ref name, ref value) => {
David Tolnay26469072016-09-04 13:59:48 -0700113 name.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -0700114 tokens.append("=");
115 value.to_tokens(tokens);
116 }
117 }
118 }
119 }
120}