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 crate::error::Result;
82 use crate::op::{BinOp, UnOp};
83 use crate::parse::{Parse, ParseStream};
84
85 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
86 impl Parse for BinOp {
87 fn parse(input: ParseStream) -> Result<Self> {
88 if input.peek(Token![+=]) {
89 input.parse().map(BinOp::AddAssign)
90 } else if input.peek(Token![-=]) {
91 input.parse().map(BinOp::SubAssign)
92 } else if input.peek(Token![*=]) {
93 input.parse().map(BinOp::MulAssign)
94 } else if input.peek(Token![/=]) {
95 input.parse().map(BinOp::DivAssign)
96 } else if input.peek(Token![%=]) {
97 input.parse().map(BinOp::RemAssign)
98 } else if input.peek(Token![^=]) {
99 input.parse().map(BinOp::BitXorAssign)
100 } else if input.peek(Token![&=]) {
101 input.parse().map(BinOp::BitAndAssign)
102 } else if input.peek(Token![|=]) {
103 input.parse().map(BinOp::BitOrAssign)
104 } else if input.peek(Token![<<=]) {
105 input.parse().map(BinOp::ShlAssign)
106 } else if input.peek(Token![>>=]) {
107 input.parse().map(BinOp::ShrAssign)
108 } else if input.peek(Token![&&]) {
109 input.parse().map(BinOp::And)
110 } else if input.peek(Token![||]) {
111 input.parse().map(BinOp::Or)
112 } else if input.peek(Token![<<]) {
113 input.parse().map(BinOp::Shl)
114 } else if input.peek(Token![>>]) {
115 input.parse().map(BinOp::Shr)
116 } else if input.peek(Token![==]) {
117 input.parse().map(BinOp::Eq)
118 } else if input.peek(Token![<=]) {
119 input.parse().map(BinOp::Le)
120 } else if input.peek(Token![!=]) {
121 input.parse().map(BinOp::Ne)
122 } else if input.peek(Token![>=]) {
123 input.parse().map(BinOp::Ge)
124 } else if input.peek(Token![+]) {
125 input.parse().map(BinOp::Add)
126 } else if input.peek(Token![-]) {
127 input.parse().map(BinOp::Sub)
128 } else if input.peek(Token![*]) {
129 input.parse().map(BinOp::Mul)
130 } else if input.peek(Token![/]) {
131 input.parse().map(BinOp::Div)
132 } else if input.peek(Token![%]) {
133 input.parse().map(BinOp::Rem)
134 } else if input.peek(Token![^]) {
135 input.parse().map(BinOp::BitXor)
136 } else if input.peek(Token![&]) {
137 input.parse().map(BinOp::BitAnd)
138 } else if input.peek(Token![|]) {
139 input.parse().map(BinOp::BitOr)
140 } else if input.peek(Token![<]) {
141 input.parse().map(BinOp::Lt)
142 } else if input.peek(Token![>]) {
143 input.parse().map(BinOp::Gt)
144 } else {
145 Err(input.error("expected binary operator"))
146 }
147 }
148 }
149
150 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
151 impl Parse for UnOp {
152 fn parse(input: ParseStream) -> Result<Self> {
153 let lookahead = input.lookahead1();
154 if lookahead.peek(Token![*]) {
155 input.parse().map(UnOp::Deref)
156 } else if lookahead.peek(Token![!]) {
157 input.parse().map(UnOp::Not)
158 } else if lookahead.peek(Token![-]) {
159 input.parse().map(UnOp::Neg)
160 } else {
161 Err(lookahead.error())
162 }
163 }
164 }
165}
166
167#[cfg(feature = "printing")]
168mod printing {
169 use crate::op::{BinOp, UnOp};
170 use proc_macro2::TokenStream;
171 use quote::ToTokens;
172
173 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
174 impl ToTokens for BinOp {
175 fn to_tokens(&self, tokens: &mut TokenStream) {
176 match self {
177 BinOp::Add(t) => t.to_tokens(tokens),
178 BinOp::Sub(t) => t.to_tokens(tokens),
179 BinOp::Mul(t) => t.to_tokens(tokens),
180 BinOp::Div(t) => t.to_tokens(tokens),
181 BinOp::Rem(t) => t.to_tokens(tokens),
182 BinOp::And(t) => t.to_tokens(tokens),
183 BinOp::Or(t) => t.to_tokens(tokens),
184 BinOp::BitXor(t) => t.to_tokens(tokens),
185 BinOp::BitAnd(t) => t.to_tokens(tokens),
186 BinOp::BitOr(t) => t.to_tokens(tokens),
187 BinOp::Shl(t) => t.to_tokens(tokens),
188 BinOp::Shr(t) => t.to_tokens(tokens),
189 BinOp::Eq(t) => t.to_tokens(tokens),
190 BinOp::Lt(t) => t.to_tokens(tokens),
191 BinOp::Le(t) => t.to_tokens(tokens),
192 BinOp::Ne(t) => t.to_tokens(tokens),
193 BinOp::Ge(t) => t.to_tokens(tokens),
194 BinOp::Gt(t) => t.to_tokens(tokens),
195 BinOp::AddAssign(t) => t.to_tokens(tokens),
196 BinOp::SubAssign(t) => t.to_tokens(tokens),
197 BinOp::MulAssign(t) => t.to_tokens(tokens),
198 BinOp::DivAssign(t) => t.to_tokens(tokens),
199 BinOp::RemAssign(t) => t.to_tokens(tokens),
200 BinOp::BitXorAssign(t) => t.to_tokens(tokens),
201 BinOp::BitAndAssign(t) => t.to_tokens(tokens),
202 BinOp::BitOrAssign(t) => t.to_tokens(tokens),
203 BinOp::ShlAssign(t) => t.to_tokens(tokens),
204 BinOp::ShrAssign(t) => t.to_tokens(tokens),
205 }
206 }
207 }
208
209 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
210 impl ToTokens for UnOp {
211 fn to_tokens(&self, tokens: &mut TokenStream) {
212 match self {
213 UnOp::Deref(t) => t.to_tokens(tokens),
214 UnOp::Not(t) => t.to_tokens(tokens),
215 UnOp::Neg(t) => t.to_tokens(tokens),
216 }
217 }
218 }
219}
220