syn/
op.rs

1ast_enum! {
2    /// A binary operator: `+`, `+=`, `&`.
3    ///
4    /// *This type is available only if Syn is built with the `"derive"` or `"full"`
5    /// feature.*
6    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
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        AddEq(Token![+=]),
46        /// The `-=` operator
47        SubEq(Token![-=]),
48        /// The `*=` operator
49        MulEq(Token![*=]),
50        /// The `/=` operator
51        DivEq(Token![/=]),
52        /// The `%=` operator
53        RemEq(Token![%=]),
54        /// The `^=` operator
55        BitXorEq(Token![^=]),
56        /// The `&=` operator
57        BitAndEq(Token![&=]),
58        /// The `|=` operator
59        BitOrEq(Token![|=]),
60        /// The `<<=` operator
61        ShlEq(Token![<<=]),
62        /// The `>>=` operator
63        ShrEq(Token![>>=]),
64    }
65}
66
67ast_enum! {
68    /// A unary operator: `*`, `!`, `-`.
69    ///
70    /// *This type is available only if Syn is built with the `"derive"` or `"full"`
71    /// feature.*
72    #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
73    pub enum UnOp {
74        /// The `*` operator for dereferencing
75        Deref(Token![*]),
76        /// The `!` operator for logical inversion
77        Not(Token![!]),
78        /// The `-` operator for negation
79        Neg(Token![-]),
80    }
81}
82
83#[cfg(feature = "parsing")]
84pub mod parsing {
85    use super::*;
86    use crate::parse::{Parse, ParseStream, Result};
87
88    fn parse_binop(input: ParseStream) -> Result<BinOp> {
89        if input.peek(Token![&&]) {
90            input.parse().map(BinOp::And)
91        } else if input.peek(Token![||]) {
92            input.parse().map(BinOp::Or)
93        } else if input.peek(Token![<<]) {
94            input.parse().map(BinOp::Shl)
95        } else if input.peek(Token![>>]) {
96            input.parse().map(BinOp::Shr)
97        } else if input.peek(Token![==]) {
98            input.parse().map(BinOp::Eq)
99        } else if input.peek(Token![<=]) {
100            input.parse().map(BinOp::Le)
101        } else if input.peek(Token![!=]) {
102            input.parse().map(BinOp::Ne)
103        } else if input.peek(Token![>=]) {
104            input.parse().map(BinOp::Ge)
105        } else if input.peek(Token![+]) {
106            input.parse().map(BinOp::Add)
107        } else if input.peek(Token![-]) {
108            input.parse().map(BinOp::Sub)
109        } else if input.peek(Token![*]) {
110            input.parse().map(BinOp::Mul)
111        } else if input.peek(Token![/]) {
112            input.parse().map(BinOp::Div)
113        } else if input.peek(Token![%]) {
114            input.parse().map(BinOp::Rem)
115        } else if input.peek(Token![^]) {
116            input.parse().map(BinOp::BitXor)
117        } else if input.peek(Token![&]) {
118            input.parse().map(BinOp::BitAnd)
119        } else if input.peek(Token![|]) {
120            input.parse().map(BinOp::BitOr)
121        } else if input.peek(Token![<]) {
122            input.parse().map(BinOp::Lt)
123        } else if input.peek(Token![>]) {
124            input.parse().map(BinOp::Gt)
125        } else {
126            Err(input.error("expected binary operator"))
127        }
128    }
129
130    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
131    impl Parse for BinOp {
132        #[cfg(not(feature = "full"))]
133        fn parse(input: ParseStream) -> Result<Self> {
134            parse_binop(input)
135        }
136
137        #[cfg(feature = "full")]
138        fn parse(input: ParseStream) -> Result<Self> {
139            if input.peek(Token![+=]) {
140                input.parse().map(BinOp::AddEq)
141            } else if input.peek(Token![-=]) {
142                input.parse().map(BinOp::SubEq)
143            } else if input.peek(Token![*=]) {
144                input.parse().map(BinOp::MulEq)
145            } else if input.peek(Token![/=]) {
146                input.parse().map(BinOp::DivEq)
147            } else if input.peek(Token![%=]) {
148                input.parse().map(BinOp::RemEq)
149            } else if input.peek(Token![^=]) {
150                input.parse().map(BinOp::BitXorEq)
151            } else if input.peek(Token![&=]) {
152                input.parse().map(BinOp::BitAndEq)
153            } else if input.peek(Token![|=]) {
154                input.parse().map(BinOp::BitOrEq)
155            } else if input.peek(Token![<<=]) {
156                input.parse().map(BinOp::ShlEq)
157            } else if input.peek(Token![>>=]) {
158                input.parse().map(BinOp::ShrEq)
159            } else {
160                parse_binop(input)
161            }
162        }
163    }
164
165    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
166    impl Parse for UnOp {
167        fn parse(input: ParseStream) -> Result<Self> {
168            let lookahead = input.lookahead1();
169            if lookahead.peek(Token![*]) {
170                input.parse().map(UnOp::Deref)
171            } else if lookahead.peek(Token![!]) {
172                input.parse().map(UnOp::Not)
173            } else if lookahead.peek(Token![-]) {
174                input.parse().map(UnOp::Neg)
175            } else {
176                Err(lookahead.error())
177            }
178        }
179    }
180}
181
182#[cfg(feature = "printing")]
183mod printing {
184    use super::*;
185    use proc_macro2::TokenStream;
186    use quote::ToTokens;
187
188    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
189    impl ToTokens for BinOp {
190        fn to_tokens(&self, tokens: &mut TokenStream) {
191            match self {
192                BinOp::Add(t) => t.to_tokens(tokens),
193                BinOp::Sub(t) => t.to_tokens(tokens),
194                BinOp::Mul(t) => t.to_tokens(tokens),
195                BinOp::Div(t) => t.to_tokens(tokens),
196                BinOp::Rem(t) => t.to_tokens(tokens),
197                BinOp::And(t) => t.to_tokens(tokens),
198                BinOp::Or(t) => t.to_tokens(tokens),
199                BinOp::BitXor(t) => t.to_tokens(tokens),
200                BinOp::BitAnd(t) => t.to_tokens(tokens),
201                BinOp::BitOr(t) => t.to_tokens(tokens),
202                BinOp::Shl(t) => t.to_tokens(tokens),
203                BinOp::Shr(t) => t.to_tokens(tokens),
204                BinOp::Eq(t) => t.to_tokens(tokens),
205                BinOp::Lt(t) => t.to_tokens(tokens),
206                BinOp::Le(t) => t.to_tokens(tokens),
207                BinOp::Ne(t) => t.to_tokens(tokens),
208                BinOp::Ge(t) => t.to_tokens(tokens),
209                BinOp::Gt(t) => t.to_tokens(tokens),
210                BinOp::AddEq(t) => t.to_tokens(tokens),
211                BinOp::SubEq(t) => t.to_tokens(tokens),
212                BinOp::MulEq(t) => t.to_tokens(tokens),
213                BinOp::DivEq(t) => t.to_tokens(tokens),
214                BinOp::RemEq(t) => t.to_tokens(tokens),
215                BinOp::BitXorEq(t) => t.to_tokens(tokens),
216                BinOp::BitAndEq(t) => t.to_tokens(tokens),
217                BinOp::BitOrEq(t) => t.to_tokens(tokens),
218                BinOp::ShlEq(t) => t.to_tokens(tokens),
219                BinOp::ShrEq(t) => t.to_tokens(tokens),
220            }
221        }
222    }
223
224    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
225    impl ToTokens for UnOp {
226        fn to_tokens(&self, tokens: &mut TokenStream) {
227            match self {
228                UnOp::Deref(t) => t.to_tokens(tokens),
229                UnOp::Not(t) => t.to_tokens(tokens),
230                UnOp::Neg(t) => t.to_tokens(tokens),
231            }
232        }
233    }
234}