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