• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ast_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 
65 ast_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")]
80 pub(crate) mod parsing {
81     use super::*;
82     use crate::parse::{Parse, ParseStream, Result};
83 
parse_binop(input: ParseStream) -> Result<BinOp>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"))]
parse(input: ParseStream) -> Result<Self>129         fn parse(input: ParseStream) -> Result<Self> {
130             parse_binop(input)
131         }
132 
133         #[cfg(feature = "full")]
parse(input: ParseStream) -> Result<Self>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 {
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     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
185     impl ToTokens for BinOp {
to_tokens(&self, tokens: &mut TokenStream)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 {
to_tokens(&self, tokens: &mut TokenStream)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