(tc: &TestCase)
| 118 | } |
| 119 | |
| 120 | fn parse_scalar(tc: &TestCase) -> String { |
| 121 | let input = tc.input.trim(); |
| 122 | match parser::parse_expr(input) { |
| 123 | Ok(s) => { |
| 124 | for printed in [s.to_ast_string_simple(), s.to_ast_string_stable()] { |
| 125 | match parser::parse_expr(&printed) { |
| 126 | Ok(parsed) => { |
| 127 | // TODO: We always coerce the double colon operator into a Cast expr instead |
| 128 | // of keeping it as an Op (see parse_pg_cast). Expr::Cast always prints |
| 129 | // itself as double colon. We're thus unable to perfectly roundtrip |
| 130 | // `CAST(..)`. We could fix this by keeping "::" as a binary operator and |
| 131 | // teaching func.rs how to handle it, similar to how that file handles "~~" |
| 132 | // (without the parser converting that operator directly into an |
| 133 | // Expr::Like). |
| 134 | if !matches!(parsed, Expr::Cast { .. }) { |
| 135 | if parsed != s { |
| 136 | panic!( |
| 137 | "reparse comparison failed: {input} != {s}\n{:?}\n!=\n{:?}\n{printed}\n", |
| 138 | s, parsed |
| 139 | ); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | Err(err) => panic!("reparse failed: {printed}: {err}\n{s:?}"), |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | if tc.args.contains_key("roundtrip") { |
| 148 | format!("{}\n", s) |
| 149 | } else { |
| 150 | // TODO(justin): it would be nice to have a middle-ground between this |
| 151 | // all-on-one-line and {:#?}'s huge number of lines. |
| 152 | format!("{:?}\n", s) |
| 153 | } |
| 154 | } |
| 155 | Err(e) => render_error(input, e), |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | match tc.directive.as_str() { |
| 160 | "parse-statement" => parse_statement(tc), |
no test coverage detected