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