1use crate::{
2 ParseableLanguage,
3 config::{
4 ConfigurableLanguage, Formattable, FormattableVec, PrettyPrintError, fill_in_to_pretty,
5 },
6 format::EmptyPlaceholder,
7 formats::formattable_vec,
8};
9
10pub struct Python {
11 module: Vec<rustpython_ast::Stmt>,
12}
13
14pub type PythonParseError = crate::LanguageParseError<rustpython_parser::ParseError>;
15
16impl ParseableLanguage for Python {
17 type CustomError = rustpython_parser::ParseError;
18
19 fn parse(s: &str) -> Result<Self, crate::LanguageParseError<Self::CustomError>> {
20 use rustpython_ast::Mod;
21 use rustpython_parser::{Mode, lexer::lex, parse_tokens};
22
23 let tokens = lex(s, Mode::Expression);
24 let ast = parse_tokens(tokens, Mode::Module, "<embedded>")
25 .map_err(crate::LanguageParseError::Custom)?;
26 match ast {
27 Mod::Module(m) => Ok(Self { module: m.body }),
28 _ => Err(crate::LanguageParseError::ParserError),
29 }
30 }
31}
32
33impl ConfigurableLanguage for Python {
34 type Formats = PythonFormats;
35
36 fn pretty_print<W: std::fmt::Write>(
37 &self,
38 f: &mut W,
39 config: &Self::Formats,
40 ) -> Result<(), PrettyPrintError> {
41 for (idx, stmt) in self.module.iter().enumerate() {
42 if idx > 0 {
43 f.write_char('\n').map_err(PrettyPrintError::Fmt)?;
44 }
45 stmt.pretty_print(f, config)?;
46 }
47 Ok(())
48 }
49}
50
51impl ConfigurableLanguage for rustpython_ast::Stmt {
52 type Formats = PythonFormats;
53
54 fn pretty_print<W: std::fmt::Write>(
55 &self,
56 f: &mut W,
57 formats: &Self::Formats,
58 ) -> Result<(), PrettyPrintError> {
59 match self {
60 rustpython_ast::Stmt::FunctionDef(stmt_function_def) => f
61 .write_str(&stmt_function_def.format(formats)?)
62 .map_err(PrettyPrintError::Fmt),
63 rustpython_ast::Stmt::AsyncFunctionDef(stmt_async_function_def) => f
64 .write_str(&stmt_async_function_def.format(formats)?)
65 .map_err(PrettyPrintError::Fmt),
66 rustpython_ast::Stmt::ClassDef(stmt_class_def) => f
67 .write_str(&stmt_class_def.format(formats)?)
68 .map_err(PrettyPrintError::Fmt),
69 rustpython_ast::Stmt::Return(stmt_return) => f
70 .write_str(&stmt_return.format(formats)?)
71 .map_err(PrettyPrintError::Fmt),
72 rustpython_ast::Stmt::Delete(stmt_delete) => f
73 .write_str(&stmt_delete.format(formats)?)
74 .map_err(PrettyPrintError::Fmt),
75 rustpython_ast::Stmt::Assign(stmt_assign) => f
76 .write_str(&stmt_assign.format(formats)?)
77 .map_err(PrettyPrintError::Fmt),
78 rustpython_ast::Stmt::TypeAlias(stmt_type_alias) => f
79 .write_str(&stmt_type_alias.format(formats)?)
80 .map_err(PrettyPrintError::Fmt),
81 rustpython_ast::Stmt::AugAssign(stmt_aug_assign) => f
82 .write_str(&stmt_aug_assign.format(formats)?)
83 .map_err(PrettyPrintError::Fmt),
84 rustpython_ast::Stmt::AnnAssign(stmt_ann_assign) => f
85 .write_str(&stmt_ann_assign.format(formats)?)
86 .map_err(PrettyPrintError::Fmt),
87 rustpython_ast::Stmt::For(stmt_for) => f
88 .write_str(&stmt_for.format(formats)?)
89 .map_err(PrettyPrintError::Fmt),
90 rustpython_ast::Stmt::AsyncFor(stmt_async_for) => f
91 .write_str(&stmt_async_for.format(formats)?)
92 .map_err(PrettyPrintError::Fmt),
93 rustpython_ast::Stmt::While(stmt_while) => f
94 .write_str(&stmt_while.format(formats)?)
95 .map_err(PrettyPrintError::Fmt),
96 rustpython_ast::Stmt::If(stmt_if) => if stmt_if.orelse.is_empty() {
97 f.write_str(
98 &IfWithoutElse {
99 test: *stmt_if.test.clone(),
100 body: stmt_if.body.clone(),
101 }
102 .format(formats)?,
103 )
104 } else {
105 f.write_str(
106 &IfWithElse {
107 test: *stmt_if.test.clone(),
108 body: stmt_if.body.clone(),
109 orelse: stmt_if.orelse.clone(),
110 }
111 .format(formats)?,
112 )
113 }
114 .map_err(PrettyPrintError::Fmt),
115 rustpython_ast::Stmt::With(stmt_with) => f
116 .write_str(&stmt_with.format(formats)?)
117 .map_err(PrettyPrintError::Fmt),
118 rustpython_ast::Stmt::AsyncWith(stmt_async_with) => f
119 .write_str(&stmt_async_with.format(formats)?)
120 .map_err(PrettyPrintError::Fmt),
121 rustpython_ast::Stmt::Match(stmt_match) => f
122 .write_str(&stmt_match.format(formats)?)
123 .map_err(PrettyPrintError::Fmt),
124 rustpython_ast::Stmt::Raise(stmt_raise) => f
125 .write_str(&stmt_raise.format(formats)?)
126 .map_err(PrettyPrintError::Fmt),
127 rustpython_ast::Stmt::Try(stmt_try) => f
128 .write_str(&stmt_try.format(formats)?)
129 .map_err(PrettyPrintError::Fmt),
130 rustpython_ast::Stmt::TryStar(stmt_try_star) => f
131 .write_str(&stmt_try_star.format(formats)?)
132 .map_err(PrettyPrintError::Fmt),
133 rustpython_ast::Stmt::Assert(stmt_assert) => f
134 .write_str(&stmt_assert.format(formats)?)
135 .map_err(PrettyPrintError::Fmt),
136 rustpython_ast::Stmt::Import(stmt_import) => f
137 .write_str(&stmt_import.format(formats)?)
138 .map_err(PrettyPrintError::Fmt),
139 rustpython_ast::Stmt::ImportFrom(stmt_import_from) => f
140 .write_str(&stmt_import_from.format(formats)?)
141 .map_err(PrettyPrintError::Fmt),
142 rustpython_ast::Stmt::Global(stmt_global) => f
143 .write_str(&stmt_global.format(formats)?)
144 .map_err(PrettyPrintError::Fmt),
145 rustpython_ast::Stmt::Nonlocal(stmt_nonlocal) => f
146 .write_str(&stmt_nonlocal.format(formats)?)
147 .map_err(PrettyPrintError::Fmt),
148 rustpython_ast::Stmt::Expr(stmt_expr) => f
149 .write_str(&stmt_expr.format(formats)?)
150 .map_err(PrettyPrintError::Fmt),
151 rustpython_ast::Stmt::Pass(stmt_pass) => f
152 .write_str(&stmt_pass.format(formats)?)
153 .map_err(PrettyPrintError::Fmt),
154 rustpython_ast::Stmt::Break(stmt_break) => f
155 .write_str(&stmt_break.format(formats)?)
156 .map_err(PrettyPrintError::Fmt),
157 rustpython_ast::Stmt::Continue(stmt_continue) => f
158 .write_str(&stmt_continue.format(formats)?)
159 .map_err(PrettyPrintError::Fmt),
160 }
161 }
162}
163
164impl ConfigurableLanguage for rustpython_ast::Expr {
165 type Formats = PythonFormats;
166
167 fn pretty_print<W: std::fmt::Write>(
168 &self,
169 f: &mut W,
170 formats: &Self::Formats,
171 ) -> Result<(), PrettyPrintError> {
172 match self {
173 rustpython_ast::Expr::BoolOp(expr_bool_op) => f
174 .write_str(&match expr_bool_op.op {
175 rustpython_ast::BoolOp::And => AndExpression {
176 operands: expr_bool_op.values.clone(),
177 }
178 .format(formats)?,
179 rustpython_ast::BoolOp::Or => OrExpression {
180 operands: expr_bool_op.values.clone(),
181 }
182 .format(formats)?,
183 })
184 .map_err(PrettyPrintError::Fmt),
185 rustpython_ast::Expr::NamedExpr(expr_named_expr) => f
186 .write_str(&expr_named_expr.format(formats)?)
187 .map_err(PrettyPrintError::Fmt),
188 rustpython_ast::Expr::BinOp(expr_bin_op) => f
189 .write_str(&match expr_bin_op.op {
190 rustpython_ast::Operator::Add => AddExpression {
191 left: *expr_bin_op.left.clone(),
192 right: *expr_bin_op.right.clone(),
193 }
194 .format(formats)?,
195 rustpython_ast::Operator::Sub => SubExpression {
196 left: *expr_bin_op.left.clone(),
197 right: *expr_bin_op.right.clone(),
198 }
199 .format(formats)?,
200 rustpython_ast::Operator::Mult => MultExpression {
201 left: *expr_bin_op.left.clone(),
202 right: *expr_bin_op.right.clone(),
203 }
204 .format(formats)?,
205 rustpython_ast::Operator::MatMult => MatMultExpression {
206 left: *expr_bin_op.left.clone(),
207 right: *expr_bin_op.right.clone(),
208 }
209 .format(formats)?,
210 rustpython_ast::Operator::Div => DivExpression {
211 left: *expr_bin_op.left.clone(),
212 right: *expr_bin_op.right.clone(),
213 }
214 .format(formats)?,
215 rustpython_ast::Operator::Mod => ModExpression {
216 left: *expr_bin_op.left.clone(),
217 right: *expr_bin_op.right.clone(),
218 }
219 .format(formats)?,
220 rustpython_ast::Operator::Pow => PowExpression {
221 left: *expr_bin_op.left.clone(),
222 right: *expr_bin_op.right.clone(),
223 }
224 .format(formats)?,
225 rustpython_ast::Operator::LShift => LShiftExpression {
226 left: *expr_bin_op.left.clone(),
227 right: *expr_bin_op.right.clone(),
228 }
229 .format(formats)?,
230 rustpython_ast::Operator::RShift => RShiftExpression {
231 left: *expr_bin_op.left.clone(),
232 right: *expr_bin_op.right.clone(),
233 }
234 .format(formats)?,
235 rustpython_ast::Operator::BitOr => BitOrExpression {
236 left: *expr_bin_op.left.clone(),
237 right: *expr_bin_op.right.clone(),
238 }
239 .format(formats)?,
240 rustpython_ast::Operator::BitXor => BitXorExpression {
241 left: *expr_bin_op.left.clone(),
242 right: *expr_bin_op.right.clone(),
243 }
244 .format(formats)?,
245 rustpython_ast::Operator::BitAnd => BitAndExpression {
246 left: *expr_bin_op.left.clone(),
247 right: *expr_bin_op.right.clone(),
248 }
249 .format(formats)?,
250 rustpython_ast::Operator::FloorDiv => FloorDivExpression {
251 left: *expr_bin_op.left.clone(),
252 right: *expr_bin_op.right.clone(),
253 }
254 .format(formats)?,
255 })
256 .map_err(PrettyPrintError::Fmt),
257 rustpython_ast::Expr::UnaryOp(expr_unary_op) => f
258 .write_str(&match expr_unary_op.op {
259 rustpython_ast::UnaryOp::Invert => InvertExpression {
260 operand: *expr_unary_op.operand.clone(),
261 }
262 .format(formats)?,
263 rustpython_ast::UnaryOp::Not => NotExpression {
264 operand: *expr_unary_op.operand.clone(),
265 }
266 .format(formats)?,
267 rustpython_ast::UnaryOp::UAdd => UnaryAddExpression {
268 operand: *expr_unary_op.operand.clone(),
269 }
270 .format(formats)?,
271 rustpython_ast::UnaryOp::USub => UnarySubExpression {
272 operand: *expr_unary_op.operand.clone(),
273 }
274 .format(formats)?,
275 })
276 .map_err(PrettyPrintError::Fmt),
277 rustpython_ast::Expr::Lambda(expr_lambda) => f
278 .write_str(&expr_lambda.format(formats)?)
279 .map_err(PrettyPrintError::Fmt),
280 rustpython_ast::Expr::IfExp(expr_if_exp) => f
281 .write_str(&expr_if_exp.format(formats)?)
282 .map_err(PrettyPrintError::Fmt),
283 rustpython_ast::Expr::Dict(expr_dict) => f
284 .write_str(&expr_dict.format(formats)?)
285 .map_err(PrettyPrintError::Fmt),
286 rustpython_ast::Expr::Set(expr_set) => f
287 .write_str(&expr_set.format(formats)?)
288 .map_err(PrettyPrintError::Fmt),
289 rustpython_ast::Expr::ListComp(expr_list_comp) => f
290 .write_str(&expr_list_comp.format(formats)?)
291 .map_err(PrettyPrintError::Fmt),
292 rustpython_ast::Expr::SetComp(expr_set_comp) => f
293 .write_str(&expr_set_comp.format(formats)?)
294 .map_err(PrettyPrintError::Fmt),
295 rustpython_ast::Expr::DictComp(expr_dict_comp) => f
296 .write_str(&expr_dict_comp.format(formats)?)
297 .map_err(PrettyPrintError::Fmt),
298 rustpython_ast::Expr::GeneratorExp(expr_generator_exp) => f
299 .write_str(&expr_generator_exp.format(formats)?)
300 .map_err(PrettyPrintError::Fmt),
301 rustpython_ast::Expr::Await(expr_await) => f
302 .write_str(&expr_await.format(formats)?)
303 .map_err(PrettyPrintError::Fmt),
304 rustpython_ast::Expr::Yield(expr_yield) => f
305 .write_str(&expr_yield.format(formats)?)
306 .map_err(PrettyPrintError::Fmt),
307 rustpython_ast::Expr::YieldFrom(expr_yield_from) => f
308 .write_str(&expr_yield_from.format(formats)?)
309 .map_err(PrettyPrintError::Fmt),
310 rustpython_ast::Expr::Compare(expr_compare) => {
311 let combinations = (std::iter::once(*expr_compare.left.clone()))
314 .chain(expr_compare.comparators.clone())
315 .zip(expr_compare.comparators.clone())
316 .zip(expr_compare.ops.iter());
317
318 let mut operands = Vec::new();
319 for ((left, right), op) in combinations {
320 operands.push(match op {
321 rustpython_ast::CmpOp::Eq => {
322 EqualExpression { left, right }.format(formats)?
323 }
324 rustpython_ast::CmpOp::NotEq => {
325 NotEqualExpression { left, right }.format(formats)?
326 }
327 rustpython_ast::CmpOp::Lt => {
328 LessThanExpression { left, right }.format(formats)?
329 }
330 rustpython_ast::CmpOp::LtE => {
331 LessThanOrEqualExpression { left, right }.format(formats)?
332 }
333 rustpython_ast::CmpOp::Gt => {
334 GreaterThanExpression { left, right }.format(formats)?
335 }
336 rustpython_ast::CmpOp::GtE => {
337 GreaterThanOrEqualExpression { left, right }.format(formats)?
338 }
339 rustpython_ast::CmpOp::Is => {
340 IsExpression { left, right }.format(formats)?
341 }
342 rustpython_ast::CmpOp::IsNot => {
343 IsNotExpression { left, right }.format(formats)?
344 }
345 rustpython_ast::CmpOp::In => {
346 InExpression { left, right }.format(formats)?
347 }
348 rustpython_ast::CmpOp::NotIn => {
349 NotInExpression { left, right }.format(formats)?
350 }
351 });
352 }
353
354 f.write_str(&AndExpressionForCompare { operands }.format(formats)?)
355 .map_err(PrettyPrintError::Fmt)
356 }
357 rustpython_ast::Expr::Call(expr_call) => f
358 .write_str(&{
359 if let rustpython_ast::Expr::Name(rustpython_ast::ExprName {
360 id: name, ..
361 }) = *expr_call.func.clone()
362 {
363 if name.as_str() == "print" {
364 if expr_call.args.len() == 1 && expr_call.keywords.is_empty() {
365 PythonPrintWithOneArgument {
366 argument: expr_call.args[0].clone(),
367 }
368 .format(formats)?
369 } else if expr_call.keywords.is_empty() {
370 PythonPrintWithMultipleArguments {
371 arguments: expr_call.args.clone(),
372 }
373 .format(formats)?
374 } else {
375 expr_call.format(formats)?
376 }
377 } else if name.as_str() == "input" {
378 if expr_call.args.is_empty() && expr_call.keywords.is_empty() {
379 PythonInputNoArgument.format(formats)?
380 } else if expr_call.args.len() == 1 && expr_call.keywords.is_empty() {
381 PythonInputWithOneArgument {
382 argument: expr_call.args[0].clone(),
383 }
384 .format(formats)?
385 } else {
386 expr_call.format(formats)?
387 }
388 } else {
389 expr_call.format(formats)?
390 }
391 } else {
392 expr_call.format(formats)?
393 }
394 })
395 .map_err(PrettyPrintError::Fmt),
396 rustpython_ast::Expr::FormattedValue(expr_formatted_value) => f
397 .write_str(&expr_formatted_value.format(formats)?)
398 .map_err(PrettyPrintError::Fmt),
399 rustpython_ast::Expr::JoinedStr(expr_joined_str) => f
400 .write_str(&expr_joined_str.format(formats)?)
401 .map_err(PrettyPrintError::Fmt),
402 rustpython_ast::Expr::Constant(expr_constant) => f
403 .write_str(&expr_constant.format(formats)?)
404 .map_err(PrettyPrintError::Fmt),
405 rustpython_ast::Expr::Attribute(expr_attribute) => f
406 .write_str(&expr_attribute.format(formats)?)
407 .map_err(PrettyPrintError::Fmt),
408 rustpython_ast::Expr::Subscript(expr_subscript) => f
409 .write_str(&expr_subscript.format(formats)?)
410 .map_err(PrettyPrintError::Fmt),
411 rustpython_ast::Expr::Starred(expr_starred) => f
412 .write_str(&expr_starred.format(formats)?)
413 .map_err(PrettyPrintError::Fmt),
414 rustpython_ast::Expr::Name(expr_name) => f
415 .write_str(&expr_name.format(formats)?)
416 .map_err(PrettyPrintError::Fmt),
417 rustpython_ast::Expr::List(expr_list) => f
418 .write_str(&expr_list.format(formats)?)
419 .map_err(PrettyPrintError::Fmt),
420 rustpython_ast::Expr::Tuple(expr_tuple) => f
421 .write_str(&expr_tuple.format(formats)?)
422 .map_err(PrettyPrintError::Fmt),
423 rustpython_ast::Expr::Slice(expr_slice) => f
424 .write_str(&expr_slice.format(formats)?)
425 .map_err(PrettyPrintError::Fmt),
426 }
427 }
428}
429
430crate::formats::formats!(
431 struct PythonFormats {
432 function_def: rustpython_ast::StmtFunctionDef: PythonFunctionDefPlaceholder {
434 Name => name,
436 Arguments => args,
438 Body => body,
440 DecoratorList => decorator_list,
442 Returns => returns,
444 TypeComment => type_comment,
446 TypeParams => type_params
448 },
449
450 async_function_def: rustpython_ast::StmtAsyncFunctionDef: PythonAsyncFunctionDefPlaceholder {
451 Name => name,
453 Arguments => args,
455 Body => body,
457 DecoratorList => decorator_list,
459 Returns => returns,
461 TypeComment => type_comment,
463 TypeParams => type_params
465 },
466
467 class_def: rustpython_ast::StmtClassDef: PythonClassDefPlaceholder {
468 Name => name,
470 Bases => bases,
472 Keywords => keywords,
474 Body => body,
476 DecoratorList => decorator_list,
478 TypeParams => type_params
480 },
481
482 r#return: rustpython_ast::StmtReturn: PythonReturnPlaceholder {
483 Value => value
485 },
486
487 delete: rustpython_ast::StmtDelete: PythonDeletePlaceholder {
488 Targets => targets
490 },
491
492 assign: rustpython_ast::StmtAssign: PythonAssignPlaceholder {
493 Targets => targets,
497 Value => value,
499 TypeComment => type_comment
501 },
502
503 type_alias: rustpython_ast::StmtTypeAlias: PythonTypeAliasPlaceholder {
504 Name => name,
506 TypeParams => type_params,
508 Value => value
510 },
511
512 augmented_assign: rustpython_ast::StmtAugAssign: PythonAugmentedAssignPlaceholder {
514 Target => target,
516 Value => value
520 },
521
522 annotated_assign: rustpython_ast::StmtAnnAssign: PythonAnnotatedAssignPlaceholder {
524 Target => target,
526 Annotation => annotation,
528 Value => value
530 },
531
532 r#for: rustpython_ast::StmtFor: PythonForPlaceholder {
533 Target => target,
536 Iter => iter,
538 Body => body,
540 OrElse => orelse,
542 TypeComment => type_comment
544 },
545
546 async_for: rustpython_ast::StmtAsyncFor: PythonAsyncForPlaceholder {
547 Target => target,
550 Iter => iter,
552 Body => body,
554 OrElse => orelse,
556 TypeComment => type_comment
558 },
559
560 r#while: rustpython_ast::StmtWhile: PythonWhilePlaceholder {
561 Test => test,
563 Body => body,
565 OrElse => orelse
567 },
568
569 if_without_else: IfWithoutElse: PythonIfWithoutElsePlaceholder {
570 Test => test,
572 Body => body
574 },
575
576 if_with_else: IfWithElse: PythonIfWithElsePlaceholder {
577 Test => test,
579 Body => body,
581 OrElse => orelse
583 },
584
585
586 with: rustpython_ast::StmtWith: PythonWithPlaceholder {
587 Items => items,
589 Body => body,
591 TypeComment => type_comment
593 },
594
595 async_with: rustpython_ast::StmtAsyncWith: PythonAsyncWithPlaceholder {
596 Items => items,
598 Body => body,
600 TypeComment => type_comment
602 },
603
604 r#match: rustpython_ast::StmtMatch: PythonMatchPlaceholder {
605 Subject => subject,
607 Cases => cases
609 },
610
611 raise: rustpython_ast::StmtRaise: PythonRaisePlaceholder {
612 Exception => exc,
614 Cause => cause
616 },
617
618 r#try: rustpython_ast::StmtTry: PythonTryPlaceholder {
619 Body => body,
621 Handlers => handlers,
623 OrElse => orelse,
625 FinalBody => finalbody
627 },
628
629 r#try_star: rustpython_ast::StmtTryStar: PythonTryStarPlaceholder {
630 Body => body,
632 Handlers => handlers,
634 OrElse => orelse,
636 FinalBody => finalbody
638 },
639
640 assert: rustpython_ast::StmtAssert: PythonAssertPlaceholder {
641 Test => test,
643 Message => msg
645 },
646
647 import: rustpython_ast::StmtImport: PythonImportPlaceholder {
648 Names => names
650 },
651
652 import_from: rustpython_ast::StmtImportFrom: PythonImportFromPlaceholder {
653 Module => module,
655 Names => names
657 },
658
659 global: rustpython_ast::StmtGlobal: PythonGlobalPlaceholder {
660 Names => names
662 },
663
664 non_local: rustpython_ast::StmtNonlocal: PythonNonLocalPlaceholder {
665 Names => names
667 },
668
669 expression_statement: rustpython_ast::StmtExpr: PythonExpressionStatementPlaceholder {
670 Value => value
672 },
673
674 pass: rustpython_ast::StmtPass: PythonPassPlaceholder EmptyPlaceholder,
675 r#break: rustpython_ast::StmtBreak: PythonBreakPlaceholder EmptyPlaceholder,
676 r#continue: rustpython_ast::StmtContinue: PythonContinuePlaceholder EmptyPlaceholder,
677
678
679 and_expression: AndExpression: PythonExprAndPlaceholder {
690 Operands => operands
692 },
693 or_expression: OrExpression: PythonExprOrPlaceholder {
694 Operands => operands
696 },
697
698 named_expr: rustpython_ast::ExprNamedExpr: PythonNamedExprPlaceholder {
700 Target => target,
702 Value => value
704 },
705
706 add_operation: AddExpression: PythonExprAddPlaceholder {
707 Left => left,
709 Right => right
711 },
712
713 sub_operation: SubExpression: PythonExprSubPlaceholder {
714 Left => left,
716 Right => right
718 },
719
720 mul_operation: MultExpression: PythonExprMultPlaceholder {
721 Left => left,
723 Right => right
725 },
726
727 mat_mul_operation: MatMultExpression: PythonExprMatMultPlaceholder {
728 Left => left,
730 Right => right
732 },
733
734 div_operation: DivExpression: PythonExprDivPlaceholder {
735 Left => left,
737 Right => right
739 },
740
741 mod_operation: ModExpression: PythonExprModPlaceholder {
742 Left => left,
744 Right => right
746 },
747
748 pow_operation: PowExpression: PythonExprPowPlaceholder {
749 Left => left,
751 Right => right
753 },
754
755 lshift_operation: LShiftExpression: PythonExprLShiftPlaceholder {
756 Left => left,
758 Right => right
760 },
761
762 rshift_operation: RShiftExpression: PythonExprRShiftPlaceholder {
763 Left => left,
765 Right => right
767 },
768
769 bit_or_operation: BitOrExpression: PythonExprBitOrPlaceholder {
770 Left => left,
772 Right => right
774 },
775
776 bit_xor_operation: BitXorExpression: PythonExprBitXorPlaceholder {
777 Left => left,
779 Right => right
781 },
782
783 bit_and_operation: BitAndExpression: PythonExprBitAndPlaceholder {
784 Left => left,
786 Right => right
788 },
789
790 floor_div_operation: FloorDivExpression: PythonExprFloorDivPlaceholder {
791 Left => left,
793 Right => right
795 },
796
797 invert_operation: InvertExpression: PythonExprInvertPlaceholder {
798 Operand => operand
800 },
801
802 not_operation: NotExpression: PythonExprNotPlaceholder {
803 Operand => operand
805 },
806
807 unary_add_operation: UnaryAddExpression: PythonExprUnaryAddPlaceholder {
808 Operand => operand
810 },
811
812 unary_sub_operation: UnarySubExpression: PythonExprUnarySubPlaceholder {
813 Operand => operand
815 },
816
817 lambda: rustpython_ast::ExprLambda: PythonLambdaPlaceholder {
818 Arguments => args,
820 Body => body
822 },
823
824 if_expression: rustpython_ast::ExprIfExp: PythonIfExprPlaceholder {
825 Test => test,
827 Body => body,
829 OrElse => orelse
831 },
832
833 dict_expression: rustpython_ast::ExprDict: PythonDictExprPlaceholder {
834 Keys => keys,
836 Values => values
838 },
839
840 set_expression: rustpython_ast::ExprSet: PythonSetExprPlaceholder {
841 Elements => elts
843 },
844
845 list_comprehension: rustpython_ast::ExprListComp: PythonListComprehensionPlaceholder {
846 Body => elt,
848 Generators => generators
850 },
851
852 set_comprehension: rustpython_ast::ExprSetComp: PythonSetComprehensionPlaceholder {
853 Body => elt,
855 Generators => generators
857 },
858
859 dict_comprehension: rustpython_ast::ExprDictComp: PythonDictComprehensionPlaceholder {
860 Key => key,
862 Value => value,
864 Generators => generators
866 },
867
868 generator_comprehension: rustpython_ast::ExprGeneratorExp: PythonGeneratorComprehensionPlaceholder {
869 Body => elt,
871 Generators => generators
873 },
874
875 r#await: rustpython_ast::ExprAwait: PythonAwaitPlaceholder {
876 Value => value
878 },
879
880 r#yield: rustpython_ast::ExprYield: PythonYieldPlaceholder {
881 Value => value
883 },
884
885 r#yield_from: rustpython_ast::ExprYieldFrom: PythonYieldFromPlaceholder {
886 Value => value
888 },
889
890 equal_operation: EqualExpression: PythonEqualPlaceholder {
892 Left => left,
894 Right => right
896 },
897
898 not_equal_operation: NotEqualExpression: PythonNotEqualPlaceholder {
899 Left => left,
901 Right => right
903 },
904
905 less_than_operation: LessThanExpression: PythonLessThanPlaceholder {
906 Left => left,
908 Right => right
910 },
911
912 less_than_or_equal_operation: LessThanOrEqualExpression: PythonLessThanOrEqualPlaceholder {
913 Left => left,
915 Right => right
917 },
918
919 greater_than_operation: GreaterThanExpression: PythonGreaterThanPlaceholder {
920 Left => left,
922 Right => right
924 },
925
926 greater_than_or_equal_operation: GreaterThanOrEqualExpression: PythonGreaterThanOrEqualPlaceholder {
927 Left => left,
929 Right => right
931 },
932
933 is_operation: IsExpression: PythonIsPlaceholder {
934 Left => left,
936 Right => right
938 },
939
940 is_not_operation: IsNotExpression: PythonIsNotPlaceholder {
941 Left => left,
943 Right => right
945 },
946
947 in_operation: InExpression: PythonInPlaceholder {
948 Left => left,
950 Right => right
952 },
953
954 not_in_operation: NotInExpression: PythonNotInPlaceholder {
955 Left => left,
957 Right => right
959 },
960
961 call: rustpython_ast::ExprCall: PythonCallPlaceholder {
962 Function => func,
964 PositionalArguments => args,
966 KeywordArguments => keywords
968 },
969
970 print_call_one_argument: PythonPrintWithOneArgument: PythonPrintWithOneArgumentPlaceholder {
971 Argument => argument
973 },
974
975 print_call_multiple_arguments: PythonPrintWithMultipleArguments: PythonPrintWithMultipleArgumentsPlaceholder {
976 Arguments => arguments
978 },
979
980 input_call_no_argument: PythonInputNoArgument: EmptyPlaceholder,
981
982 input_call_one_argument: PythonInputWithOneArgument: PythonInputWithOneArgumentPlaceholder {
983 Argument => argument
985 },
986
987 formatted_value: rustpython_ast::ExprFormattedValue: PythonFormattedValuePlaceholder {
988 Value => value,
990 FormatSpecification => format_spec
992 },
993
994 joined_string: rustpython_ast::ExprJoinedStr: PythonJoinedStringPlaceholder {
995 Values => values
997 },
998
999 constant_expression: rustpython_ast::ExprConstant: PythonConstantExpressionPlaceholder {
1000 Value => value
1002 },
1003
1004 attribute: rustpython_ast::ExprAttribute: PythonAttributePlaceholder {
1006 Value => value,
1008 Attribute => attr
1010 },
1011
1012 subscript: rustpython_ast::ExprSubscript: PythonSubscriptPlaceholder {
1014 Value => value,
1016 Slice => slice
1018 },
1019
1020 starred: rustpython_ast::ExprStarred: PythonStarredPlaceholder {
1022 Value => value
1024 },
1025
1026 name: rustpython_ast::ExprName: PythonNamePlaceholder {
1028 Identifier => id
1030 },
1031
1032 list: rustpython_ast::ExprList: PythonListPlaceholder {
1034 Elements => elts
1036 },
1037
1038 tuple: rustpython_ast::ExprTuple: PythonTuplePlaceholder {
1040 Elements => elts
1042 },
1043
1044 slice: rustpython_ast::ExprSlice: PythonSlicePlaceholder {
1045 Lower => lower,
1047 Upper => upper,
1049 Step => step
1051 },
1052
1053 identifier: rustpython_ast::Identifier: PythonIdentifierPlaceholder {
1055 Value for to_string
1057 },
1058
1059 arguments: rustpython_ast::Arguments: PythonArgumentsPlaceholder {
1060 PositionOnlyArguments => posonlyargs,
1063 Arguments => args,
1065 VariableNumberArguments => vararg,
1067 KeywordOnlyArguments => kwonlyargs,
1069 KeywordArguments => kwarg
1071 },
1072
1073 argument: rustpython_ast::Arg: PythonArgumentPlaceholder {
1074 Identifier => arg,
1076 Annotation => annotation,
1078 TypeComment => type_comment
1080 },
1081
1082 argument_with_default: rustpython_ast::ArgWithDefault: PythonArgumentWithDefaultPlaceholder {
1083 Argument => def,
1085 Default => default
1087 },
1088
1089 comprehension: rustpython_ast::Comprehension: PythonComprehensionPlaceholder {
1091 Target => target,
1093 Iterator => iter,
1095 Ifs => ifs
1097 },
1098
1099 keyword: rustpython_ast::Keyword: PythonKeywordPlaceholder {
1100 Name => arg,
1102 Value => value
1104 },
1105
1106 constant_none: ConstantNone: PythonConstantNonePlaceholder EmptyPlaceholder,
1107
1108 constant_bool: ConstantBool: PythonConstantBoolPlaceholder {
1109 Value => value
1111 },
1112
1113 constant_string: ConstantString: PythonConstantStringPlaceholder {
1114 Value => value
1116 },
1117
1118 constant_bytes: ConstantBytes: PythonConstantBytesPlaceholder {
1119 Bytes => bytes
1121 },
1122
1123 constant_integer: ConstantInt: PythonConstantIntegerPlaceholder {
1124 Value => value
1126 },
1127
1128 constant_tuples: ConstantTuple: PythonConstantTuplePlaceholder {
1129 Items => items
1131 },
1132
1133 constant_float: ConstantFloat: PythonConstantFloatPlaceholder {
1134 Value => value
1136 },
1137
1138 constant_complex: ConstantComplex: PythonConstantComplexPlaceholder {
1139 Real => real,
1141 Imaginary => imaginary
1143 },
1144
1145 constant_ellipsis: ConstantEllipsis: PythonConstantEllipsisPlaceholder EmptyPlaceholder,
1146
1147 with_item: rustpython_ast::WithItem: PythonWithItemPlaceholder {
1148 ContextExpr => context_expr,
1150 OptionalVariables => optional_vars
1152 },
1153
1154 match_case: rustpython_ast::MatchCase: PythonMatchCasePlaceholder {
1155 Pattern => pattern,
1157 Guard => guard,
1159 Body => body
1161 },
1162
1163 except_handler: rustpython_ast::ExceptHandlerExceptHandler: PythonExceptHandlerPlaceholder {
1164 Type => type_,
1166 Name => name,
1168 Body => body
1170 },
1171
1172 alias: rustpython_ast::Alias: PythonAliasPlaceholder {
1173 Original => name,
1175 AsName => asname
1177 }
1178
1179 }
1180);
1181
1182pub struct AndExpressionForCompare {
1183 operands: Vec<String>,
1184}
1185
1186impl Formattable<PythonFormats> for AndExpressionForCompare {
1187 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1188 if self.operands.len() == 1 {
1189 Ok(self.operands[0].clone())
1190 } else {
1191 formatting
1192 .and_expression
1193 .filled_in_string(
1194 "comparison_operators",
1195 &vec![(PythonExprAndPlaceholder::Operands, self.operands.clone())]
1196 .into_iter()
1197 .collect(),
1198 )
1199 .map_err(fill_in_to_pretty("and_expression (for comparisons)"))
1200 }
1201 }
1202}
1203
1204pub struct AndExpression {
1205 operands: Vec<rustpython_ast::Expr>,
1206}
1207
1208pub struct OrExpression {
1209 operands: Vec<rustpython_ast::Expr>,
1210}
1211
1212macro_rules! binary_expression {
1213 ($ident: ident) => {
1214 pub struct $ident {
1215 left: rustpython_ast::Expr,
1216 right: rustpython_ast::Expr,
1217 }
1218 };
1219}
1220
1221binary_expression!(AddExpression);
1222binary_expression!(SubExpression);
1223binary_expression!(MultExpression);
1224binary_expression!(MatMultExpression);
1225binary_expression!(DivExpression);
1226binary_expression!(ModExpression);
1227binary_expression!(PowExpression);
1228binary_expression!(LShiftExpression);
1229binary_expression!(RShiftExpression);
1230binary_expression!(BitOrExpression);
1231binary_expression!(BitXorExpression);
1232binary_expression!(BitAndExpression);
1233binary_expression!(FloorDivExpression);
1234
1235binary_expression!(EqualExpression);
1236binary_expression!(NotEqualExpression);
1237binary_expression!(LessThanExpression);
1238binary_expression!(LessThanOrEqualExpression);
1239binary_expression!(GreaterThanExpression);
1240binary_expression!(GreaterThanOrEqualExpression);
1241binary_expression!(IsExpression);
1242binary_expression!(IsNotExpression);
1243binary_expression!(InExpression);
1244binary_expression!(NotInExpression);
1245
1246macro_rules! unary_expression {
1247 ($ident: ident) => {
1248 pub struct $ident {
1249 operand: rustpython_ast::Expr,
1250 }
1251 };
1252}
1253
1254unary_expression!(InvertExpression);
1255unary_expression!(NotExpression);
1256unary_expression!(UnaryAddExpression);
1257unary_expression!(UnarySubExpression);
1258pub struct ConstantNone;
1259pub struct ConstantBool {
1260 value: bool,
1261}
1262pub struct ConstantString {
1263 value: String,
1264}
1265
1266pub struct LiteralBytes(Vec<u8>);
1268
1269pub struct ConstantBytes {
1270 bytes: LiteralBytes,
1271}
1272pub struct ConstantInt {
1273 value: rustpython_ast::bigint::BigInt,
1274}
1275pub struct ConstantTuple {
1276 items: Vec<rustpython_ast::Constant>,
1277}
1278pub struct ConstantFloat {
1279 value: f64,
1280}
1281pub struct ConstantComplex {
1282 real: f64,
1283 imaginary: f64,
1284}
1285pub struct ConstantEllipsis;
1286
1287pub struct IfWithoutElse {
1288 pub test: rustpython_ast::Expr,
1289 pub body: Vec<rustpython_ast::Stmt>,
1290}
1291
1292pub struct IfWithElse {
1293 pub test: rustpython_ast::Expr,
1294 pub body: Vec<rustpython_ast::Stmt>,
1295 pub orelse: Vec<rustpython_ast::Stmt>,
1296}
1297
1298pub struct PythonPrintWithOneArgument {
1299 argument: rustpython_ast::Expr,
1300}
1301
1302pub struct PythonPrintWithMultipleArguments {
1303 arguments: Vec<rustpython_ast::Expr>,
1304}
1305
1306pub struct PythonInputNoArgument;
1307
1308pub struct PythonInputWithOneArgument {
1309 argument: rustpython_ast::Expr,
1310}
1311
1312impl Formattable<PythonFormats> for LiteralBytes {
1313 fn format(&self, _formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1314 Err(PrettyPrintError::UnsupportedFeature {
1315 description: format!("Literal byte arrays"),
1316 })
1317 }
1318}
1319formattable_vec!(LiteralBytes);
1320
1321impl Formattable<PythonFormats> for rustpython_ast::bigint::BigInt {
1322 fn format(&self, _formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1323 Ok(self.to_string())
1324 }
1325}
1326formattable_vec!(rustpython_ast::bigint::BigInt);
1327
1328impl Formattable<PythonFormats> for rustpython_ast::ExceptHandler {
1329 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1330 match self {
1331 rustpython_ast::ExceptHandler::ExceptHandler(except_handler_except_handler) => {
1332 except_handler_except_handler.format(formatting)
1333 }
1334 }
1335 }
1336}
1337formattable_vec!(rustpython_ast::ExceptHandler);
1338
1339impl Formattable<PythonFormats> for rustpython_ast::Constant {
1340 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1341 match self {
1342 rustpython_ast::Constant::None => ConstantNone.format(formatting),
1343 rustpython_ast::Constant::Bool(bool) => {
1344 ConstantBool { value: *bool }.format(formatting)
1345 }
1346 rustpython_ast::Constant::Str(s) => {
1347 ConstantString { value: s.clone() }.format(formatting)
1348 }
1349 rustpython_ast::Constant::Bytes(items) => ConstantBytes {
1350 bytes: LiteralBytes(items.clone()),
1351 }
1352 .format(formatting),
1353 rustpython_ast::Constant::Int(big_int) => ConstantInt {
1354 value: big_int.clone(),
1355 }
1356 .format(formatting),
1357 rustpython_ast::Constant::Tuple(constants) => ConstantTuple {
1358 items: constants.clone(),
1359 }
1360 .format(formatting),
1361 rustpython_ast::Constant::Float(f) => ConstantFloat { value: *f }.format(formatting),
1362 rustpython_ast::Constant::Complex { real, imag } => ConstantComplex {
1363 real: *real,
1364 imaginary: *imag,
1365 }
1366 .format(formatting),
1367 rustpython_ast::Constant::Ellipsis => ConstantEllipsis.format(formatting),
1368 }
1369 }
1370}
1371
1372formattable_vec!(rustpython_ast::Constant);
1373
1374impl Formattable<PythonFormats> for rustpython_ast::Stmt {
1375 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1376 let mut f = String::new();
1377 self.pretty_print(&mut f, formatting)?;
1378 Ok(f)
1379 }
1380}
1381formattable_vec!(rustpython_ast::Stmt);
1382
1383impl FormattableVec<PythonFormats> for Vec<Option<rustpython_ast::Expr>> {
1384 fn format_vec(&self, _formatting: &PythonFormats) -> Result<Vec<String>, PrettyPrintError> {
1385 Err(PrettyPrintError::UnsupportedFeature {
1386 description: format!("vec option expr"),
1387 })
1388 }
1397}
1398
1399impl Formattable<PythonFormats> for rustpython_ast::Expr {
1400 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1401 let mut f = String::new();
1402 self.pretty_print(&mut f, formatting)?;
1403 Ok(f)
1404 }
1405}
1406formattable_vec!(rustpython_ast::Expr);
1407
1408impl Formattable<PythonFormats> for rustpython_ast::TypeParam {
1410 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1411 Err(PrettyPrintError::UnsupportedFeature {
1412 description: format!("Type params"),
1413 })
1414 }
1415}
1416formattable_vec!(rustpython_ast::TypeParam);
1417
1418impl Formattable<PythonFormats> for rustpython_ast::Pattern {
1420 fn format(&self, formatting: &PythonFormats) -> Result<String, PrettyPrintError> {
1421 Err(PrettyPrintError::UnsupportedFeature {
1422 description: format!("Patterns"),
1423 })
1424 }
1425}
1426formattable_vec!(rustpython_ast::Pattern);
1427
1428pub fn example_format() -> PythonFormats {
1429 use crate::format::{Format, PossibleFormat};
1430 use std::str::FromStr;
1431
1432 PythonFormats {
1433 input_call_no_argument: PossibleFormat::empty(),
1434 input_call_one_argument: PossibleFormat::empty(),
1435 print_call_one_argument: PossibleFormat::empty(),
1436 print_call_multiple_arguments: PossibleFormat::empty(),
1437 function_def: PossibleFormat::empty(),
1438 async_function_def: PossibleFormat::empty(),
1439 class_def: PossibleFormat::empty(),
1440 r#return: PossibleFormat::empty(),
1441 delete: PossibleFormat::empty(),
1442 assign: Format::from_str(r"evaluate\ $value\ and\ assign\ it\ to\ $targets").expect("format parsing to work").into(),
1443 type_alias: PossibleFormat::empty(),
1444 augmented_assign: PossibleFormat::empty(),
1445 annotated_assign: PossibleFormat::empty(),
1446 r#for: PossibleFormat::empty(),
1447 async_for: PossibleFormat::empty(),
1448 r#while: PossibleFormat::empty(),
1449 if_without_else: Format::from_str(r"When\n
1450>>>>$test\n
1451 is\ seen\ as\ true\n
1452 >>>>do\n
1453 >>>>$body
1454 <<<<
1455 <<<<
1456<<<<").expect("parsing to work").into(),
1457 if_with_else: Format::from_str(
1458 r"When\n
1459>>>>$test\n
1460 is\ seen\ as\ true\n
1461 >>>>do\n
1462 >>>>$body
1463 <<<<
1464 <<<<\n
1465 else,\ if\ it\ is\ seen\ as\ false,\n
1466 >>>>do\n
1467 >>>>$or_else
1468 <<<<
1469 <<<<
1470<<<<"
1471 ).expect("parsing to work")
1472 .into(),
1473 with: PossibleFormat::empty(),
1474 async_with: PossibleFormat::empty(),
1475 r#match: PossibleFormat::empty(),
1476 raise: PossibleFormat::empty(),
1477 r#try: PossibleFormat::empty(),
1478 try_star: PossibleFormat::empty(),
1479 assert: PossibleFormat::empty(),
1480 import: PossibleFormat::empty(),
1481 import_from: PossibleFormat::empty(),
1482 global: PossibleFormat::empty(),
1483 non_local: PossibleFormat::empty(),
1484 expression_statement: PossibleFormat::empty(),
1485 pass: PossibleFormat::empty(),
1486 r#break: PossibleFormat::empty(),
1487 r#continue: PossibleFormat::empty(),
1488 and_expression: Format::from_str(r"
1489each\ of\ the\ following\ conditions\ (when\ one\ evaluates\ to\ false,\ we\ do\ not\ evaluate\ the\ remaining\ conditions)\n
1490 >>>>{{{{ $operands as -\ $operands & \n }}}}
1491 <<<<
1492").expect("parsing to work")
1493 .into(),
1494 or_expression: PossibleFormat::empty(),
1495 named_expr: PossibleFormat::empty(),
1496 add_operation: Format::from_str(r"($left\ +\ $right)").expect("parsing to work").into(),
1497 sub_operation: Format::from_str(r"($left\ -\ $right)").expect("parsing to work").into(),
1498 mul_operation: Format::from_str(r"($left\ *\ $right)").expect("parsing to work").into(),
1499 mat_mul_operation: Format::from_str(r"($left\ @\ $right)").expect("parsing to work").into(),
1500 div_operation: Format::from_str(r"($left\ /\ $right)").expect("parsing to work").into(),
1501 mod_operation: Format::from_str(r"($left\ %\ $right)").expect("parsing to work").into(),
1502 pow_operation: Format::from_str(r"($left\ **\ $right)").expect("parsing to work").into(),
1503 lshift_operation: PossibleFormat::empty(),
1504 rshift_operation: PossibleFormat::empty(),
1505 bit_or_operation: PossibleFormat::empty(),
1506 bit_xor_operation: PossibleFormat::empty(),
1507 bit_and_operation: PossibleFormat::empty(),
1508 floor_div_operation: Format::from_str(r"($left\ //\ $right)").expect("parsing to work").into(),
1509 invert_operation: PossibleFormat::empty(),
1510 not_operation: PossibleFormat::empty(),
1511 unary_add_operation: PossibleFormat::empty(),
1512 unary_sub_operation: PossibleFormat::empty(),
1513 lambda: PossibleFormat::empty(),
1514 if_expression: PossibleFormat::empty(),
1515 dict_expression: PossibleFormat::empty(),
1516 set_expression: PossibleFormat::empty(),
1517 list_comprehension: PossibleFormat::empty(),
1518 set_comprehension: PossibleFormat::empty(),
1519 dict_comprehension: PossibleFormat::empty(),
1520 generator_comprehension: PossibleFormat::empty(),
1521 r#await: PossibleFormat::empty(),
1522 r#yield: PossibleFormat::empty(),
1523 yield_from: PossibleFormat::empty(),
1524 equal_operation: Format::from_str(r"the\ equality\ comparison\ of\ the\ result\ of\ $left\ with\ the\ result\ of\ $right").expect("failed parsing").into(),
1525 not_equal_operation: Format::from_str(r"the\ result\ of\ $left\ is\ different\ from\ the\ result\ of\ $right").expect("failed parsing").into(),
1526 less_than_operation: Format::from_str(r"the\ result\ of\ $left\ is\ less\ than\ the\ result\ of\ $right").expect("failed parsing").into(),
1527 less_than_or_equal_operation: Format::from_str(r"the\ result\ of\ $left\ is\ less\ than\ or\ equal\ to\ the\ result\ of\ $right").expect("failed parsing").into(),
1528 greater_than_operation: Format::from_str(r"the\ result\ of\ $left\ is\ greater\ than\ the\ result\ of\ $right").expect("failed parsing").into(),
1529 greater_than_or_equal_operation: Format::from_str(r"the\ result\ of\ $left\ is\ greater\ than\ or\ equal\ to\ the\ result\ of\ $right").expect("failed parsing").into(),
1530 is_operation: Format::from_str(r"the\ result\ of\ $left\ refers\ to\ the\ same\ object\ as\ the\ result\ of\ $right").expect("failed parsing").into(),
1531 is_not_operation: Format::from_str(r"the\ result\ of\ $left\ does\ not\ refer\ to\ the\ same\ object\ as\ the\ result\ of\ $right").expect("failed parsing").into(),
1532 in_operation: PossibleFormat::empty(),
1533 not_in_operation: PossibleFormat::empty(),
1534 call: PossibleFormat::empty(),
1535 formatted_value: PossibleFormat::empty(),
1536 joined_string: PossibleFormat::empty(),
1537 constant_expression: Format::from_str(r"the\ literal\ $value").expect("parsing failed").into(),
1538 attribute: PossibleFormat::empty(),
1539 subscript: PossibleFormat::empty(),
1540 starred: PossibleFormat::empty(),
1541 name: Format::from_str(r"the\ variable\ $identifier").expect("parsing failed").into(),
1542 list: PossibleFormat::empty(),
1543 tuple: PossibleFormat::empty(),
1544 slice: PossibleFormat::empty(),
1545 identifier: Format::from_str("$value").expect("parsing failed").into(),
1546 arguments: PossibleFormat::empty(),
1547 argument: PossibleFormat::empty(),
1548 argument_with_default: PossibleFormat::empty(),
1549 comprehension: PossibleFormat::empty(),
1550 keyword: PossibleFormat::empty(),
1551 constant_none: Format::from_str("None").expect("parsing failed").into(),
1552 constant_bool: Format::from_str(r"boolean\ $value").expect("parsing failed").into(),
1553 constant_string: Format::from_str(r#"string\ "$value""#).expect("parsing failed").into(),
1554 constant_bytes: PossibleFormat::empty(),
1555 constant_integer: Format::from_str(r#"integer\ $value"#).expect("parsing failed").into(),
1556 constant_tuples: PossibleFormat::empty(),
1557 constant_float: Format::from_str(r#"float\ $value"#).expect("parsing failed").into(),
1558 constant_complex: PossibleFormat::empty(),
1559 constant_ellipsis: PossibleFormat::empty(),
1560 with_item: PossibleFormat::empty(),
1561 match_case: PossibleFormat::empty(),
1562 except_handler: PossibleFormat::empty(),
1563 alias: PossibleFormat::empty(),
1564 }
1565}
1566
1567#[cfg(test)]
1568mod test {
1569
1570 use super::*;
1571
1572 use pretty_assertions::assert_eq;
1573
1574 #[test]
1575 fn simple_if_true() {
1576 let code = r#"if True:
1577 a = 10"#;
1578
1579 let parsed = Python::parse(code).expect("Parsing to work");
1580
1581 println!("{:?}", parsed.module);
1582
1583 let mut result = String::new();
1584
1585 let formats = example_format();
1586
1587 parsed
1588 .pretty_print(&mut result, &formats)
1589 .expect("pretty printing to work");
1590
1591 assert_eq!(
1592 result,
1593 r#"When
1594 the literal boolean true
1595 is seen as true
1596 do
1597 evaluate the literal integer 10 and assign it to the variable a"#
1598 )
1599 }
1600
1601 #[test]
1602 fn simple_if_false_with_else() {
1603 let code = r#"if False:
1604 a = 10
1605else:
1606 b = "test""#;
1607
1608 let parsed = Python::parse(code).expect("Parsing to work");
1609
1610 println!("{:?}", parsed.module);
1611
1612 let mut result = String::new();
1613
1614 let formats = example_format();
1615
1616 parsed
1617 .pretty_print(&mut result, &formats)
1618 .expect("pretty printing to work");
1619
1620 assert_eq!(
1621 result,
1622 r#"When
1623 the literal boolean false
1624 is seen as true
1625 do
1626 evaluate the literal integer 10 and assign it to the variable a
1627 else, if it is seen as false,
1628 do
1629 evaluate the literal string "test" and assign it to the variable b"#
1630 )
1631 }
1632
1633 #[test]
1634 fn if_one_comparison() {
1635 let code = r#"if 3.5 == 3:
1636 a = 10"#;
1637
1638 let parsed = Python::parse(code).expect("Parsing to work");
1639
1640 println!("{:?}", parsed.module);
1641
1642 let mut result = String::new();
1643
1644 let formats = example_format();
1645
1646 parsed
1647 .pretty_print(&mut result, &formats)
1648 .expect("pretty printing to work");
1649
1650 assert_eq!(
1651 result,
1652 r#"When
1653 the equality comparison of the result of the literal float 3.5 with the result of the literal integer 3
1654 is seen as true
1655 do
1656 evaluate the literal integer 10 and assign it to the variable a"#
1657 )
1658 }
1659
1660 #[test]
1661 fn if_two_comparisons() {
1662 let code = r#"if 3.5 == 3 <= 5:
1663 a = 10"#;
1664
1665 let parsed = Python::parse(code).expect("Parsing to work");
1666
1667 println!("{:?}", parsed.module);
1668
1669 let mut result = String::new();
1670
1671 let formats = example_format();
1672
1673 parsed
1674 .pretty_print(&mut result, &formats)
1675 .expect("pretty printing to work");
1676
1677 assert_eq!(
1678 result,
1679 r#"When
1680 each of the following conditions (when one evaluates to false, we do not evaluate the remaining conditions)
1681 - the equality comparison of the result of the literal float 3.5 with the result of the literal integer 3
1682 - the result of the literal integer 3 is less than or equal to the result of the literal integer 5
1683 is seen as true
1684 do
1685 evaluate the literal integer 10 and assign it to the variable a"#
1686 )
1687 }
1688
1689 #[test]
1690 fn if_eight_ands() {
1691 let code = r#"if 3.5 == "test" and test < "test" and 5 > 9 and "test" <= "test" and "test" >= testing and 8.5 != 17 and test is not None and test is None:
1692 a = 10 + 8"#;
1693
1694 let parsed = Python::parse(code).expect("Parsing to work");
1695
1696 println!("{:?}", parsed.module);
1697
1698 let mut result = String::new();
1699
1700 let formats = example_format();
1701
1702 parsed
1703 .pretty_print(&mut result, &formats)
1704 .expect("pretty printing to work");
1705
1706 assert_eq!(
1707 result,
1708 r#"When
1709 each of the following conditions (when one evaluates to false, we do not evaluate the remaining conditions)
1710 - the equality comparison of the result of the literal float 3.5 with the result of the literal string "test"
1711 - the result of the variable test is less than the result of the literal string "test"
1712 - the result of the literal integer 5 is greater than the result of the literal integer 9
1713 - the result of the literal string "test" is less than or equal to the result of the literal string "test"
1714 - the result of the literal string "test" is greater than or equal to the result of the variable testing
1715 - the result of the literal float 8.5 is different from the result of the literal integer 17
1716 - the result of the variable test does not refer to the same object as the result of the literal None
1717 - the result of the variable test refers to the same object as the result of the literal None
1718 is seen as true
1719 do
1720 evaluate (the literal integer 10 + the literal integer 8) and assign it to the variable a"#
1721 )
1722 }
1723}