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