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