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(feature = "clone-impls", derive(Copy))]
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(feature = "clone-impls", derive(Copy))]
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 
87     use crate::parse::{Parse, ParseStream, Result};
88 
parse_binop(input: ParseStream) -> Result<BinOp>89     fn parse_binop(input: ParseStream) -> Result<BinOp> {
90         if input.peek(Token![&&]) {
91             input.parse().map(BinOp::And)
92         } else if input.peek(Token![||]) {
93             input.parse().map(BinOp::Or)
94         } else if input.peek(Token![<<]) {
95             input.parse().map(BinOp::Shl)
96         } else if input.peek(Token![>>]) {
97             input.parse().map(BinOp::Shr)
98         } else if input.peek(Token![==]) {
99             input.parse().map(BinOp::Eq)
100         } else if input.peek(Token![<=]) {
101             input.parse().map(BinOp::Le)
102         } else if input.peek(Token![!=]) {
103             input.parse().map(BinOp::Ne)
104         } else if input.peek(Token![>=]) {
105             input.parse().map(BinOp::Ge)
106         } else if input.peek(Token![+]) {
107             input.parse().map(BinOp::Add)
108         } else if input.peek(Token![-]) {
109             input.parse().map(BinOp::Sub)
110         } else if input.peek(Token![*]) {
111             input.parse().map(BinOp::Mul)
112         } else if input.peek(Token![/]) {
113             input.parse().map(BinOp::Div)
114         } else if input.peek(Token![%]) {
115             input.parse().map(BinOp::Rem)
116         } else if input.peek(Token![^]) {
117             input.parse().map(BinOp::BitXor)
118         } else if input.peek(Token![&]) {
119             input.parse().map(BinOp::BitAnd)
120         } else if input.peek(Token![|]) {
121             input.parse().map(BinOp::BitOr)
122         } else if input.peek(Token![<]) {
123             input.parse().map(BinOp::Lt)
124         } else if input.peek(Token![>]) {
125             input.parse().map(BinOp::Gt)
126         } else {
127             Err(input.error("expected binary operator"))
128         }
129     }
130 
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     impl Parse for UnOp {
parse(input: ParseStream) -> Result<Self>166         fn parse(input: ParseStream) -> Result<Self> {
167             let lookahead = input.lookahead1();
168             if lookahead.peek(Token![*]) {
169                 input.parse().map(UnOp::Deref)
170             } else if lookahead.peek(Token![!]) {
171                 input.parse().map(UnOp::Not)
172             } else if lookahead.peek(Token![-]) {
173                 input.parse().map(UnOp::Neg)
174             } else {
175                 Err(lookahead.error())
176             }
177         }
178     }
179 }
180 
181 #[cfg(feature = "printing")]
182 mod printing {
183     use super::*;
184     use proc_macro2::TokenStream;
185     use quote::ToTokens;
186 
187     impl ToTokens for BinOp {
to_tokens(&self, tokens: &mut TokenStream)188         fn to_tokens(&self, tokens: &mut TokenStream) {
189             match self {
190                 BinOp::Add(t) => t.to_tokens(tokens),
191                 BinOp::Sub(t) => t.to_tokens(tokens),
192                 BinOp::Mul(t) => t.to_tokens(tokens),
193                 BinOp::Div(t) => t.to_tokens(tokens),
194                 BinOp::Rem(t) => t.to_tokens(tokens),
195                 BinOp::And(t) => t.to_tokens(tokens),
196                 BinOp::Or(t) => t.to_tokens(tokens),
197                 BinOp::BitXor(t) => t.to_tokens(tokens),
198                 BinOp::BitAnd(t) => t.to_tokens(tokens),
199                 BinOp::BitOr(t) => t.to_tokens(tokens),
200                 BinOp::Shl(t) => t.to_tokens(tokens),
201                 BinOp::Shr(t) => t.to_tokens(tokens),
202                 BinOp::Eq(t) => t.to_tokens(tokens),
203                 BinOp::Lt(t) => t.to_tokens(tokens),
204                 BinOp::Le(t) => t.to_tokens(tokens),
205                 BinOp::Ne(t) => t.to_tokens(tokens),
206                 BinOp::Ge(t) => t.to_tokens(tokens),
207                 BinOp::Gt(t) => t.to_tokens(tokens),
208                 BinOp::AddEq(t) => t.to_tokens(tokens),
209                 BinOp::SubEq(t) => t.to_tokens(tokens),
210                 BinOp::MulEq(t) => t.to_tokens(tokens),
211                 BinOp::DivEq(t) => t.to_tokens(tokens),
212                 BinOp::RemEq(t) => t.to_tokens(tokens),
213                 BinOp::BitXorEq(t) => t.to_tokens(tokens),
214                 BinOp::BitAndEq(t) => t.to_tokens(tokens),
215                 BinOp::BitOrEq(t) => t.to_tokens(tokens),
216                 BinOp::ShlEq(t) => t.to_tokens(tokens),
217                 BinOp::ShrEq(t) => t.to_tokens(tokens),
218             }
219         }
220     }
221 
222     impl ToTokens for UnOp {
to_tokens(&self, tokens: &mut TokenStream)223         fn to_tokens(&self, tokens: &mut TokenStream) {
224             match self {
225                 UnOp::Deref(t) => t.to_tokens(tokens),
226                 UnOp::Not(t) => t.to_tokens(tokens),
227                 UnOp::Neg(t) => t.to_tokens(tokens),
228             }
229         }
230     }
231 }
232