syn/
op.rs

1ast_enum! {
2    /// A binary operator: `+`, `+=`, `&`.
3    #[cfg_attr(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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}