1 ast_enum! {
2     /// A binary operator: `+`, `+=`, `&`.
3     ///
4     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
5     /// feature.*
6     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
7     pub enum BinOp {
8         /// The `+` operator (addition)
9         Add(Token![+]),
10         /// The `-` operator (subtraction)
11         Sub(Token![-]),
12         /// The `*` operator (multiplication)
13         Mul(Token![*]),
14         /// The `/` operator (division)
15         Div(Token![/]),
16         /// The `%` operator (modulus)
17         Rem(Token![%]),
18         /// The `&&` operator (logical and)
19         And(Token![&&]),
20         /// The `||` operator (logical or)
21         Or(Token![||]),
22         /// The `^` operator (bitwise xor)
23         BitXor(Token![^]),
24         /// The `&` operator (bitwise and)
25         BitAnd(Token![&]),
26         /// The `|` operator (bitwise or)
27         BitOr(Token![|]),
28         /// The `<<` operator (shift left)
29         Shl(Token![<<]),
30         /// The `>>` operator (shift right)
31         Shr(Token![>>]),
32         /// The `==` operator (equality)
33         Eq(Token![==]),
34         /// The `<` operator (less than)
35         Lt(Token![<]),
36         /// The `<=` operator (less than or equal to)
37         Le(Token![<=]),
38         /// The `!=` operator (not equal to)
39         Ne(Token![!=]),
40         /// The `>=` operator (greater than or equal to)
41         Ge(Token![>=]),
42         /// The `>` operator (greater than)
43         Gt(Token![>]),
44         /// The `+=` operator
45         AddEq(Token![+=]),
46         /// The `-=` operator
47         SubEq(Token![-=]),
48         /// The `*=` operator
49         MulEq(Token![*=]),
50         /// The `/=` operator
51         DivEq(Token![/=]),
52         /// The `%=` operator
53         RemEq(Token![%=]),
54         /// The `^=` operator
55         BitXorEq(Token![^=]),
56         /// The `&=` operator
57         BitAndEq(Token![&=]),
58         /// The `|=` operator
59         BitOrEq(Token![|=]),
60         /// The `<<=` operator
61         ShlEq(Token![<<=]),
62         /// The `>>=` operator
63         ShrEq(Token![>>=]),
64     }
65 }
66 
67 ast_enum! {
68     /// A unary operator: `*`, `!`, `-`.
69     ///
70     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
71     /// feature.*
72     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
73     pub enum UnOp {
74         /// The `*` operator for dereferencing
75         Deref(Token![*]),
76         /// The `!` operator for logical inversion
77         Not(Token![!]),
78         /// The `-` operator for negation
79         Neg(Token![-]),
80     }
81 }
82 
83 #[cfg(feature = "parsing")]
84 pub mod parsing {
85     use super::*;
86     use crate::parse::{Parse, ParseStream, Result};
87 
parse_binop(input: ParseStream) -> Result<BinOp>88     fn parse_binop(input: ParseStream) -> Result<BinOp> {
89         if input.peek(Token![&&]) {
90             input.parse().map(BinOp::And)
91         } else if input.peek(Token![||]) {
92             input.parse().map(BinOp::Or)
93         } else if input.peek(Token![<<]) {
94             input.parse().map(BinOp::Shl)
95         } else if input.peek(Token![>>]) {
96             input.parse().map(BinOp::Shr)
97         } else if input.peek(Token![==]) {
98             input.parse().map(BinOp::Eq)
99         } else if input.peek(Token![<=]) {
100             input.parse().map(BinOp::Le)
101         } else if input.peek(Token![!=]) {
102             input.parse().map(BinOp::Ne)
103         } else if input.peek(Token![>=]) {
104             input.parse().map(BinOp::Ge)
105         } else if input.peek(Token![+]) {
106             input.parse().map(BinOp::Add)
107         } else if input.peek(Token![-]) {
108             input.parse().map(BinOp::Sub)
109         } else if input.peek(Token![*]) {
110             input.parse().map(BinOp::Mul)
111         } else if input.peek(Token![/]) {
112             input.parse().map(BinOp::Div)
113         } else if input.peek(Token![%]) {
114             input.parse().map(BinOp::Rem)
115         } else if input.peek(Token![^]) {
116             input.parse().map(BinOp::BitXor)
117         } else if input.peek(Token![&]) {
118             input.parse().map(BinOp::BitAnd)
119         } else if input.peek(Token![|]) {
120             input.parse().map(BinOp::BitOr)
121         } else if input.peek(Token![<]) {
122             input.parse().map(BinOp::Lt)
123         } else if input.peek(Token![>]) {
124             input.parse().map(BinOp::Gt)
125         } else {
126             Err(input.error("expected binary operator"))
127         }
128     }
129 
130     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
131     impl Parse for BinOp {
132         #[cfg(not(feature = "full"))]
parse(input: ParseStream) -> Result<Self>133         fn parse(input: ParseStream) -> Result<Self> {
134             parse_binop(input)
135         }
136 
137         #[cfg(feature = "full")]
parse(input: ParseStream) -> Result<Self>138         fn parse(input: ParseStream) -> Result<Self> {
139             if input.peek(Token![+=]) {
140                 input.parse().map(BinOp::AddEq)
141             } else if input.peek(Token![-=]) {
142                 input.parse().map(BinOp::SubEq)
143             } else if input.peek(Token![*=]) {
144                 input.parse().map(BinOp::MulEq)
145             } else if input.peek(Token![/=]) {
146                 input.parse().map(BinOp::DivEq)
147             } else if input.peek(Token![%=]) {
148                 input.parse().map(BinOp::RemEq)
149             } else if input.peek(Token![^=]) {
150                 input.parse().map(BinOp::BitXorEq)
151             } else if input.peek(Token![&=]) {
152                 input.parse().map(BinOp::BitAndEq)
153             } else if input.peek(Token![|=]) {
154                 input.parse().map(BinOp::BitOrEq)
155             } else if input.peek(Token![<<=]) {
156                 input.parse().map(BinOp::ShlEq)
157             } else if input.peek(Token![>>=]) {
158                 input.parse().map(BinOp::ShrEq)
159             } else {
160                 parse_binop(input)
161             }
162         }
163     }
164 
165     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
166     impl Parse for UnOp {
parse(input: ParseStream) -> Result<Self>167         fn parse(input: ParseStream) -> Result<Self> {
168             let lookahead = input.lookahead1();
169             if lookahead.peek(Token![*]) {
170                 input.parse().map(UnOp::Deref)
171             } else if lookahead.peek(Token![!]) {
172                 input.parse().map(UnOp::Not)
173             } else if lookahead.peek(Token![-]) {
174                 input.parse().map(UnOp::Neg)
175             } else {
176                 Err(lookahead.error())
177             }
178         }
179     }
180 }
181 
182 #[cfg(feature = "printing")]
183 mod printing {
184     use super::*;
185     use proc_macro2::TokenStream;
186     use quote::ToTokens;
187 
188     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
189     impl ToTokens for BinOp {
to_tokens(&self, tokens: &mut TokenStream)190         fn to_tokens(&self, tokens: &mut TokenStream) {
191             match self {
192                 BinOp::Add(t) => t.to_tokens(tokens),
193                 BinOp::Sub(t) => t.to_tokens(tokens),
194                 BinOp::Mul(t) => t.to_tokens(tokens),
195                 BinOp::Div(t) => t.to_tokens(tokens),
196                 BinOp::Rem(t) => t.to_tokens(tokens),
197                 BinOp::And(t) => t.to_tokens(tokens),
198                 BinOp::Or(t) => t.to_tokens(tokens),
199                 BinOp::BitXor(t) => t.to_tokens(tokens),
200                 BinOp::BitAnd(t) => t.to_tokens(tokens),
201                 BinOp::BitOr(t) => t.to_tokens(tokens),
202                 BinOp::Shl(t) => t.to_tokens(tokens),
203                 BinOp::Shr(t) => t.to_tokens(tokens),
204                 BinOp::Eq(t) => t.to_tokens(tokens),
205                 BinOp::Lt(t) => t.to_tokens(tokens),
206                 BinOp::Le(t) => t.to_tokens(tokens),
207                 BinOp::Ne(t) => t.to_tokens(tokens),
208                 BinOp::Ge(t) => t.to_tokens(tokens),
209                 BinOp::Gt(t) => t.to_tokens(tokens),
210                 BinOp::AddEq(t) => t.to_tokens(tokens),
211                 BinOp::SubEq(t) => t.to_tokens(tokens),
212                 BinOp::MulEq(t) => t.to_tokens(tokens),
213                 BinOp::DivEq(t) => t.to_tokens(tokens),
214                 BinOp::RemEq(t) => t.to_tokens(tokens),
215                 BinOp::BitXorEq(t) => t.to_tokens(tokens),
216                 BinOp::BitAndEq(t) => t.to_tokens(tokens),
217                 BinOp::BitOrEq(t) => t.to_tokens(tokens),
218                 BinOp::ShlEq(t) => t.to_tokens(tokens),
219                 BinOp::ShrEq(t) => t.to_tokens(tokens),
220             }
221         }
222     }
223 
224     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
225     impl ToTokens for UnOp {
to_tokens(&self, tokens: &mut TokenStream)226         fn to_tokens(&self, tokens: &mut TokenStream) {
227             match self {
228                 UnOp::Deref(t) => t.to_tokens(tokens),
229                 UnOp::Not(t) => t.to_tokens(tokens),
230                 UnOp::Neg(t) => t.to_tokens(tokens),
231             }
232         }
233     }
234 }
235