1use std::mem::swap;
7
8use crate::{
9 inflate_helpers::adjust_parameters_trailing_whitespace,
10 nodes::{
11 op::*,
12 statement::*,
13 traits::{Inflate, ParenthesizedDeflatedNode, ParenthesizedNode, Result, WithComma},
14 whitespace::ParenthesizableWhitespace,
15 Annotation, AssignEqual, AssignTargetExpression, BinaryOp, BooleanOp, Codegen,
16 CodegenState, Colon, Comma, CompOp, Dot, UnaryOp,
17 },
18 tokenizer::{
19 whitespace_parser::{parse_parenthesizable_whitespace, Config},
20 Token,
21 },
22};
23#[cfg(feature = "py")]
24use libcst_derive::TryIntoPy;
25use libcst_derive::{cst_node, Codegen, Inflate, ParenthesizedDeflatedNode, ParenthesizedNode};
26
27type TokenRef<'r, 'a> = &'r Token<'a>;
28
29#[cst_node(Default)]
30pub struct Parameters<'a> {
31 pub params: Vec<Param<'a>>,
32 pub star_arg: Option<StarArg<'a>>,
33 pub kwonly_params: Vec<Param<'a>>,
34 pub star_kwarg: Option<Param<'a>>,
35 pub posonly_params: Vec<Param<'a>>,
36 pub posonly_ind: Option<ParamSlash<'a>>,
37}
38
39impl<'a> Parameters<'a> {
40 pub fn is_empty(&self) -> bool {
41 self.params.is_empty()
42 && self.star_arg.is_none()
43 && self.kwonly_params.is_empty()
44 && self.star_kwarg.is_none()
45 && self.posonly_params.is_empty()
46 && self.posonly_ind.is_none()
47 }
48}
49
50impl<'r, 'a> DeflatedParameters<'r, 'a> {
51 pub fn is_empty(&self) -> bool {
52 self.params.is_empty()
53 && self.star_arg.is_none()
54 && self.kwonly_params.is_empty()
55 && self.star_kwarg.is_none()
56 && self.posonly_params.is_empty()
57 && self.posonly_ind.is_none()
58 }
59}
60
61impl<'r, 'a> Inflate<'a> for DeflatedParameters<'r, 'a> {
62 type Inflated = Parameters<'a>;
63 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
64 let posonly_params = self.posonly_params.inflate(config)?;
65 let posonly_ind = self.posonly_ind.inflate(config)?;
66 let params = self.params.inflate(config)?;
67 let star_arg = self.star_arg.inflate(config)?;
68 let kwonly_params = self.kwonly_params.inflate(config)?;
69 let star_kwarg = self.star_kwarg.inflate(config)?;
70 Ok(Self::Inflated {
71 params,
72 star_arg,
73 kwonly_params,
74 star_kwarg,
75 posonly_params,
76 posonly_ind,
77 })
78 }
79}
80
81#[cst_node(Inflate)]
82pub enum StarArg<'a> {
83 Star(Box<ParamStar<'a>>),
84 Param(Box<Param<'a>>),
85}
86
87impl<'a> Codegen<'a> for Parameters<'a> {
88 fn codegen(&self, state: &mut CodegenState<'a>) {
89 let params_after_kwonly = self.star_kwarg.is_some();
90 let params_after_regular = !self.kwonly_params.is_empty() || params_after_kwonly;
91 let params_after_posonly = !self.params.is_empty() || params_after_regular;
92 let star_included = self.star_arg.is_some() || !self.kwonly_params.is_empty();
93
94 for p in &self.posonly_params {
95 p.codegen(state, None, true);
96 }
97
98 match &self.posonly_ind {
99 Some(ind) => ind.codegen(state, params_after_posonly),
100 _ => {
101 if !self.posonly_params.is_empty() {
102 if params_after_posonly {
103 state.add_token("/, ");
104 } else {
105 state.add_token("/");
106 }
107 }
108 }
109 }
110
111 let param_size = self.params.len();
112 for (i, p) in self.params.iter().enumerate() {
113 p.codegen(state, None, params_after_regular || i < param_size - 1);
114 }
115
116 let kwonly_size = self.kwonly_params.len();
117 match &self.star_arg {
118 None => {
119 if star_included {
120 state.add_token("*, ")
121 }
122 }
123 Some(StarArg::Param(p)) => p.codegen(
124 state,
125 Some("*"),
126 kwonly_size > 0 || self.star_kwarg.is_some(),
127 ),
128 Some(StarArg::Star(s)) => s.codegen(state),
129 }
130
131 for (i, p) in self.kwonly_params.iter().enumerate() {
132 p.codegen(state, None, params_after_kwonly || i < kwonly_size - 1);
133 }
134
135 if let Some(star) = &self.star_kwarg {
136 star.codegen(state, Some("**"), false)
137 }
138 }
139}
140
141#[cst_node]
142pub struct ParamSlash<'a> {
143 pub comma: Option<Comma<'a>>,
144 pub whitespace_after: ParenthesizableWhitespace<'a>,
145
146 pub(crate) tok: TokenRef<'a>,
147}
148
149impl<'a> ParamSlash<'a> {
150 fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
151 state.add_token("/");
152 self.whitespace_after.codegen(state);
153 match (&self.comma, default_comma) {
154 (Some(comma), _) => comma.codegen(state),
155 (None, true) => state.add_token(", "),
156 _ => {}
157 }
158 }
159}
160
161impl<'r, 'a> Inflate<'a> for DeflatedParamSlash<'r, 'a> {
162 type Inflated = ParamSlash<'a>;
163 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
164 let whitespace_after =
165 parse_parenthesizable_whitespace(config, &mut self.tok.whitespace_after.borrow_mut())?;
166 let comma = self.comma.inflate(config)?;
167 Ok(Self::Inflated {
168 comma,
169 whitespace_after,
170 })
171 }
172}
173
174#[cst_node]
175pub struct ParamStar<'a> {
176 pub comma: Comma<'a>,
177}
178
179impl<'a> Codegen<'a> for ParamStar<'a> {
180 fn codegen(&self, state: &mut CodegenState<'a>) {
181 state.add_token("*");
182 self.comma.codegen(state);
183 }
184}
185
186impl<'r, 'a> Inflate<'a> for DeflatedParamStar<'r, 'a> {
187 type Inflated = ParamStar<'a>;
188 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
189 let comma = self.comma.inflate(config)?;
190 Ok(Self::Inflated { comma })
191 }
192}
193
194#[cst_node(ParenthesizedNode, Default)]
195pub struct Name<'a> {
196 pub value: &'a str,
197 pub lpar: Vec<LeftParen<'a>>,
198 pub rpar: Vec<RightParen<'a>>,
199}
200
201impl<'r, 'a> Inflate<'a> for DeflatedName<'r, 'a> {
202 type Inflated = Name<'a>;
203 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
204 let lpar = self.lpar.inflate(config)?;
205 let rpar = self.rpar.inflate(config)?;
206 Ok(Self::Inflated {
207 value: self.value,
208 lpar,
209 rpar,
210 })
211 }
212}
213
214impl<'a> Codegen<'a> for Name<'a> {
215 fn codegen(&self, state: &mut CodegenState<'a>) {
216 self.parenthesize(state, |state| {
217 state.add_token(self.value);
218 });
219 }
220}
221
222#[cst_node]
223pub struct Param<'a> {
224 pub name: Name<'a>,
225 pub annotation: Option<Annotation<'a>>,
226 pub equal: Option<AssignEqual<'a>>,
227 pub default: Option<Expression<'a>>,
228
229 pub comma: Option<Comma<'a>>,
230
231 pub star: Option<&'a str>,
232
233 pub whitespace_after_star: ParenthesizableWhitespace<'a>,
234 pub whitespace_after_param: ParenthesizableWhitespace<'a>,
235
236 pub(crate) star_tok: Option<TokenRef<'a>>,
237}
238
239impl<'r, 'a> Inflate<'a> for DeflatedParam<'r, 'a> {
240 type Inflated = Param<'a>;
241 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
242 let name = self.name.inflate(config)?;
243 let annotation = self.annotation.inflate(config)?;
244 let equal = self.equal.inflate(config)?;
245 let default = self.default.inflate(config)?;
246 let comma = self.comma.inflate(config)?;
247 let whitespace_after_star = if let Some(star_tok) = self.star_tok.as_mut() {
248 parse_parenthesizable_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?
249 } else {
250 Default::default()
251 };
252 let whitespace_after_param = Default::default(); Ok(Self::Inflated {
254 name,
255 annotation,
256 equal,
257 default,
258 comma,
259 star: self.star,
260 whitespace_after_star,
261 whitespace_after_param,
262 })
263 }
264}
265
266impl<'r, 'a> Default for DeflatedParam<'r, 'a> {
267 fn default() -> Self {
268 Self {
269 name: Default::default(),
270 annotation: None,
271 equal: None,
272 default: None,
273 comma: None,
274 star: Some(""), star_tok: None,
276 }
277 }
278}
279
280impl<'a> Param<'a> {
281 fn codegen(
282 &self,
283 state: &mut CodegenState<'a>,
284 default_star: Option<&'a str>,
285 default_comma: bool,
286 ) {
287 match (self.star, default_star) {
288 (Some(star), _) => state.add_token(star),
289 (None, Some(star)) => state.add_token(star),
290 _ => {}
291 }
292 self.whitespace_after_star.codegen(state);
293 self.name.codegen(state);
294
295 if let Some(ann) = &self.annotation {
296 ann.codegen(state, ":");
297 }
298
299 match (&self.equal, &self.default) {
300 (Some(equal), Some(def)) => {
301 equal.codegen(state);
302 def.codegen(state);
303 }
304 (None, Some(def)) => {
305 state.add_token(" = ");
306 def.codegen(state);
307 }
308 _ => {}
309 }
310
311 match &self.comma {
312 Some(comma) => comma.codegen(state),
313 None if default_comma => state.add_token(", "),
314 _ => {}
315 }
316
317 self.whitespace_after_param.codegen(state);
318 }
319}
320
321#[cst_node]
322pub struct Arg<'a> {
323 pub value: Expression<'a>,
324 pub keyword: Option<Name<'a>>,
325 pub equal: Option<AssignEqual<'a>>,
326 pub comma: Option<Comma<'a>>,
327 pub star: &'a str,
328 pub whitespace_after_star: ParenthesizableWhitespace<'a>,
329 pub whitespace_after_arg: ParenthesizableWhitespace<'a>,
330
331 pub(crate) star_tok: Option<TokenRef<'a>>,
332}
333
334impl<'r, 'a> Inflate<'a> for DeflatedArg<'r, 'a> {
335 type Inflated = Arg<'a>;
336 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
337 let whitespace_after_star = if let Some(star_tok) = self.star_tok.as_mut() {
338 parse_parenthesizable_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?
339 } else {
340 Default::default()
341 };
342 let keyword = self.keyword.inflate(config)?;
343 let equal = self.equal.inflate(config)?;
344 let value = self.value.inflate(config)?;
345 let comma = self.comma.inflate(config)?;
346 let whitespace_after_arg = Default::default();
348 Ok(Self::Inflated {
349 value,
350 keyword,
351 equal,
352 comma,
353 star: self.star,
354 whitespace_after_star,
355 whitespace_after_arg,
356 })
357 }
358}
359
360impl<'a> Arg<'a> {
361 pub fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
362 state.add_token(self.star);
363 self.whitespace_after_star.codegen(state);
364 if let Some(kw) = &self.keyword {
365 kw.codegen(state);
366 }
367 if let Some(eq) = &self.equal {
368 eq.codegen(state);
369 } else if self.keyword.is_some() {
370 state.add_token(" = ");
371 }
372 self.value.codegen(state);
373
374 if let Some(comma) = &self.comma {
375 comma.codegen(state);
376 } else if default_comma {
377 state.add_token(", ");
378 }
379
380 self.whitespace_after_arg.codegen(state);
381 }
382}
383
384impl<'r, 'a> WithComma<'r, 'a> for DeflatedArg<'r, 'a> {
385 fn with_comma(self, c: DeflatedComma<'r, 'a>) -> Self {
386 Self {
387 comma: Some(c),
388 ..self
389 }
390 }
391}
392
393#[cst_node]
394#[derive(Default)]
395pub struct LeftParen<'a> {
396 pub whitespace_after: ParenthesizableWhitespace<'a>,
398
399 pub(crate) lpar_tok: TokenRef<'a>,
400}
401
402impl<'a> Codegen<'a> for LeftParen<'a> {
403 fn codegen(&self, state: &mut CodegenState<'a>) {
404 state.add_token("(");
405 self.whitespace_after.codegen(state);
406 }
407}
408
409impl<'r, 'a> Inflate<'a> for DeflatedLeftParen<'r, 'a> {
410 type Inflated = LeftParen<'a>;
411 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
412 let whitespace_after = parse_parenthesizable_whitespace(
413 config,
414 &mut (*self.lpar_tok).whitespace_after.borrow_mut(),
415 )?;
416 Ok(Self::Inflated { whitespace_after })
417 }
418}
419
420#[cst_node]
421#[derive(Default)]
422pub struct RightParen<'a> {
423 pub whitespace_before: ParenthesizableWhitespace<'a>,
425
426 pub(crate) rpar_tok: TokenRef<'a>,
427}
428
429impl<'a> Codegen<'a> for RightParen<'a> {
430 fn codegen(&self, state: &mut CodegenState<'a>) {
431 self.whitespace_before.codegen(state);
432 state.add_token(")");
433 }
434}
435
436impl<'r, 'a> Inflate<'a> for DeflatedRightParen<'r, 'a> {
437 type Inflated = RightParen<'a>;
438 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
439 let whitespace_before = parse_parenthesizable_whitespace(
440 config,
441 &mut (*self.rpar_tok).whitespace_before.borrow_mut(),
442 )?;
443 Ok(Self::Inflated { whitespace_before })
444 }
445}
446
447#[cst_node(ParenthesizedNode, Codegen, Inflate)]
448pub enum Expression<'a> {
449 Name(Box<Name<'a>>),
450 Ellipsis(Box<Ellipsis<'a>>),
451 Integer(Box<Integer<'a>>),
452 Float(Box<Float<'a>>),
453 Imaginary(Box<Imaginary<'a>>),
454 Comparison(Box<Comparison<'a>>),
455 UnaryOperation(Box<UnaryOperation<'a>>),
456 BinaryOperation(Box<BinaryOperation<'a>>),
457 BooleanOperation(Box<BooleanOperation<'a>>),
458 Attribute(Box<Attribute<'a>>),
459 Tuple(Box<Tuple<'a>>),
460 Call(Box<Call<'a>>),
461 GeneratorExp(Box<GeneratorExp<'a>>),
462 ListComp(Box<ListComp<'a>>),
463 SetComp(Box<SetComp<'a>>),
464 DictComp(Box<DictComp<'a>>),
465 StarredDictComp(Box<StarredDictComp<'a>>),
466 List(Box<List<'a>>),
467 Set(Box<Set<'a>>),
468 Dict(Box<Dict<'a>>),
469 Subscript(Box<Subscript<'a>>),
470 StarredElement(Box<StarredElement<'a>>),
471 IfExp(Box<IfExp<'a>>),
472 Lambda(Box<Lambda<'a>>),
473 Yield(Box<Yield<'a>>),
474 Await(Box<Await<'a>>),
475 SimpleString(Box<SimpleString<'a>>),
476 ConcatenatedString(Box<ConcatenatedString<'a>>),
477 FormattedString(Box<FormattedString<'a>>),
478 TemplatedString(Box<TemplatedString<'a>>),
479 NamedExpr(Box<NamedExpr<'a>>),
480}
481
482#[cst_node(ParenthesizedNode)]
483pub struct Ellipsis<'a> {
484 pub lpar: Vec<LeftParen<'a>>,
485 pub rpar: Vec<RightParen<'a>>,
486}
487
488impl<'a> Codegen<'a> for Ellipsis<'a> {
489 fn codegen(&self, state: &mut CodegenState<'a>) {
490 self.parenthesize(state, |state| {
491 state.add_token("...");
492 })
493 }
494}
495impl<'r, 'a> Inflate<'a> for DeflatedEllipsis<'r, 'a> {
496 type Inflated = Ellipsis<'a>;
497 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
498 let lpar = self.lpar.inflate(config)?;
499 let rpar = self.rpar.inflate(config)?;
500 Ok(Self::Inflated { lpar, rpar })
501 }
502}
503
504#[cst_node(ParenthesizedNode)]
505pub struct Integer<'a> {
506 pub value: &'a str,
509 pub lpar: Vec<LeftParen<'a>>,
510 pub rpar: Vec<RightParen<'a>>,
511}
512
513impl<'a> Codegen<'a> for Integer<'a> {
514 fn codegen(&self, state: &mut CodegenState<'a>) {
515 self.parenthesize(state, |state| {
516 state.add_token(self.value);
517 })
518 }
519}
520
521impl<'r, 'a> Inflate<'a> for DeflatedInteger<'r, 'a> {
522 type Inflated = Integer<'a>;
523 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
524 let lpar = self.lpar.inflate(config)?;
525 let rpar = self.rpar.inflate(config)?;
526 Ok(Self::Inflated {
527 value: self.value,
528 lpar,
529 rpar,
530 })
531 }
532}
533
534#[cst_node(ParenthesizedNode)]
535pub struct Float<'a> {
536 pub value: &'a str,
539 pub lpar: Vec<LeftParen<'a>>,
540 pub rpar: Vec<RightParen<'a>>,
541}
542
543impl<'a> Codegen<'a> for Float<'a> {
544 fn codegen(&self, state: &mut CodegenState<'a>) {
545 self.parenthesize(state, |state| {
546 state.add_token(self.value);
547 })
548 }
549}
550
551impl<'r, 'a> Inflate<'a> for DeflatedFloat<'r, 'a> {
552 type Inflated = Float<'a>;
553 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
554 let lpar = self.lpar.inflate(config)?;
555 let rpar = self.rpar.inflate(config)?;
556 Ok(Self::Inflated {
557 value: self.value,
558 lpar,
559 rpar,
560 })
561 }
562}
563
564#[cst_node(ParenthesizedNode)]
565pub struct Imaginary<'a> {
566 pub value: &'a str,
568 pub lpar: Vec<LeftParen<'a>>,
569 pub rpar: Vec<RightParen<'a>>,
570}
571
572impl<'a> Codegen<'a> for Imaginary<'a> {
573 fn codegen(&self, state: &mut CodegenState<'a>) {
574 self.parenthesize(state, |state| {
575 state.add_token(self.value);
576 })
577 }
578}
579
580impl<'r, 'a> Inflate<'a> for DeflatedImaginary<'r, 'a> {
581 type Inflated = Imaginary<'a>;
582 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
583 let lpar = self.lpar.inflate(config)?;
584 let rpar = self.rpar.inflate(config)?;
585 Ok(Self::Inflated {
586 value: self.value,
587 lpar,
588 rpar,
589 })
590 }
591}
592
593#[cst_node(ParenthesizedNode)]
594pub struct Comparison<'a> {
595 pub left: Box<Expression<'a>>,
596 pub comparisons: Vec<ComparisonTarget<'a>>,
597 pub lpar: Vec<LeftParen<'a>>,
598 pub rpar: Vec<RightParen<'a>>,
599}
600
601impl<'a> Codegen<'a> for Comparison<'a> {
602 fn codegen(&self, state: &mut CodegenState<'a>) {
603 self.parenthesize(state, |state| {
604 self.left.codegen(state);
605 for comp in &self.comparisons {
606 comp.codegen(state);
607 }
608 })
609 }
610}
611impl<'r, 'a> Inflate<'a> for DeflatedComparison<'r, 'a> {
612 type Inflated = Comparison<'a>;
613 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
614 let lpar = self.lpar.inflate(config)?;
615 let left = self.left.inflate(config)?;
616 let comparisons = self.comparisons.inflate(config)?;
617 let rpar = self.rpar.inflate(config)?;
618 Ok(Self::Inflated {
619 left,
620 comparisons,
621 lpar,
622 rpar,
623 })
624 }
625}
626
627#[cst_node(ParenthesizedNode)]
628pub struct UnaryOperation<'a> {
629 pub operator: UnaryOp<'a>,
630 pub expression: Box<Expression<'a>>,
631 pub lpar: Vec<LeftParen<'a>>,
632 pub rpar: Vec<RightParen<'a>>,
633}
634
635impl<'a> Codegen<'a> for UnaryOperation<'a> {
636 fn codegen(&self, state: &mut CodegenState<'a>) {
637 self.parenthesize(state, |state| {
638 self.operator.codegen(state);
639 self.expression.codegen(state);
640 })
641 }
642}
643
644impl<'r, 'a> Inflate<'a> for DeflatedUnaryOperation<'r, 'a> {
645 type Inflated = UnaryOperation<'a>;
646 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
647 let lpar = self.lpar.inflate(config)?;
648 let operator = self.operator.inflate(config)?;
649 let expression = self.expression.inflate(config)?;
650 let rpar = self.rpar.inflate(config)?;
651 Ok(Self::Inflated {
652 operator,
653 expression,
654 lpar,
655 rpar,
656 })
657 }
658}
659
660#[cst_node(ParenthesizedNode)]
661pub struct BinaryOperation<'a> {
662 pub left: Box<Expression<'a>>,
663 pub operator: BinaryOp<'a>,
664 pub right: Box<Expression<'a>>,
665 pub lpar: Vec<LeftParen<'a>>,
666 pub rpar: Vec<RightParen<'a>>,
667}
668
669impl<'a> Codegen<'a> for BinaryOperation<'a> {
670 fn codegen(&self, state: &mut CodegenState<'a>) {
671 self.parenthesize(state, |state| {
672 self.left.codegen(state);
673 self.operator.codegen(state);
674 self.right.codegen(state);
675 })
676 }
677}
678
679impl<'r, 'a> Inflate<'a> for DeflatedBinaryOperation<'r, 'a> {
680 type Inflated = BinaryOperation<'a>;
681 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
682 let lpar = self.lpar.inflate(config)?;
683 let left = self.left.inflate(config)?;
684 let operator = self.operator.inflate(config)?;
685 let right = self.right.inflate(config)?;
686 let rpar = self.rpar.inflate(config)?;
687 Ok(Self::Inflated {
688 left,
689 operator,
690 right,
691 lpar,
692 rpar,
693 })
694 }
695}
696
697#[cst_node(ParenthesizedNode)]
698pub struct BooleanOperation<'a> {
699 pub left: Box<Expression<'a>>,
700 pub operator: BooleanOp<'a>,
701 pub right: Box<Expression<'a>>,
702 pub lpar: Vec<LeftParen<'a>>,
703 pub rpar: Vec<RightParen<'a>>,
704}
705
706impl<'a> Codegen<'a> for BooleanOperation<'a> {
707 fn codegen(&self, state: &mut CodegenState<'a>) {
708 self.parenthesize(state, |state| {
709 self.left.codegen(state);
710 self.operator.codegen(state);
711 self.right.codegen(state);
712 })
713 }
714}
715
716impl<'r, 'a> Inflate<'a> for DeflatedBooleanOperation<'r, 'a> {
717 type Inflated = BooleanOperation<'a>;
718 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
719 let lpar = self.lpar.inflate(config)?;
720 let left = self.left.inflate(config)?;
721 let operator = self.operator.inflate(config)?;
722 let right = self.right.inflate(config)?;
723 let rpar = self.rpar.inflate(config)?;
724 Ok(Self::Inflated {
725 left,
726 operator,
727 right,
728 lpar,
729 rpar,
730 })
731 }
732}
733
734#[cst_node(ParenthesizedNode)]
735pub struct Call<'a> {
736 pub func: Box<Expression<'a>>,
737 pub args: Vec<Arg<'a>>,
738 pub lpar: Vec<LeftParen<'a>>,
739 pub rpar: Vec<RightParen<'a>>,
740 pub whitespace_after_func: ParenthesizableWhitespace<'a>,
741 pub whitespace_before_args: ParenthesizableWhitespace<'a>,
742
743 pub(crate) lpar_tok: TokenRef<'a>,
744 pub(crate) rpar_tok: TokenRef<'a>,
745}
746
747impl<'r, 'a> Inflate<'a> for DeflatedCall<'r, 'a> {
748 type Inflated = Call<'a>;
749 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
750 let lpar = self.lpar.inflate(config)?;
751 let func = self.func.inflate(config)?;
752 let whitespace_after_func = parse_parenthesizable_whitespace(
753 config,
754 &mut (*self.lpar_tok).whitespace_before.borrow_mut(),
755 )?;
756 let whitespace_before_args = parse_parenthesizable_whitespace(
757 config,
758 &mut (*self.lpar_tok).whitespace_after.borrow_mut(),
759 )?;
760 let mut args = self.args.inflate(config)?;
761
762 if let Some(arg) = args.last_mut() {
763 if arg.comma.is_none() {
764 arg.whitespace_after_arg = parse_parenthesizable_whitespace(
765 config,
766 &mut (*self.rpar_tok).whitespace_before.borrow_mut(),
767 )?;
768 }
769 }
770 let rpar = self.rpar.inflate(config)?;
771
772 Ok(Self::Inflated {
773 func,
774 args,
775 lpar,
776 rpar,
777 whitespace_after_func,
778 whitespace_before_args,
779 })
780 }
781}
782
783impl<'a> Codegen<'a> for Call<'a> {
784 fn codegen(&self, state: &mut CodegenState<'a>) {
785 self.parenthesize(state, |state| {
786 self.func.codegen(state);
787 self.whitespace_after_func.codegen(state);
788 state.add_token("(");
789 self.whitespace_before_args.codegen(state);
790 let arg_len = self.args.len();
791 for (i, arg) in self.args.iter().enumerate() {
792 arg.codegen(state, i + 1 < arg_len);
793 }
794 state.add_token(")");
795 })
796 }
797}
798
799#[cst_node(ParenthesizedNode)]
800pub struct Attribute<'a> {
801 pub value: Box<Expression<'a>>,
802 pub attr: Name<'a>,
803 pub dot: Dot<'a>,
804 pub lpar: Vec<LeftParen<'a>>,
805 pub rpar: Vec<RightParen<'a>>,
806}
807
808impl<'r, 'a> Inflate<'a> for DeflatedAttribute<'r, 'a> {
809 type Inflated = Attribute<'a>;
810 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
811 let lpar = self.lpar.inflate(config)?;
812 let value = self.value.inflate(config)?;
813 let dot = self.dot.inflate(config)?;
814 let attr = self.attr.inflate(config)?;
815 let rpar = self.rpar.inflate(config)?;
816 Ok(Self::Inflated {
817 value,
818 attr,
819 dot,
820 lpar,
821 rpar,
822 })
823 }
824}
825
826impl<'a> Codegen<'a> for Attribute<'a> {
827 fn codegen(&self, state: &mut CodegenState<'a>) {
828 self.parenthesize(state, |state| {
829 self.value.codegen(state);
830 self.dot.codegen(state);
831 self.attr.codegen(state);
832 })
833 }
834}
835
836#[cst_node(Codegen, Inflate)]
837pub enum NameOrAttribute<'a> {
838 N(Box<Name<'a>>),
839 A(Box<Attribute<'a>>),
840}
841
842impl<'r, 'a> std::convert::From<DeflatedNameOrAttribute<'r, 'a>> for DeflatedExpression<'r, 'a> {
843 fn from(x: DeflatedNameOrAttribute<'r, 'a>) -> Self {
844 match x {
845 DeflatedNameOrAttribute::N(n) => Self::Name(n),
846 DeflatedNameOrAttribute::A(a) => Self::Attribute(a),
847 }
848 }
849}
850
851#[cst_node]
852pub struct ComparisonTarget<'a> {
853 pub operator: CompOp<'a>,
854 pub comparator: Expression<'a>,
855}
856
857impl<'a> Codegen<'a> for ComparisonTarget<'a> {
858 fn codegen(&self, state: &mut CodegenState<'a>) {
859 self.operator.codegen(state);
860 self.comparator.codegen(state);
861 }
862}
863
864impl<'r, 'a> Inflate<'a> for DeflatedComparisonTarget<'r, 'a> {
865 type Inflated = ComparisonTarget<'a>;
866 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
867 let operator = self.operator.inflate(config)?;
868 let comparator = self.comparator.inflate(config)?;
869 Ok(Self::Inflated {
870 operator,
871 comparator,
872 })
873 }
874}
875
876#[cst_node(ParenthesizedNode)]
877pub struct StarredElement<'a> {
878 pub value: Box<Expression<'a>>,
879 pub comma: Option<Comma<'a>>,
880 pub lpar: Vec<LeftParen<'a>>,
881 pub rpar: Vec<RightParen<'a>>,
882 pub whitespace_before_value: ParenthesizableWhitespace<'a>,
883
884 pub(crate) star_tok: TokenRef<'a>,
885}
886
887impl<'r, 'a> DeflatedStarredElement<'r, 'a> {
888 pub fn inflate_element(self, config: &Config<'a>, is_last: bool) -> Result<StarredElement<'a>> {
889 let lpar = self.lpar.inflate(config)?;
890 let whitespace_before_value = parse_parenthesizable_whitespace(
891 config,
892 &mut (*self.star_tok).whitespace_after.borrow_mut(),
893 )?;
894 let value = self.value.inflate(config)?;
895 let rpar = self.rpar.inflate(config)?;
896 let comma = if is_last {
897 self.comma.map(|c| c.inflate_before(config)).transpose()
898 } else {
899 self.comma.inflate(config)
900 }?;
901 Ok(StarredElement {
902 value,
903 comma,
904 lpar,
905 rpar,
906 whitespace_before_value,
907 })
908 }
909}
910
911impl<'r, 'a> Inflate<'a> for DeflatedStarredElement<'r, 'a> {
912 type Inflated = StarredElement<'a>;
913 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
914 self.inflate_element(config, false)
915 }
916}
917
918impl<'a> Codegen<'a> for StarredElement<'a> {
919 fn codegen(&self, state: &mut CodegenState<'a>) {
920 self.parenthesize(state, |state| {
921 state.add_token("*");
922 self.whitespace_before_value.codegen(state);
923 self.value.codegen(state);
924 });
925 if let Some(comma) = &self.comma {
926 comma.codegen(state);
927 }
928 }
929}
930
931#[allow(clippy::large_enum_variant)]
932#[cst_node(NoIntoPy)]
933pub enum Element<'a> {
934 Simple {
935 value: Expression<'a>,
936 comma: Option<Comma<'a>>,
937 },
938 Starred(Box<StarredElement<'a>>),
939}
940
941impl<'a> Element<'a> {
942 pub fn codegen(
943 &self,
944 state: &mut CodegenState<'a>,
945 default_comma: bool,
946 default_comma_whitespace: bool,
947 ) {
948 match self {
949 Self::Simple { value, comma } => {
950 value.codegen(state);
951 if let Some(comma) = comma {
952 comma.codegen(state)
953 }
954 }
955 Self::Starred(s) => s.codegen(state),
956 }
957 let maybe_comma = match self {
958 Self::Simple { comma, .. } => comma,
959 Self::Starred(s) => &s.comma,
960 };
961 if maybe_comma.is_none() && default_comma {
962 state.add_token(if default_comma_whitespace { ", " } else { "," });
963 }
964 }
965}
966impl<'r, 'a> DeflatedElement<'r, 'a> {
967 pub fn inflate_element(self, config: &Config<'a>, is_last: bool) -> Result<Element<'a>> {
968 Ok(match self {
969 Self::Starred(s) => Element::Starred(Box::new(s.inflate_element(config, is_last)?)),
970 Self::Simple { value, comma } => Element::Simple {
971 value: value.inflate(config)?,
972 comma: if is_last {
973 comma.map(|c| c.inflate_before(config)).transpose()?
974 } else {
975 comma.inflate(config)?
976 },
977 },
978 })
979 }
980}
981
982impl<'r, 'a> WithComma<'r, 'a> for DeflatedElement<'r, 'a> {
983 fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
984 let comma = Some(comma);
985 match self {
986 Self::Simple { value, .. } => Self::Simple { comma, value },
987 Self::Starred(mut s) => {
988 s.comma = comma;
989 Self::Starred(s)
990 }
991 }
992 }
993}
994impl<'r, 'a> std::convert::From<DeflatedExpression<'r, 'a>> for DeflatedElement<'r, 'a> {
995 fn from(e: DeflatedExpression<'r, 'a>) -> Self {
996 match e {
997 DeflatedExpression::StarredElement(e) => Self::Starred(e),
998 value => Self::Simple { value, comma: None },
999 }
1000 }
1001}
1002
1003#[cst_node(ParenthesizedNode, Default)]
1004pub struct Tuple<'a> {
1005 pub elements: Vec<Element<'a>>,
1006 pub lpar: Vec<LeftParen<'a>>,
1007 pub rpar: Vec<RightParen<'a>>,
1008}
1009
1010impl<'r, 'a> Inflate<'a> for DeflatedTuple<'r, 'a> {
1011 type Inflated = Tuple<'a>;
1012 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1013 let lpar = self.lpar.inflate(config)?;
1014 let len = self.elements.len();
1015 let elements = self
1016 .elements
1017 .into_iter()
1018 .enumerate()
1019 .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1020 .collect::<Result<Vec<_>>>()?;
1021 let rpar = self.rpar.inflate(config)?;
1022 Ok(Self::Inflated {
1023 elements,
1024 lpar,
1025 rpar,
1026 })
1027 }
1028}
1029
1030impl<'a> Codegen<'a> for Tuple<'a> {
1031 fn codegen(&self, state: &mut CodegenState<'a>) {
1032 self.parenthesize(state, |state| {
1033 let len = self.elements.len();
1034 if len == 1 {
1035 self.elements.first().unwrap().codegen(state, true, false);
1036 } else {
1037 for (idx, el) in self.elements.iter().enumerate() {
1038 el.codegen(state, idx < len - 1, true);
1039 }
1040 }
1041 });
1042 }
1043}
1044
1045#[cst_node(ParenthesizedNode)]
1046pub struct GeneratorExp<'a> {
1047 pub elt: Box<Expression<'a>>,
1048 pub for_in: Box<CompFor<'a>>,
1049 pub lpar: Vec<LeftParen<'a>>,
1050 pub rpar: Vec<RightParen<'a>>,
1051}
1052
1053impl<'a> Codegen<'a> for GeneratorExp<'a> {
1054 fn codegen(&self, state: &mut CodegenState<'a>) {
1055 self.parenthesize(state, |state| {
1056 self.elt.codegen(state);
1057 self.for_in.codegen(state);
1058 })
1059 }
1060}
1061
1062impl<'r, 'a> Inflate<'a> for DeflatedGeneratorExp<'r, 'a> {
1063 type Inflated = GeneratorExp<'a>;
1064 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1065 let lpar = self.lpar.inflate(config)?;
1066 let elt = self.elt.inflate(config)?;
1067 let for_in = self.for_in.inflate(config)?;
1068 let rpar = self.rpar.inflate(config)?;
1069 Ok(Self::Inflated {
1070 elt,
1071 for_in,
1072 lpar,
1073 rpar,
1074 })
1075 }
1076}
1077
1078#[cst_node(ParenthesizedNode)]
1079pub struct ListComp<'a> {
1080 pub elt: Box<Expression<'a>>,
1081 pub for_in: Box<CompFor<'a>>,
1082 pub lbracket: LeftSquareBracket<'a>,
1083 pub rbracket: RightSquareBracket<'a>,
1084 pub lpar: Vec<LeftParen<'a>>,
1085 pub rpar: Vec<RightParen<'a>>,
1086}
1087
1088impl<'a> Codegen<'a> for ListComp<'a> {
1089 fn codegen(&self, state: &mut CodegenState<'a>) {
1090 self.parenthesize(state, |state| {
1091 self.lbracket.codegen(state);
1092 self.elt.codegen(state);
1093 self.for_in.codegen(state);
1094 self.rbracket.codegen(state);
1095 })
1096 }
1097}
1098
1099impl<'r, 'a> Inflate<'a> for DeflatedListComp<'r, 'a> {
1100 type Inflated = ListComp<'a>;
1101 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1102 let lpar = self.lpar.inflate(config)?;
1103 let lbracket = self.lbracket.inflate(config)?;
1104 let elt = self.elt.inflate(config)?;
1105 let for_in = self.for_in.inflate(config)?;
1106 let rbracket = self.rbracket.inflate(config)?;
1107 let rpar = self.rpar.inflate(config)?;
1108 Ok(Self::Inflated {
1109 elt,
1110 for_in,
1111 lbracket,
1112 rbracket,
1113 lpar,
1114 rpar,
1115 })
1116 }
1117}
1118
1119#[cst_node]
1120#[derive(Default)]
1121pub struct LeftSquareBracket<'a> {
1122 pub whitespace_after: ParenthesizableWhitespace<'a>,
1123 pub(crate) tok: TokenRef<'a>,
1124}
1125
1126impl<'a> Codegen<'a> for LeftSquareBracket<'a> {
1127 fn codegen(&self, state: &mut CodegenState<'a>) {
1128 state.add_token("[");
1129 self.whitespace_after.codegen(state);
1130 }
1131}
1132
1133impl<'r, 'a> Inflate<'a> for DeflatedLeftSquareBracket<'r, 'a> {
1134 type Inflated = LeftSquareBracket<'a>;
1135 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1136 let whitespace_after = parse_parenthesizable_whitespace(
1137 config,
1138 &mut (*self.tok).whitespace_after.borrow_mut(),
1139 )?;
1140 Ok(Self::Inflated { whitespace_after })
1141 }
1142}
1143
1144#[cst_node]
1145#[derive(Default)]
1146pub struct RightSquareBracket<'a> {
1147 pub whitespace_before: ParenthesizableWhitespace<'a>,
1148 pub(crate) tok: TokenRef<'a>,
1149}
1150
1151impl<'a> Codegen<'a> for RightSquareBracket<'a> {
1152 fn codegen(&self, state: &mut CodegenState<'a>) {
1153 self.whitespace_before.codegen(state);
1154 state.add_token("]");
1155 }
1156}
1157
1158impl<'r, 'a> Inflate<'a> for DeflatedRightSquareBracket<'r, 'a> {
1159 type Inflated = RightSquareBracket<'a>;
1160 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1161 let whitespace_before = parse_parenthesizable_whitespace(
1162 config,
1163 &mut (*self.tok).whitespace_before.borrow_mut(),
1164 )?;
1165 Ok(Self::Inflated { whitespace_before })
1166 }
1167}
1168
1169#[cst_node(ParenthesizedNode)]
1170pub struct SetComp<'a> {
1171 pub elt: Box<Expression<'a>>,
1172 pub for_in: Box<CompFor<'a>>,
1173 pub lbrace: LeftCurlyBrace<'a>,
1174 pub rbrace: RightCurlyBrace<'a>,
1175 pub lpar: Vec<LeftParen<'a>>,
1176 pub rpar: Vec<RightParen<'a>>,
1177}
1178
1179impl<'r, 'a> Inflate<'a> for DeflatedSetComp<'r, 'a> {
1180 type Inflated = SetComp<'a>;
1181 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1182 let lpar = self.lpar.inflate(config)?;
1183 let lbrace = self.lbrace.inflate(config)?;
1184 let elt = self.elt.inflate(config)?;
1185 let for_in = self.for_in.inflate(config)?;
1186 let rbrace = self.rbrace.inflate(config)?;
1187 let rpar = self.rpar.inflate(config)?;
1188 Ok(Self::Inflated {
1189 elt,
1190 for_in,
1191 lbrace,
1192 rbrace,
1193 lpar,
1194 rpar,
1195 })
1196 }
1197}
1198
1199impl<'a> Codegen<'a> for SetComp<'a> {
1200 fn codegen(&self, state: &mut CodegenState<'a>) {
1201 self.parenthesize(state, |state| {
1202 self.lbrace.codegen(state);
1203 self.elt.codegen(state);
1204 self.for_in.codegen(state);
1205 self.rbrace.codegen(state);
1206 })
1207 }
1208}
1209
1210#[cst_node(ParenthesizedNode)]
1211pub struct DictComp<'a> {
1212 pub key: Box<Expression<'a>>,
1213 pub value: Box<Expression<'a>>,
1214 pub for_in: Box<CompFor<'a>>,
1215 pub lbrace: LeftCurlyBrace<'a>,
1216 pub rbrace: RightCurlyBrace<'a>,
1217 pub lpar: Vec<LeftParen<'a>>,
1218 pub rpar: Vec<RightParen<'a>>,
1219 pub whitespace_before_colon: ParenthesizableWhitespace<'a>,
1220 pub whitespace_after_colon: ParenthesizableWhitespace<'a>,
1221
1222 pub(crate) colon_tok: TokenRef<'a>,
1223}
1224
1225impl<'r, 'a> Inflate<'a> for DeflatedDictComp<'r, 'a> {
1226 type Inflated = DictComp<'a>;
1227 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1228 let lpar = self.lpar.inflate(config)?;
1229 let lbrace = self.lbrace.inflate(config)?;
1230 let key = self.key.inflate(config)?;
1231 let whitespace_before_colon = parse_parenthesizable_whitespace(
1232 config,
1233 &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1234 )?;
1235 let whitespace_after_colon = parse_parenthesizable_whitespace(
1236 config,
1237 &mut (*self.colon_tok).whitespace_after.borrow_mut(),
1238 )?;
1239 let value = self.value.inflate(config)?;
1240 let for_in = self.for_in.inflate(config)?;
1241 let rbrace = self.rbrace.inflate(config)?;
1242 let rpar = self.rpar.inflate(config)?;
1243 Ok(Self::Inflated {
1244 key,
1245 value,
1246 for_in,
1247 lbrace,
1248 rbrace,
1249 lpar,
1250 rpar,
1251 whitespace_before_colon,
1252 whitespace_after_colon,
1253 })
1254 }
1255}
1256
1257impl<'a> Codegen<'a> for DictComp<'a> {
1258 fn codegen(&self, state: &mut CodegenState<'a>) {
1259 self.parenthesize(state, |state| {
1260 self.lbrace.codegen(state);
1261 self.key.codegen(state);
1262 self.whitespace_before_colon.codegen(state);
1263 state.add_token(":");
1264 self.whitespace_after_colon.codegen(state);
1265 self.value.codegen(state);
1266 self.for_in.codegen(state);
1267 self.rbrace.codegen(state);
1268 })
1269 }
1270}
1271
1272#[cst_node(ParenthesizedNode)]
1273pub struct StarredDictComp<'a> {
1274 pub value: Box<Expression<'a>>,
1275 pub for_in: Box<CompFor<'a>>,
1276 pub lbrace: LeftCurlyBrace<'a>,
1277 pub rbrace: RightCurlyBrace<'a>,
1278 pub lpar: Vec<LeftParen<'a>>,
1279 pub rpar: Vec<RightParen<'a>>,
1280 pub whitespace_before_value: ParenthesizableWhitespace<'a>,
1281
1282 pub(crate) doublestar_tok: TokenRef<'a>,
1283}
1284
1285impl<'r, 'a> Inflate<'a> for DeflatedStarredDictComp<'r, 'a> {
1286 type Inflated = StarredDictComp<'a>;
1287 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1288 let lpar = self.lpar.inflate(config)?;
1289 let lbrace = self.lbrace.inflate(config)?;
1290 let whitespace_before_value = parse_parenthesizable_whitespace(
1291 config,
1292 &mut (*self.doublestar_tok).whitespace_after.borrow_mut(),
1293 )?;
1294 let value = self.value.inflate(config)?;
1295 let for_in = self.for_in.inflate(config)?;
1296 let rbrace = self.rbrace.inflate(config)?;
1297 let rpar = self.rpar.inflate(config)?;
1298 Ok(Self::Inflated {
1299 value,
1300 for_in,
1301 lbrace,
1302 rbrace,
1303 lpar,
1304 rpar,
1305 whitespace_before_value,
1306 })
1307 }
1308}
1309
1310impl<'a> Codegen<'a> for StarredDictComp<'a> {
1311 fn codegen(&self, state: &mut CodegenState<'a>) {
1312 self.parenthesize(state, |state| {
1313 self.lbrace.codegen(state);
1314 state.add_token("**");
1315 self.whitespace_before_value.codegen(state);
1316 self.value.codegen(state);
1317 self.for_in.codegen(state);
1318 self.rbrace.codegen(state);
1319 })
1320 }
1321}
1322
1323#[cst_node]
1324pub struct LeftCurlyBrace<'a> {
1325 pub whitespace_after: ParenthesizableWhitespace<'a>,
1326 pub(crate) tok: TokenRef<'a>,
1327}
1328
1329impl<'a> Default for LeftCurlyBrace<'a> {
1330 fn default() -> Self {
1331 Self {
1332 whitespace_after: Default::default(),
1333 }
1334 }
1335}
1336
1337impl<'r, 'a> Inflate<'a> for DeflatedLeftCurlyBrace<'r, 'a> {
1338 type Inflated = LeftCurlyBrace<'a>;
1339 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1340 let whitespace_after = parse_parenthesizable_whitespace(
1341 config,
1342 &mut (*self.tok).whitespace_after.borrow_mut(),
1343 )?;
1344 Ok(Self::Inflated { whitespace_after })
1345 }
1346}
1347
1348impl<'a> Codegen<'a> for LeftCurlyBrace<'a> {
1349 fn codegen(&self, state: &mut CodegenState<'a>) {
1350 state.add_token("{");
1351 self.whitespace_after.codegen(state);
1352 }
1353}
1354
1355#[cst_node]
1356pub struct RightCurlyBrace<'a> {
1357 pub whitespace_before: ParenthesizableWhitespace<'a>,
1358 pub(crate) tok: TokenRef<'a>,
1359}
1360
1361impl<'a> Default for RightCurlyBrace<'a> {
1362 fn default() -> Self {
1363 Self {
1364 whitespace_before: Default::default(),
1365 }
1366 }
1367}
1368
1369impl<'r, 'a> Inflate<'a> for DeflatedRightCurlyBrace<'r, 'a> {
1370 type Inflated = RightCurlyBrace<'a>;
1371 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1372 let whitespace_before = parse_parenthesizable_whitespace(
1373 config,
1374 &mut (*self.tok).whitespace_before.borrow_mut(),
1375 )?;
1376 Ok(Self::Inflated { whitespace_before })
1377 }
1378}
1379
1380impl<'a> Codegen<'a> for RightCurlyBrace<'a> {
1381 fn codegen(&self, state: &mut CodegenState<'a>) {
1382 self.whitespace_before.codegen(state);
1383 state.add_token("}");
1384 }
1385}
1386
1387#[cst_node]
1388pub struct CompFor<'a> {
1389 pub target: AssignTargetExpression<'a>,
1390 pub iter: Expression<'a>,
1391 pub ifs: Vec<CompIf<'a>>,
1392 pub inner_for_in: Option<Box<CompFor<'a>>>,
1393 pub asynchronous: Option<Asynchronous<'a>>,
1394 pub whitespace_before: ParenthesizableWhitespace<'a>,
1395 pub whitespace_after_for: ParenthesizableWhitespace<'a>,
1396 pub whitespace_before_in: ParenthesizableWhitespace<'a>,
1397 pub whitespace_after_in: ParenthesizableWhitespace<'a>,
1398
1399 pub(crate) async_tok: Option<TokenRef<'a>>,
1400 pub(crate) for_tok: TokenRef<'a>,
1401 pub(crate) in_tok: TokenRef<'a>,
1402}
1403
1404impl<'a> Codegen<'a> for CompFor<'a> {
1405 fn codegen(&self, state: &mut CodegenState<'a>) {
1406 self.whitespace_before.codegen(state);
1407 if let Some(asynchronous) = &self.asynchronous {
1408 asynchronous.codegen(state);
1409 }
1410 state.add_token("for");
1411 self.whitespace_after_for.codegen(state);
1412 self.target.codegen(state);
1413 self.whitespace_before_in.codegen(state);
1414 state.add_token("in");
1415 self.whitespace_after_in.codegen(state);
1416 self.iter.codegen(state);
1417 for if_ in &self.ifs {
1418 if_.codegen(state);
1419 }
1420 if let Some(inner) = &self.inner_for_in {
1421 inner.codegen(state);
1422 }
1423 }
1424}
1425
1426impl<'r, 'a> Inflate<'a> for DeflatedCompFor<'r, 'a> {
1427 type Inflated = CompFor<'a>;
1428 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1429 let mut whitespace_before = parse_parenthesizable_whitespace(
1430 config,
1431 &mut (*self.for_tok).whitespace_before.borrow_mut(),
1432 )?;
1433 let asynchronous = if let Some(asy_tok) = self.async_tok.as_mut() {
1434 let mut asy_whitespace_after = parse_parenthesizable_whitespace(
1438 config,
1439 &mut asy_tok.whitespace_before.borrow_mut(),
1440 )?;
1441 swap(&mut asy_whitespace_after, &mut whitespace_before);
1442 Some(Asynchronous {
1443 whitespace_after: asy_whitespace_after,
1444 })
1445 } else {
1446 None
1447 };
1448 let whitespace_after_for = parse_parenthesizable_whitespace(
1449 config,
1450 &mut (*self.for_tok).whitespace_after.borrow_mut(),
1451 )?;
1452 let target = self.target.inflate(config)?;
1453 let whitespace_before_in = parse_parenthesizable_whitespace(
1454 config,
1455 &mut (*self.in_tok).whitespace_before.borrow_mut(),
1456 )?;
1457 let whitespace_after_in = parse_parenthesizable_whitespace(
1458 config,
1459 &mut (*self.in_tok).whitespace_after.borrow_mut(),
1460 )?;
1461 let iter = self.iter.inflate(config)?;
1462 let ifs = self.ifs.inflate(config)?;
1463 let inner_for_in = self.inner_for_in.inflate(config)?;
1464 Ok(Self::Inflated {
1465 target,
1466 iter,
1467 ifs,
1468 inner_for_in,
1469 asynchronous,
1470 whitespace_before,
1471 whitespace_after_for,
1472 whitespace_before_in,
1473 whitespace_after_in,
1474 })
1475 }
1476}
1477
1478#[cst_node]
1479pub struct Asynchronous<'a> {
1480 pub whitespace_after: ParenthesizableWhitespace<'a>,
1481}
1482
1483impl<'a> Codegen<'a> for Asynchronous<'a> {
1484 fn codegen(&self, state: &mut CodegenState<'a>) {
1485 state.add_token("async");
1486 self.whitespace_after.codegen(state);
1487 }
1488}
1489
1490pub(crate) fn make_async<'r, 'a>() -> DeflatedAsynchronous<'r, 'a> {
1491 DeflatedAsynchronous {
1492 _phantom: Default::default(),
1493 }
1494}
1495
1496#[cst_node]
1497pub struct CompIf<'a> {
1498 pub test: Expression<'a>,
1499 pub whitespace_before: ParenthesizableWhitespace<'a>,
1500 pub whitespace_before_test: ParenthesizableWhitespace<'a>,
1501
1502 pub(crate) if_tok: TokenRef<'a>,
1503}
1504
1505impl<'a> Codegen<'a> for CompIf<'a> {
1506 fn codegen(&self, state: &mut CodegenState<'a>) {
1507 self.whitespace_before.codegen(state);
1508 state.add_token("if");
1509 self.whitespace_before_test.codegen(state);
1510 self.test.codegen(state);
1511 }
1512}
1513
1514impl<'r, 'a> Inflate<'a> for DeflatedCompIf<'r, 'a> {
1515 type Inflated = CompIf<'a>;
1516 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1517 let whitespace_before = parse_parenthesizable_whitespace(
1518 config,
1519 &mut (*self.if_tok).whitespace_before.borrow_mut(),
1520 )?;
1521 let whitespace_before_test = parse_parenthesizable_whitespace(
1522 config,
1523 &mut (*self.if_tok).whitespace_after.borrow_mut(),
1524 )?;
1525 let test = self.test.inflate(config)?;
1526 Ok(Self::Inflated {
1527 test,
1528 whitespace_before,
1529 whitespace_before_test,
1530 })
1531 }
1532}
1533
1534#[cst_node(ParenthesizedNode)]
1535pub struct List<'a> {
1536 pub elements: Vec<Element<'a>>,
1537 pub lbracket: LeftSquareBracket<'a>,
1538 pub rbracket: RightSquareBracket<'a>,
1539 pub lpar: Vec<LeftParen<'a>>,
1540 pub rpar: Vec<RightParen<'a>>,
1541}
1542
1543impl<'r, 'a> Inflate<'a> for DeflatedList<'r, 'a> {
1544 type Inflated = List<'a>;
1545 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1546 let lpar = self.lpar.inflate(config)?;
1547 let lbracket = self.lbracket.inflate(config)?;
1548 let len = self.elements.len();
1549 let elements = self
1550 .elements
1551 .into_iter()
1552 .enumerate()
1553 .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1554 .collect::<Result<Vec<_>>>()?;
1555 let rbracket = if !elements.is_empty() {
1556 self.rbracket.inflate(config)?
1558 } else {
1559 Default::default()
1560 };
1561 let rpar = self.rpar.inflate(config)?;
1562 Ok(Self::Inflated {
1563 elements,
1564 lbracket,
1565 rbracket,
1566 lpar,
1567 rpar,
1568 })
1569 }
1570}
1571
1572impl<'a> Codegen<'a> for List<'a> {
1573 fn codegen(&self, state: &mut CodegenState<'a>) {
1574 self.parenthesize(state, |state| {
1575 self.lbracket.codegen(state);
1576 let len = self.elements.len();
1577 for (idx, el) in self.elements.iter().enumerate() {
1578 el.codegen(state, idx < len - 1, true);
1579 }
1580 self.rbracket.codegen(state);
1581 })
1582 }
1583}
1584
1585#[cst_node(ParenthesizedNode)]
1586pub struct Set<'a> {
1587 pub elements: Vec<Element<'a>>,
1588 pub lbrace: LeftCurlyBrace<'a>,
1589 pub rbrace: RightCurlyBrace<'a>,
1590 pub lpar: Vec<LeftParen<'a>>,
1591 pub rpar: Vec<RightParen<'a>>,
1592}
1593
1594impl<'r, 'a> Inflate<'a> for DeflatedSet<'r, 'a> {
1595 type Inflated = Set<'a>;
1596 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1597 let lpar = self.lpar.inflate(config)?;
1598 let lbrace = self.lbrace.inflate(config)?;
1599 let len = self.elements.len();
1600 let elements = self
1601 .elements
1602 .into_iter()
1603 .enumerate()
1604 .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1605 .collect::<Result<Vec<_>>>()?;
1606 let rbrace = if !elements.is_empty() {
1607 self.rbrace.inflate(config)?
1608 } else {
1609 Default::default()
1610 };
1611 let rpar = self.rpar.inflate(config)?;
1612 Ok(Self::Inflated {
1613 elements,
1614 lbrace,
1615 rbrace,
1616 lpar,
1617 rpar,
1618 })
1619 }
1620}
1621
1622impl<'a> Codegen<'a> for Set<'a> {
1623 fn codegen(&self, state: &mut CodegenState<'a>) {
1624 self.parenthesize(state, |state| {
1625 self.lbrace.codegen(state);
1626 let len = self.elements.len();
1627 for (idx, el) in self.elements.iter().enumerate() {
1628 el.codegen(state, idx < len - 1, true);
1629 }
1630 self.rbrace.codegen(state);
1631 })
1632 }
1633}
1634
1635#[cst_node(ParenthesizedNode)]
1636pub struct Dict<'a> {
1637 pub elements: Vec<DictElement<'a>>,
1638 pub lbrace: LeftCurlyBrace<'a>,
1639 pub rbrace: RightCurlyBrace<'a>,
1640 pub lpar: Vec<LeftParen<'a>>,
1641 pub rpar: Vec<RightParen<'a>>,
1642}
1643
1644impl<'r, 'a> Inflate<'a> for DeflatedDict<'r, 'a> {
1645 type Inflated = Dict<'a>;
1646 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1647 let lpar = self.lpar.inflate(config)?;
1648 let lbrace = self.lbrace.inflate(config)?;
1649 let len = self.elements.len();
1650 let elements = self
1651 .elements
1652 .into_iter()
1653 .enumerate()
1654 .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1655 .collect::<Result<Vec<_>>>()?;
1656 let rbrace = if !elements.is_empty() {
1657 self.rbrace.inflate(config)?
1658 } else {
1659 Default::default()
1660 };
1661 let rpar = self.rpar.inflate(config)?;
1662 Ok(Self::Inflated {
1663 elements,
1664 lbrace,
1665 rbrace,
1666 lpar,
1667 rpar,
1668 })
1669 }
1670}
1671
1672impl<'a> Codegen<'a> for Dict<'a> {
1673 fn codegen(&self, state: &mut CodegenState<'a>) {
1674 self.parenthesize(state, |state| {
1675 self.lbrace.codegen(state);
1676 let len = self.elements.len();
1677 for (idx, el) in self.elements.iter().enumerate() {
1678 el.codegen(state, idx < len - 1, true);
1679 }
1680 self.rbrace.codegen(state);
1681 })
1682 }
1683}
1684
1685#[cst_node(NoIntoPy)]
1686pub enum DictElement<'a> {
1687 Simple {
1688 key: Expression<'a>,
1689 value: Expression<'a>,
1690 comma: Option<Comma<'a>>,
1691 whitespace_before_colon: ParenthesizableWhitespace<'a>,
1692 whitespace_after_colon: ParenthesizableWhitespace<'a>,
1693 colon_tok: TokenRef<'a>,
1694 },
1695 Starred(StarredDictElement<'a>),
1696}
1697
1698impl<'r, 'a> DeflatedDictElement<'r, 'a> {
1699 pub fn inflate_element(
1700 self,
1701 config: &Config<'a>,
1702 last_element: bool,
1703 ) -> Result<DictElement<'a>> {
1704 Ok(match self {
1705 Self::Starred(s) => DictElement::Starred(s.inflate_element(config, last_element)?),
1706 Self::Simple {
1707 key,
1708 value,
1709 comma,
1710 colon_tok,
1711 ..
1712 } => {
1713 let whitespace_before_colon = parse_parenthesizable_whitespace(
1714 config,
1715 &mut colon_tok.whitespace_before.borrow_mut(),
1716 )?;
1717 let whitespace_after_colon = parse_parenthesizable_whitespace(
1718 config,
1719 &mut colon_tok.whitespace_after.borrow_mut(),
1720 )?;
1721 DictElement::Simple {
1722 key: key.inflate(config)?,
1723 whitespace_before_colon,
1724 whitespace_after_colon,
1725 value: value.inflate(config)?,
1726 comma: if last_element {
1727 comma.map(|c| c.inflate_before(config)).transpose()
1728 } else {
1729 comma.inflate(config)
1730 }?,
1731 }
1732 }
1733 })
1734 }
1735}
1736
1737impl<'a> DictElement<'a> {
1738 fn codegen(
1739 &self,
1740 state: &mut CodegenState<'a>,
1741 default_comma: bool,
1742 default_comma_whitespace: bool,
1743 ) {
1744 match self {
1745 Self::Simple {
1746 key,
1747 value,
1748 comma,
1749 whitespace_before_colon,
1750 whitespace_after_colon,
1751 ..
1752 } => {
1753 key.codegen(state);
1754 whitespace_before_colon.codegen(state);
1755 state.add_token(":");
1756 whitespace_after_colon.codegen(state);
1757 value.codegen(state);
1758 if let Some(comma) = comma {
1759 comma.codegen(state)
1760 }
1761 }
1762 Self::Starred(s) => s.codegen(state),
1763 }
1764 let maybe_comma = match self {
1765 Self::Simple { comma, .. } => comma,
1766 Self::Starred(s) => &s.comma,
1767 };
1768 if maybe_comma.is_none() && default_comma {
1769 state.add_token(if default_comma_whitespace { ", " } else { "," });
1770 }
1771 }
1772}
1773
1774impl<'r, 'a> WithComma<'r, 'a> for DeflatedDictElement<'r, 'a> {
1775 fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
1776 let comma = Some(comma);
1777 match self {
1778 Self::Starred(s) => Self::Starred(DeflatedStarredDictElement { comma, ..s }),
1779 Self::Simple {
1780 key,
1781 value,
1782 colon_tok,
1783 ..
1784 } => Self::Simple {
1785 comma,
1786 key,
1787 value,
1788 colon_tok,
1789 },
1790 }
1791 }
1792}
1793
1794#[cst_node]
1795pub struct StarredDictElement<'a> {
1796 pub value: Expression<'a>,
1797 pub comma: Option<Comma<'a>>,
1798 pub whitespace_before_value: ParenthesizableWhitespace<'a>,
1799
1800 pub(crate) star_tok: TokenRef<'a>,
1801}
1802
1803impl<'r, 'a> DeflatedStarredDictElement<'r, 'a> {
1804 fn inflate_element(
1805 self,
1806 config: &Config<'a>,
1807 last_element: bool,
1808 ) -> Result<StarredDictElement<'a>> {
1809 let whitespace_before_value = parse_parenthesizable_whitespace(
1810 config,
1811 &mut (*self.star_tok).whitespace_after.borrow_mut(),
1812 )?;
1813 let value = self.value.inflate(config)?;
1814 let comma = if last_element {
1815 self.comma.map(|c| c.inflate_before(config)).transpose()
1816 } else {
1817 self.comma.inflate(config)
1818 }?;
1819 Ok(StarredDictElement {
1820 value,
1821 comma,
1822 whitespace_before_value,
1823 })
1824 }
1825}
1826
1827impl<'a> Codegen<'a> for StarredDictElement<'a> {
1828 fn codegen(&self, state: &mut CodegenState<'a>) {
1829 state.add_token("**");
1830 self.whitespace_before_value.codegen(state);
1831 self.value.codegen(state);
1832 if let Some(comma) = &self.comma {
1833 comma.codegen(state);
1834 }
1835 }
1836}
1837
1838#[cst_node(Codegen, Inflate)]
1839pub enum BaseSlice<'a> {
1840 Index(Box<Index<'a>>),
1841 Slice(Box<Slice<'a>>),
1842}
1843
1844#[cst_node]
1845pub struct Index<'a> {
1846 pub value: Expression<'a>,
1847 pub star: Option<&'a str>,
1848 pub whitespace_after_star: Option<ParenthesizableWhitespace<'a>>,
1849
1850 pub(crate) star_tok: Option<TokenRef<'a>>,
1851}
1852
1853impl<'r, 'a> Inflate<'a> for DeflatedIndex<'r, 'a> {
1854 type Inflated = Index<'a>;
1855 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1856 let (star, whitespace_after_star) = if let Some(star_tok) = self.star_tok.as_mut() {
1857 (
1858 Some(star_tok.string),
1859 Some(parse_parenthesizable_whitespace(
1860 config,
1861 &mut star_tok.whitespace_after.borrow_mut(),
1862 )?),
1863 )
1864 } else {
1865 (None, None)
1866 };
1867 let value = self.value.inflate(config)?;
1868 Ok(Self::Inflated {
1869 value,
1870 star,
1871 whitespace_after_star,
1872 })
1873 }
1874}
1875
1876impl<'a> Codegen<'a> for Index<'a> {
1877 fn codegen(&self, state: &mut CodegenState<'a>) {
1878 if let Some(star) = self.star {
1879 state.add_token(star);
1880 }
1881 self.whitespace_after_star.codegen(state);
1882 self.value.codegen(state);
1883 }
1884}
1885
1886#[cst_node]
1887pub struct Slice<'a> {
1888 #[cfg_attr(feature = "py", no_py_default)]
1889 pub lower: Option<Expression<'a>>,
1890 #[cfg_attr(feature = "py", no_py_default)]
1891 pub upper: Option<Expression<'a>>,
1892 pub step: Option<Expression<'a>>,
1893 pub first_colon: Colon<'a>,
1894 pub second_colon: Option<Colon<'a>>,
1895}
1896
1897impl<'r, 'a> Inflate<'a> for DeflatedSlice<'r, 'a> {
1898 type Inflated = Slice<'a>;
1899 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1900 let lower = self.lower.inflate(config)?;
1901 let first_colon = self.first_colon.inflate(config)?;
1902 let upper = self.upper.inflate(config)?;
1903 let second_colon = self.second_colon.inflate(config)?;
1904 let step = self.step.inflate(config)?;
1905 Ok(Self::Inflated {
1906 lower,
1907 upper,
1908 step,
1909 first_colon,
1910 second_colon,
1911 })
1912 }
1913}
1914
1915impl<'a> Codegen<'a> for Slice<'a> {
1916 fn codegen(&self, state: &mut CodegenState<'a>) {
1917 if let Some(lower) = &self.lower {
1918 lower.codegen(state);
1919 }
1920 self.first_colon.codegen(state);
1921 if let Some(upper) = &self.upper {
1922 upper.codegen(state);
1923 }
1924 if let Some(second_colon) = &self.second_colon {
1925 second_colon.codegen(state);
1926 } else if self.step.is_some() {
1927 state.add_token(";");
1928 }
1929 if let Some(step) = &self.step {
1930 step.codegen(state);
1931 }
1932 }
1933}
1934
1935#[cst_node]
1936pub struct SubscriptElement<'a> {
1937 pub slice: BaseSlice<'a>,
1938 pub comma: Option<Comma<'a>>,
1939}
1940
1941impl<'r, 'a> Inflate<'a> for DeflatedSubscriptElement<'r, 'a> {
1942 type Inflated = SubscriptElement<'a>;
1943 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1944 let slice = self.slice.inflate(config)?;
1945 let comma = self.comma.inflate(config)?;
1946 Ok(Self::Inflated { slice, comma })
1947 }
1948}
1949
1950impl<'a> Codegen<'a> for SubscriptElement<'a> {
1951 fn codegen(&self, state: &mut CodegenState<'a>) {
1952 self.slice.codegen(state);
1953 if let Some(comma) = &self.comma {
1954 comma.codegen(state);
1955 }
1956 }
1957}
1958
1959#[cst_node(ParenthesizedNode)]
1960pub struct Subscript<'a> {
1961 pub value: Box<Expression<'a>>,
1962 pub slice: Vec<SubscriptElement<'a>>,
1963 pub lbracket: LeftSquareBracket<'a>,
1964 pub rbracket: RightSquareBracket<'a>,
1965 pub lpar: Vec<LeftParen<'a>>,
1966 pub rpar: Vec<RightParen<'a>>,
1967 pub whitespace_after_value: ParenthesizableWhitespace<'a>,
1968}
1969
1970impl<'r, 'a> Inflate<'a> for DeflatedSubscript<'r, 'a> {
1971 type Inflated = Subscript<'a>;
1972 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1973 let lpar = self.lpar.inflate(config)?;
1974 let value = self.value.inflate(config)?;
1975 let whitespace_after_value = parse_parenthesizable_whitespace(
1976 config,
1977 &mut self.lbracket.tok.whitespace_before.borrow_mut(),
1978 )?;
1979 let lbracket = self.lbracket.inflate(config)?;
1980 let slice = self.slice.inflate(config)?;
1981 let rbracket = self.rbracket.inflate(config)?;
1982 let rpar = self.rpar.inflate(config)?;
1983 Ok(Self::Inflated {
1984 value,
1985 slice,
1986 lbracket,
1987 rbracket,
1988 lpar,
1989 rpar,
1990 whitespace_after_value,
1991 })
1992 }
1993}
1994
1995impl<'a> Codegen<'a> for Subscript<'a> {
1996 fn codegen(&self, state: &mut CodegenState<'a>) {
1997 self.parenthesize(state, |state| {
1998 self.value.codegen(state);
1999 self.whitespace_after_value.codegen(state);
2000 self.lbracket.codegen(state);
2001 let len = self.slice.len();
2002 for (i, slice) in self.slice.iter().enumerate() {
2003 slice.codegen(state);
2004 if slice.comma.is_none() && i + 1 < len {
2005 state.add_token(", ")
2006 }
2007 }
2008 self.rbracket.codegen(state);
2009 })
2010 }
2011}
2012
2013#[cst_node(ParenthesizedNode)]
2014pub struct IfExp<'a> {
2015 pub test: Box<Expression<'a>>,
2016 pub body: Box<Expression<'a>>,
2017 pub orelse: Box<Expression<'a>>,
2018 pub lpar: Vec<LeftParen<'a>>,
2019 pub rpar: Vec<RightParen<'a>>,
2020 pub whitespace_before_if: ParenthesizableWhitespace<'a>,
2021 pub whitespace_after_if: ParenthesizableWhitespace<'a>,
2022 pub whitespace_before_else: ParenthesizableWhitespace<'a>,
2023 pub whitespace_after_else: ParenthesizableWhitespace<'a>,
2024
2025 pub(crate) if_tok: TokenRef<'a>,
2026 pub(crate) else_tok: TokenRef<'a>,
2027}
2028
2029impl<'r, 'a> Inflate<'a> for DeflatedIfExp<'r, 'a> {
2030 type Inflated = IfExp<'a>;
2031 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2032 let lpar = self.lpar.inflate(config)?;
2033 let body = self.body.inflate(config)?;
2034 let whitespace_before_if = parse_parenthesizable_whitespace(
2035 config,
2036 &mut (*self.if_tok).whitespace_before.borrow_mut(),
2037 )?;
2038 let whitespace_after_if = parse_parenthesizable_whitespace(
2039 config,
2040 &mut (*self.if_tok).whitespace_after.borrow_mut(),
2041 )?;
2042 let test = self.test.inflate(config)?;
2043 let whitespace_before_else = parse_parenthesizable_whitespace(
2044 config,
2045 &mut (*self.else_tok).whitespace_before.borrow_mut(),
2046 )?;
2047 let whitespace_after_else = parse_parenthesizable_whitespace(
2048 config,
2049 &mut (*self.else_tok).whitespace_after.borrow_mut(),
2050 )?;
2051 let orelse = self.orelse.inflate(config)?;
2052 let rpar = self.rpar.inflate(config)?;
2053 Ok(Self::Inflated {
2054 test,
2055 body,
2056 orelse,
2057 lpar,
2058 rpar,
2059 whitespace_before_if,
2060 whitespace_after_if,
2061 whitespace_before_else,
2062 whitespace_after_else,
2063 })
2064 }
2065}
2066
2067impl<'a> Codegen<'a> for IfExp<'a> {
2068 fn codegen(&self, state: &mut CodegenState<'a>) {
2069 self.parenthesize(state, |state| {
2070 self.body.codegen(state);
2071 self.whitespace_before_if.codegen(state);
2072 state.add_token("if");
2073 self.whitespace_after_if.codegen(state);
2074 self.test.codegen(state);
2075 self.whitespace_before_else.codegen(state);
2076 state.add_token("else");
2077 self.whitespace_after_else.codegen(state);
2078 self.orelse.codegen(state);
2079 })
2080 }
2081}
2082
2083#[cst_node(ParenthesizedNode)]
2084pub struct Lambda<'a> {
2085 pub params: Box<Parameters<'a>>,
2086 pub body: Box<Expression<'a>>,
2087 pub colon: Colon<'a>,
2088 pub lpar: Vec<LeftParen<'a>>,
2089 pub rpar: Vec<RightParen<'a>>,
2090 pub whitespace_after_lambda: Option<ParenthesizableWhitespace<'a>>,
2091
2092 pub(crate) lambda_tok: TokenRef<'a>,
2093}
2094
2095impl<'r, 'a> Inflate<'a> for DeflatedLambda<'r, 'a> {
2096 type Inflated = Lambda<'a>;
2097 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2098 let lpar = self.lpar.inflate(config)?;
2099 let whitespace_after_lambda = if !self.params.is_empty() {
2100 Some(parse_parenthesizable_whitespace(
2101 config,
2102 &mut (*self.lambda_tok).whitespace_after.borrow_mut(),
2103 )?)
2104 } else {
2105 Default::default()
2106 };
2107 let mut params = self.params.inflate(config)?;
2108 adjust_parameters_trailing_whitespace(config, &mut params, &self.colon.tok)?;
2109 let colon = self.colon.inflate(config)?;
2110 let body = self.body.inflate(config)?;
2111 let rpar = self.rpar.inflate(config)?;
2112 Ok(Self::Inflated {
2113 params,
2114 body,
2115 colon,
2116 lpar,
2117 rpar,
2118 whitespace_after_lambda,
2119 })
2120 }
2121}
2122
2123impl<'a> Codegen<'a> for Lambda<'a> {
2124 fn codegen(&self, state: &mut CodegenState<'a>) {
2125 self.parenthesize(state, |state| {
2126 state.add_token("lambda");
2127 if let Some(ws) = &self.whitespace_after_lambda {
2128 ws.codegen(state);
2129 } else if !self.params.is_empty() {
2130 state.add_token(" ")
2132 }
2133 self.params.codegen(state);
2134 self.colon.codegen(state);
2135 self.body.codegen(state);
2136 })
2137 }
2138}
2139
2140#[cst_node]
2141pub struct From<'a> {
2142 pub item: Expression<'a>,
2143 pub whitespace_before_from: Option<ParenthesizableWhitespace<'a>>,
2144 pub whitespace_after_from: ParenthesizableWhitespace<'a>,
2145
2146 pub(crate) tok: TokenRef<'a>,
2147}
2148
2149impl<'a> From<'a> {
2150 pub fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) {
2151 if let Some(ws) = &self.whitespace_before_from {
2152 ws.codegen(state);
2153 } else {
2154 state.add_token(default_space);
2155 }
2156 state.add_token("from");
2157 self.whitespace_after_from.codegen(state);
2158 self.item.codegen(state);
2159 }
2160}
2161
2162impl<'r, 'a> Inflate<'a> for DeflatedFrom<'r, 'a> {
2163 type Inflated = From<'a>;
2164 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2165 let whitespace_before_from = Some(parse_parenthesizable_whitespace(
2166 config,
2167 &mut (*self.tok).whitespace_before.borrow_mut(),
2168 )?);
2169 let whitespace_after_from = parse_parenthesizable_whitespace(
2170 config,
2171 &mut (*self.tok).whitespace_after.borrow_mut(),
2172 )?;
2173 let item = self.item.inflate(config)?;
2174 Ok(Self::Inflated {
2175 item,
2176 whitespace_before_from,
2177 whitespace_after_from,
2178 })
2179 }
2180}
2181
2182#[cst_node]
2183pub enum YieldValue<'a> {
2184 Expression(Box<Expression<'a>>),
2185 From(Box<From<'a>>),
2186}
2187
2188impl<'r, 'a> Inflate<'a> for DeflatedYieldValue<'r, 'a> {
2189 type Inflated = YieldValue<'a>;
2190 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2191 Ok(match self {
2192 Self::Expression(e) => Self::Inflated::Expression(e.inflate(config)?),
2193 Self::From(e) => {
2194 let mut e = e.inflate(config)?;
2195 e.whitespace_before_from = None;
2196 Self::Inflated::From(e)
2197 }
2198 })
2199 }
2200}
2201
2202impl<'a> YieldValue<'a> {
2203 fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) {
2204 match self {
2205 Self::Expression(e) => e.codegen(state),
2206 Self::From(f) => f.codegen(state, default_space),
2207 }
2208 }
2209}
2210
2211#[cst_node(ParenthesizedNode)]
2212pub struct Yield<'a> {
2213 pub value: Option<Box<YieldValue<'a>>>,
2214 pub lpar: Vec<LeftParen<'a>>,
2215 pub rpar: Vec<RightParen<'a>>,
2216 pub whitespace_after_yield: Option<ParenthesizableWhitespace<'a>>,
2217
2218 pub(crate) yield_tok: TokenRef<'a>,
2219}
2220
2221impl<'r, 'a> Inflate<'a> for DeflatedYield<'r, 'a> {
2222 type Inflated = Yield<'a>;
2223 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2224 let lpar = self.lpar.inflate(config)?;
2225 let whitespace_after_yield = if self.value.is_some() {
2226 Some(parse_parenthesizable_whitespace(
2227 config,
2228 &mut (*self.yield_tok).whitespace_after.borrow_mut(),
2229 )?)
2230 } else {
2231 Default::default()
2232 };
2233 let value = self.value.inflate(config)?;
2234 let rpar = self.rpar.inflate(config)?;
2235 Ok(Self::Inflated {
2236 value,
2237 lpar,
2238 rpar,
2239 whitespace_after_yield,
2240 })
2241 }
2242}
2243
2244impl<'a> Codegen<'a> for Yield<'a> {
2245 fn codegen(&self, state: &mut CodegenState<'a>) {
2246 self.parenthesize(state, |state| {
2247 state.add_token("yield");
2248 if let Some(ws) = &self.whitespace_after_yield {
2249 ws.codegen(state);
2250 } else if self.value.is_some() {
2251 state.add_token(" ");
2252 }
2253
2254 if let Some(val) = &self.value {
2255 val.codegen(state, "")
2256 }
2257 })
2258 }
2259}
2260
2261#[cst_node(ParenthesizedNode)]
2262pub struct Await<'a> {
2263 pub expression: Box<Expression<'a>>,
2264 pub lpar: Vec<LeftParen<'a>>,
2265 pub rpar: Vec<RightParen<'a>>,
2266 pub whitespace_after_await: ParenthesizableWhitespace<'a>,
2267
2268 pub(crate) await_tok: TokenRef<'a>,
2269}
2270
2271impl<'r, 'a> Inflate<'a> for DeflatedAwait<'r, 'a> {
2272 type Inflated = Await<'a>;
2273 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2274 let lpar = self.lpar.inflate(config)?;
2275 let whitespace_after_await = parse_parenthesizable_whitespace(
2276 config,
2277 &mut (*self.await_tok).whitespace_after.borrow_mut(),
2278 )?;
2279 let expression = self.expression.inflate(config)?;
2280 let rpar = self.rpar.inflate(config)?;
2281 Ok(Self::Inflated {
2282 expression,
2283 lpar,
2284 rpar,
2285 whitespace_after_await,
2286 })
2287 }
2288}
2289
2290impl<'a> Codegen<'a> for Await<'a> {
2291 fn codegen(&self, state: &mut CodegenState<'a>) {
2292 self.parenthesize(state, |state| {
2293 state.add_token("await");
2294 self.whitespace_after_await.codegen(state);
2295 self.expression.codegen(state);
2296 })
2297 }
2298}
2299
2300#[cst_node(Codegen, Inflate)]
2301pub enum String<'a> {
2302 Simple(SimpleString<'a>),
2303 Concatenated(ConcatenatedString<'a>),
2304 Formatted(FormattedString<'a>),
2305 Templated(TemplatedString<'a>),
2306}
2307
2308impl<'r, 'a> std::convert::From<DeflatedString<'r, 'a>> for DeflatedExpression<'r, 'a> {
2309 fn from(s: DeflatedString<'r, 'a>) -> Self {
2310 match s {
2311 DeflatedString::Simple(s) => Self::SimpleString(Box::new(s)),
2312 DeflatedString::Concatenated(s) => Self::ConcatenatedString(Box::new(s)),
2313 DeflatedString::Formatted(s) => Self::FormattedString(Box::new(s)),
2314 DeflatedString::Templated(s) => Self::TemplatedString(Box::new(s)),
2315 }
2316 }
2317}
2318
2319#[cst_node(ParenthesizedNode)]
2320pub struct ConcatenatedString<'a> {
2321 pub left: Box<String<'a>>,
2322 pub right: Box<String<'a>>,
2323 pub lpar: Vec<LeftParen<'a>>,
2324 pub rpar: Vec<RightParen<'a>>,
2325 pub whitespace_between: ParenthesizableWhitespace<'a>,
2326
2327 pub(crate) right_tok: TokenRef<'a>,
2330}
2331
2332impl<'r, 'a> Inflate<'a> for DeflatedConcatenatedString<'r, 'a> {
2333 type Inflated = ConcatenatedString<'a>;
2334 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2335 let lpar = self.lpar.inflate(config)?;
2336 let left = self.left.inflate(config)?;
2337 let whitespace_between = parse_parenthesizable_whitespace(
2338 config,
2339 &mut (*self.right_tok).whitespace_before.borrow_mut(),
2340 )?;
2341 let right = self.right.inflate(config)?;
2342 let rpar = self.rpar.inflate(config)?;
2343 Ok(Self::Inflated {
2344 left,
2345 right,
2346 lpar,
2347 rpar,
2348 whitespace_between,
2349 })
2350 }
2351}
2352
2353impl<'a> Codegen<'a> for ConcatenatedString<'a> {
2354 fn codegen(&self, state: &mut CodegenState<'a>) {
2355 self.parenthesize(state, |state| {
2356 self.left.codegen(state);
2357 self.whitespace_between.codegen(state);
2358 self.right.codegen(state);
2359 })
2360 }
2361}
2362
2363#[cst_node(ParenthesizedNode, Default)]
2364pub struct SimpleString<'a> {
2365 pub value: &'a str,
2369 pub lpar: Vec<LeftParen<'a>>,
2370 pub rpar: Vec<RightParen<'a>>,
2371}
2372
2373impl<'r, 'a> Inflate<'a> for DeflatedSimpleString<'r, 'a> {
2374 type Inflated = SimpleString<'a>;
2375 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2376 let lpar = self.lpar.inflate(config)?;
2377 let rpar = self.rpar.inflate(config)?;
2378 Ok(Self::Inflated {
2379 value: self.value,
2380 lpar,
2381 rpar,
2382 })
2383 }
2384}
2385
2386impl<'a> Codegen<'a> for SimpleString<'a> {
2387 fn codegen(&self, state: &mut CodegenState<'a>) {
2388 self.parenthesize(state, |state| state.add_token(self.value))
2389 }
2390}
2391
2392#[cst_node]
2393pub struct TemplatedStringText<'a> {
2394 pub value: &'a str,
2395}
2396
2397impl<'r, 'a> Inflate<'a> for DeflatedTemplatedStringText<'r, 'a> {
2398 type Inflated = TemplatedStringText<'a>;
2399 fn inflate(self, _config: &Config<'a>) -> Result<Self::Inflated> {
2400 Ok(Self::Inflated { value: self.value })
2401 }
2402}
2403
2404impl<'a> Codegen<'a> for TemplatedStringText<'a> {
2405 fn codegen(&self, state: &mut CodegenState<'a>) {
2406 state.add_token(self.value);
2407 }
2408}
2409
2410pub(crate) fn make_tstringtext<'r, 'a>(value: &'a str) -> DeflatedTemplatedStringText<'r, 'a> {
2411 DeflatedTemplatedStringText {
2412 value,
2413 _phantom: Default::default(),
2414 }
2415}
2416
2417#[cst_node]
2418pub struct TemplatedStringExpression<'a> {
2419 pub expression: Expression<'a>,
2421 pub conversion: Option<&'a str>,
2422 pub format_spec: Option<Vec<TemplatedStringContent<'a>>>,
2423 pub whitespace_before_expression: ParenthesizableWhitespace<'a>,
2424 pub whitespace_after_expression: ParenthesizableWhitespace<'a>,
2425 pub equal: Option<AssignEqual<'a>>,
2426
2427 pub(crate) lbrace_tok: TokenRef<'a>,
2428 pub(crate) after_expr_tok: Option<TokenRef<'a>>,
2431}
2432
2433impl<'r, 'a> Inflate<'a> for DeflatedTemplatedStringExpression<'r, 'a> {
2434 type Inflated = TemplatedStringExpression<'a>;
2435 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2436 let whitespace_before_expression = parse_parenthesizable_whitespace(
2437 config,
2438 &mut (*self.lbrace_tok).whitespace_after.borrow_mut(),
2439 )?;
2440 let expression = self.expression.inflate(config)?;
2441 let equal = self.equal.inflate(config)?;
2442 let whitespace_after_expression = if let Some(after_expr_tok) = self.after_expr_tok.as_mut()
2443 {
2444 parse_parenthesizable_whitespace(
2445 config,
2446 &mut after_expr_tok.whitespace_before.borrow_mut(),
2447 )?
2448 } else {
2449 Default::default()
2450 };
2451 let format_spec = self.format_spec.inflate(config)?;
2452 Ok(Self::Inflated {
2453 expression,
2454 conversion: self.conversion,
2455 format_spec,
2456 whitespace_before_expression,
2457 whitespace_after_expression,
2458 equal,
2459 })
2460 }
2461}
2462
2463impl<'a> Codegen<'a> for TemplatedStringExpression<'a> {
2464 fn codegen(&self, state: &mut CodegenState<'a>) {
2465 state.add_token("{");
2466 self.whitespace_before_expression.codegen(state);
2467 self.expression.codegen(state);
2468 if let Some(eq) = &self.equal {
2469 eq.codegen(state);
2470 }
2471 self.whitespace_after_expression.codegen(state);
2472 if let Some(conv) = &self.conversion {
2473 state.add_token("!");
2474 state.add_token(conv);
2475 }
2476 if let Some(specs) = &self.format_spec {
2477 state.add_token(":");
2478 for spec in specs {
2479 spec.codegen(state);
2480 }
2481 }
2482 state.add_token("}");
2483 }
2484}
2485
2486#[cst_node(ParenthesizedNode)]
2487pub struct TemplatedString<'a> {
2488 pub parts: Vec<TemplatedStringContent<'a>>,
2489 pub start: &'a str,
2490 pub end: &'a str,
2491 pub lpar: Vec<LeftParen<'a>>,
2492 pub rpar: Vec<RightParen<'a>>,
2493}
2494
2495impl<'r, 'a> Inflate<'a> for DeflatedTemplatedString<'r, 'a> {
2496 type Inflated = TemplatedString<'a>;
2497 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2498 let lpar = self.lpar.inflate(config)?;
2499 let parts = self.parts.inflate(config)?;
2500 let rpar = self.rpar.inflate(config)?;
2501 Ok(Self::Inflated {
2502 parts,
2503 start: self.start,
2504 end: self.end,
2505 lpar,
2506 rpar,
2507 })
2508 }
2509}
2510
2511impl<'a> Codegen<'a> for TemplatedString<'a> {
2512 fn codegen(&self, state: &mut CodegenState<'a>) {
2513 self.parenthesize(state, |state| {
2514 state.add_token(self.start);
2515 for part in &self.parts {
2516 part.codegen(state);
2517 }
2518 state.add_token(self.end);
2519 })
2520 }
2521}
2522
2523#[cst_node(Codegen, Inflate)]
2524pub enum TemplatedStringContent<'a> {
2525 Text(TemplatedStringText<'a>),
2526 Expression(Box<TemplatedStringExpression<'a>>),
2527}
2528#[cst_node]
2529pub struct FormattedStringText<'a> {
2530 pub value: &'a str,
2531}
2532
2533impl<'r, 'a> Inflate<'a> for DeflatedFormattedStringText<'r, 'a> {
2534 type Inflated = FormattedStringText<'a>;
2535 fn inflate(self, _config: &Config<'a>) -> Result<Self::Inflated> {
2536 Ok(Self::Inflated { value: self.value })
2537 }
2538}
2539
2540impl<'a> Codegen<'a> for FormattedStringText<'a> {
2541 fn codegen(&self, state: &mut CodegenState<'a>) {
2542 state.add_token(self.value);
2543 }
2544}
2545
2546pub(crate) fn make_fstringtext<'r, 'a>(value: &'a str) -> DeflatedFormattedStringText<'r, 'a> {
2547 DeflatedFormattedStringText {
2548 value,
2549 _phantom: Default::default(),
2550 }
2551}
2552
2553#[cst_node]
2554pub struct FormattedStringExpression<'a> {
2555 pub expression: Expression<'a>,
2556 pub conversion: Option<&'a str>,
2557 pub format_spec: Option<Vec<FormattedStringContent<'a>>>,
2558 pub whitespace_before_expression: ParenthesizableWhitespace<'a>,
2559 pub whitespace_after_expression: ParenthesizableWhitespace<'a>,
2560 pub equal: Option<AssignEqual<'a>>,
2561
2562 pub(crate) lbrace_tok: TokenRef<'a>,
2563 pub(crate) after_expr_tok: Option<TokenRef<'a>>,
2566}
2567
2568impl<'r, 'a> Inflate<'a> for DeflatedFormattedStringExpression<'r, 'a> {
2569 type Inflated = FormattedStringExpression<'a>;
2570 fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2571 let whitespace_before_expression = parse_parenthesizable_whitespace(
2572 config,
2573 &mut (*self.lbrace_tok).whitespace_after.borrow_mut(),
2574 )?;
2575 let expression = self.expression.inflate(config)?;
2576 let equal = self.equal.inflate(config)?;
2577 let whitespace_after_expression = if let Some(after_expr_tok) = self.after_expr_tok.as_mut()
2578 {
2579 parse_parenthesizable_whitespace(
2580 config,
2581 &mut after_expr_tok.whitespace_before.borrow_mut(),
2582 )?
2583 } else {
2584 Default::default()
2585 };
2586 let format_spec = self.format_spec.inflate(config)?;
2587 Ok(Self::Inflated {
2588 expression,
2589 conversion: self.conversion,
2590 format_spec,
2591 whitespace_before_expression,
2592 whitespace_after_expression,
2593 equal,
2594 })
2595 }
2596}
2597
2598impl<'a> Codegen<'a> for FormattedStringExpression<'a> {
2599 fn codegen(&self, state: &mut CodegenState<'a>) {
2600 state.add_token("{");
2601 self.whitespace_before_expression.codegen(state);
2602 self.expression.codegen(state);
2603 if let Some(eq) = &self.equal {
2604 eq.codegen(state);
2605 }
2606 self.whitespace_after_expression.codegen(state);
2607 if let Some(conv) = &self.conversion {
2608 state.add_token("!");
2609 state.add_token(conv);
2610 }
2611 if let Some(specs) = &self.format_spec {
2612 state.add_token(":");
2613 for spec in specs {
2614 spec.codegen(state);
2615 }
2616 }
2617 state.add_token("}");
2618 }
2619}
2620
2621#[cst_node(Codegen, Inflate)]
2622pub enum FormattedStringContent<'a> {
2623 Text(FormattedStringText<'a>),
2624 Expression(Box<FormattedStringExpression<'a>>),
2625}
2626
2627#[cst_node(ParenthesizedNode)]
2628pub struct FormattedString<'a> {
2629 pub parts: Vec<FormattedStringContent<'a>>,
2630 pub start: &'a str,
2631 pub end: &'a str,
2632 pub lpar: Vec<LeftParen<'a>>,
2633 pub rpar: Vec<RightParen<'a>>,
2634}
2635
2636impl<'r, 'a> Inflate<'a> for DeflatedFormattedString<'r, 'a> {
2637 type Inflated = FormattedString<'a>;
2638 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2639 let lpar = self.lpar.inflate(config)?;
2640 let parts = self.parts.inflate(config)?;
2641 let rpar = self.rpar.inflate(config)?;
2642 Ok(Self::Inflated {
2643 parts,
2644 start: self.start,
2645 end: self.end,
2646 lpar,
2647 rpar,
2648 })
2649 }
2650}
2651
2652impl<'a> Codegen<'a> for FormattedString<'a> {
2653 fn codegen(&self, state: &mut CodegenState<'a>) {
2654 self.parenthesize(state, |state| {
2655 state.add_token(self.start);
2656 for part in &self.parts {
2657 part.codegen(state);
2658 }
2659 state.add_token(self.end);
2660 })
2661 }
2662}
2663
2664#[cst_node(ParenthesizedNode)]
2665pub struct NamedExpr<'a> {
2666 pub target: Box<Expression<'a>>,
2667 pub value: Box<Expression<'a>>,
2668 pub lpar: Vec<LeftParen<'a>>,
2669 pub rpar: Vec<RightParen<'a>>,
2670
2671 pub whitespace_before_walrus: ParenthesizableWhitespace<'a>,
2672 pub whitespace_after_walrus: ParenthesizableWhitespace<'a>,
2673
2674 pub(crate) walrus_tok: TokenRef<'a>,
2675}
2676
2677impl<'a> Codegen<'a> for NamedExpr<'a> {
2678 fn codegen(&self, state: &mut CodegenState<'a>) {
2679 self.parenthesize(state, |state| {
2680 self.target.codegen(state);
2681 self.whitespace_before_walrus.codegen(state);
2682 state.add_token(":=");
2683 self.whitespace_after_walrus.codegen(state);
2684 self.value.codegen(state);
2685 })
2686 }
2687}
2688
2689impl<'r, 'a> Inflate<'a> for DeflatedNamedExpr<'r, 'a> {
2690 type Inflated = NamedExpr<'a>;
2691 fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2692 let lpar = self.lpar.inflate(config)?;
2693 let target = self.target.inflate(config)?;
2694 let whitespace_before_walrus = parse_parenthesizable_whitespace(
2695 config,
2696 &mut self.walrus_tok.whitespace_before.borrow_mut(),
2697 )?;
2698 let whitespace_after_walrus = parse_parenthesizable_whitespace(
2699 config,
2700 &mut self.walrus_tok.whitespace_after.borrow_mut(),
2701 )?;
2702 let value = self.value.inflate(config)?;
2703 let rpar = self.rpar.inflate(config)?;
2704 Ok(Self::Inflated {
2705 target,
2706 value,
2707 lpar,
2708 rpar,
2709 whitespace_before_walrus,
2710 whitespace_after_walrus,
2711 })
2712 }
2713}
2714
2715#[cfg(feature = "py")]
2716mod py {
2717
2718 use pyo3::types::PyAnyMethods;
2719 use pyo3::types::PyModule;
2720
2721 use super::*;
2722 use crate::nodes::traits::py::TryIntoPy;
2723
2724 impl<'a> TryIntoPy<pyo3::Py<pyo3::PyAny>> for Element<'a> {
2726 fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
2727 match self {
2728 Self::Starred(s) => s.try_into_py(py),
2729 Self::Simple { value, comma } => {
2730 let libcst = PyModule::import(py, "libcst")?;
2731 let kwargs = [
2732 Some(("value", value.try_into_py(py)?)),
2733 comma
2734 .map(|x| x.try_into_py(py))
2735 .transpose()?
2736 .map(|x| ("comma", x)),
2737 ]
2738 .iter()
2739 .filter(|x| x.is_some())
2740 .map(|x| x.as_ref().unwrap())
2741 .collect::<Vec<_>>()
2742 .into_py_dict(py)?;
2743 Ok(libcst
2744 .getattr("Element")
2745 .expect("no Element found in libcst")
2746 .call((), Some(&kwargs))?
2747 .into())
2748 }
2749 }
2750 }
2751 }
2752
2753 impl<'a> TryIntoPy<pyo3::Py<pyo3::PyAny>> for DictElement<'a> {
2755 fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
2756 match self {
2757 Self::Starred(s) => s.try_into_py(py),
2758 Self::Simple {
2759 key,
2760 value,
2761 comma,
2762 whitespace_after_colon,
2763 whitespace_before_colon,
2764 ..
2765 } => {
2766 let libcst = PyModule::import(py, "libcst")?;
2767 let kwargs = [
2768 Some(("key", key.try_into_py(py)?)),
2769 Some(("value", value.try_into_py(py)?)),
2770 Some((
2771 "whitespace_before_colon",
2772 whitespace_before_colon.try_into_py(py)?,
2773 )),
2774 Some((
2775 "whitespace_after_colon",
2776 whitespace_after_colon.try_into_py(py)?,
2777 )),
2778 comma
2779 .map(|x| x.try_into_py(py))
2780 .transpose()?
2781 .map(|x| ("comma", x)),
2782 ]
2783 .iter()
2784 .filter(|x| x.is_some())
2785 .map(|x| x.as_ref().unwrap())
2786 .collect::<Vec<_>>()
2787 .into_py_dict(py)?;
2788 Ok(libcst
2789 .getattr("DictElement")
2790 .expect("no Element found in libcst")
2791 .call((), Some(&kwargs))?
2792 .into())
2793 }
2794 }
2795 }
2796 }
2797}