python_ast/ast/tree/
expression.rs

1use proc_macro2::TokenStream;
2use pyo3::{Bound, FromPyObject, PyAny, PyResult, prelude::PyAnyMethods, types::PyTypeMethods};
3use quote::quote;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    dump, Attribute, Await, BinOp, BoolOp, Call, CodeGen, CodeGenContext, Compare, Constant, Error,
8    Name, NamedExpr, Node, PythonOptions, SymbolTableScopes, UnaryOp, Lambda, IfExp, Dict, Set, Tuple, Subscript, Starred, ListComp, DictComp, SetComp, GeneratorExp, Yield, YieldFrom, JoinedStr, FormattedValue,
9};
10
11/// Mostly this shouldn't be used, but it exists so that we don't have to manually implement FromPyObject on all of ExprType
12#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
13#[repr(transparent)]
14pub struct Container<T>(pub T);
15
16impl<'a> FromPyObject<'a> for Container<crate::pytypes::List<ExprType>> {
17    fn extract_bound(ob: &Bound<'a, PyAny>) -> PyResult<Self> {
18        let list = crate::pytypes::List::<ExprType>::new();
19
20        log::debug!("pylist: {}", dump(ob, Some(4))?);
21        let _converted_list: Vec<Bound<PyAny>> = ob.extract()?;
22        for item in _converted_list.iter() {
23            log::debug!("item: {:?}", item);
24        }
25
26        Ok(Self(list))
27    }
28}
29
30#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
31pub enum ExprType {
32    BoolOp(BoolOp),
33    NamedExpr(NamedExpr),
34    BinOp(BinOp),
35    UnaryOp(UnaryOp),
36    Lambda(Lambda),
37    IfExp(IfExp),
38    Dict(Dict),
39    Set(Set),
40    ListComp(ListComp),
41    DictComp(DictComp),
42    SetComp(SetComp),
43    GeneratorExp(GeneratorExp),
44    Await(Await),
45    Yield(Yield),
46    YieldFrom(YieldFrom),
47    Compare(Compare),
48    Call(Call),
49    FormattedValue(FormattedValue),
50    JoinedStr(JoinedStr),
51    Constant(Constant),
52
53    /// These can appear in a few places, such as the left side of an assignment.
54    Attribute(Attribute),
55    Subscript(Subscript),
56    Starred(Starred),
57    Name(Name),
58    List(Vec<ExprType>),
59    Tuple(Tuple),
60    /*Slice(),*/
61    NoneType(Constant),
62
63    Unimplemented(String),
64    #[default]
65    Unknown,
66}
67
68impl<'a> FromPyObject<'a> for ExprType {
69    fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
70        log::debug!("exprtype ob: {}", dump(ob, Some(4))?);
71
72        let expr_type = ob.get_type().name().expect(
73            ob.error_message(
74                "<unknown>",
75                format!("extracting type name {:?} in expression", dump(ob, None)),
76            )
77            .as_str(),
78        );
79        log::debug!("expression type: {}, value: {}", expr_type, dump(ob, None)?);
80
81        let r = match expr_type.extract::<String>()?.as_str() {
82            "Attribute" => {
83                let a = ob.extract().expect(
84                    ob.error_message(
85                        "<unknown>",
86                        format!("extracting Attribute in expression {}", dump(ob, None)?),
87                    )
88                    .as_str(),
89                );
90                Ok(Self::Attribute(a))
91            }
92            "Await" => {
93                //println!("await: {}", dump(ob, None)?);
94                let a = ob.extract().expect(
95                    ob.error_message(
96                        "<unknown>",
97                        format!("extracting await value in expression {}", dump(ob, None)?),
98                    )
99                    .as_str(),
100                );
101                Ok(Self::Await(a))
102            }
103            "BoolOp" => {
104                let b = ob.extract().expect(
105                    ob.error_message(
106                        "<unknown>",
107                        format!("extracting BoolOp in expression {}", dump(ob, None)?),
108                    )
109                    .as_str(),
110                );
111                Ok(Self::BoolOp(b))
112            }
113            "Call" => {
114                let et = ob.extract().expect(
115                    ob.error_message(
116                        "<unknown>",
117                        format!("parsing Call expression {}", dump(ob, None)?),
118                    )
119                    .as_str(),
120                );
121                Ok(Self::Call(et))
122            }
123            "Compare" => {
124                let c = ob.extract().expect(
125                    ob.error_message(
126                        "<unknown>",
127                        format!("extracting Compare in expression {}", dump(ob, None)?),
128                    )
129                    .as_str(),
130                );
131                Ok(Self::Compare(c))
132            }
133            "Constant" => {
134                log::debug!("constant: {}", dump(ob, None)?);
135                let c = ob.extract().expect(
136                    ob.error_message(
137                        "<unknown>",
138                        format!("extracting Constant in expression {}", dump(ob, None)?),
139                    )
140                    .as_str(),
141                );
142                Ok(Self::Constant(c))
143            }
144            "List" => {
145                // Extract the list elements using the 'elts' attribute
146                let elts_attr = ob.getattr("elts")
147                    .expect(format!("getting elts attribute from List {}", dump(ob, None)?).as_str());
148                let elts_vec: Vec<Bound<PyAny>> = elts_attr.extract()
149                    .expect(format!("extracting elts as Vec<Bound<PyAny>> from List {}", dump(ob, None)?).as_str());
150                
151                // Convert each element to ExprType
152                let mut expr_list = Vec::new();
153                for elt in elts_vec {
154                    let expr: ExprType = elt.extract()
155                        .expect(format!("extracting list element {}", dump(&elt, None)?).as_str());
156                    expr_list.push(expr);
157                }
158                
159                Ok(Self::List(expr_list))
160            }
161            "ListComp" => {
162                let lc = ob.extract().expect(
163                    ob.error_message(
164                        "<unknown>",
165                        format!("extracting ListComp in expression {}", dump(ob, None)?),
166                    )
167                    .as_str(),
168                );
169                Ok(Self::ListComp(lc))
170            }
171            "DictComp" => {
172                let dc = ob.extract().expect(
173                    ob.error_message(
174                        "<unknown>",
175                        format!("extracting DictComp in expression {}", dump(ob, None)?),
176                    )
177                    .as_str(),
178                );
179                Ok(Self::DictComp(dc))
180            }
181            "SetComp" => {
182                let sc = ob.extract().expect(
183                    ob.error_message(
184                        "<unknown>",
185                        format!("extracting SetComp in expression {}", dump(ob, None)?),
186                    )
187                    .as_str(),
188                );
189                Ok(Self::SetComp(sc))
190            }
191            "GeneratorExp" => {
192                let ge = ob.extract().expect(
193                    ob.error_message(
194                        "<unknown>",
195                        format!("extracting GeneratorExp in expression {}", dump(ob, None)?),
196                    )
197                    .as_str(),
198                );
199                Ok(Self::GeneratorExp(ge))
200            }
201            "Name" => {
202                let name = ob.extract().expect(
203                    ob.error_message(
204                        "<unknown>",
205                        format!("parsing Name expression {}", dump(ob, None)?),
206                    )
207                    .as_str(),
208                );
209                Ok(Self::Name(name))
210            }
211            "UnaryOp" => {
212                let c = ob.extract().expect(
213                    ob.error_message(
214                        "<unknown>",
215                        format!("extracting UnaryOp in expression {}", dump(ob, None)?),
216                    )
217                    .as_str(),
218                );
219                Ok(Self::UnaryOp(c))
220            }
221            "BinOp" => {
222                let c = ob.extract().expect(
223                    ob.error_message(
224                        "<unknown>",
225                        format!("extracting BinOp in expression {}", dump(ob, None)?),
226                    )
227                    .as_str(),
228                );
229                Ok(Self::BinOp(c))
230            }
231            "Lambda" => {
232                let l = ob.extract().expect(
233                    ob.error_message(
234                        "<unknown>",
235                        format!("extracting Lambda in expression {}", dump(ob, None)?),
236                    )
237                    .as_str(),
238                );
239                Ok(Self::Lambda(l))
240            }
241            "IfExp" => {
242                let i = ob.extract().expect(
243                    ob.error_message(
244                        "<unknown>",
245                        format!("extracting IfExp in expression {}", dump(ob, None)?),
246                    )
247                    .as_str(),
248                );
249                Ok(Self::IfExp(i))
250            }
251            "Dict" => {
252                let d = ob.extract().expect(
253                    ob.error_message(
254                        "<unknown>",
255                        format!("extracting Dict in expression {}", dump(ob, None)?),
256                    )
257                    .as_str(),
258                );
259                Ok(Self::Dict(d))
260            }
261            "Set" => {
262                let s = ob.extract().expect(
263                    ob.error_message(
264                        "<unknown>",
265                        format!("extracting Set in expression {}", dump(ob, None)?),
266                    )
267                    .as_str(),
268                );
269                Ok(Self::Set(s))
270            }
271            "Tuple" => {
272                let t = ob.extract().expect(
273                    ob.error_message(
274                        "<unknown>",
275                        format!("extracting Tuple in expression {}", dump(ob, None)?),
276                    )
277                    .as_str(),
278                );
279                Ok(Self::Tuple(t))
280            }
281            "Subscript" => {
282                let s = ob.extract().expect(
283                    ob.error_message(
284                        "<unknown>",
285                        format!("extracting Subscript in expression {}", dump(ob, None)?),
286                    )
287                    .as_str(),
288                );
289                Ok(Self::Subscript(s))
290            }
291            "Starred" => {
292                let s = ob.extract().expect(
293                    ob.error_message(
294                        "<unknown>",
295                        format!("extracting Starred in expression {}", dump(ob, None)?),
296                    )
297                    .as_str(),
298                );
299                Ok(Self::Starred(s))
300            }
301            "Yield" => {
302                let y = ob.extract().expect(
303                    ob.error_message(
304                        "<unknown>",
305                        format!("extracting Yield in expression {}", dump(ob, None)?),
306                    )
307                    .as_str(),
308                );
309                Ok(Self::Yield(y))
310            }
311            "YieldFrom" => {
312                let yf = ob.extract().expect(
313                    ob.error_message(
314                        "<unknown>",
315                        format!("extracting YieldFrom in expression {}", dump(ob, None)?),
316                    )
317                    .as_str(),
318                );
319                Ok(Self::YieldFrom(yf))
320            }
321            "JoinedStr" => {
322                let js = ob.extract().expect(
323                    ob.error_message(
324                        "<unknown>",
325                        format!("extracting JoinedStr in expression {}", dump(ob, None)?),
326                    )
327                    .as_str(),
328                );
329                Ok(Self::JoinedStr(js))
330            }
331            "FormattedValue" => {
332                let fv = ob.extract().expect(
333                    ob.error_message(
334                        "<unknown>",
335                        format!("extracting FormattedValue in expression {}", dump(ob, None)?),
336                    )
337                    .as_str(),
338                );
339                Ok(Self::FormattedValue(fv))
340            }
341            _ => {
342                let err_msg = format!(
343                    "Unimplemented expression type {}, {}",
344                    expr_type,
345                    dump(ob, None)?
346                );
347                Err(pyo3::exceptions::PyValueError::new_err(
348                    ob.error_message("<unknown>", err_msg.as_str()),
349                ))
350            }
351        };
352        r
353    }
354}
355
356impl<'a> CodeGen for ExprType {
357    type Context = CodeGenContext;
358    type Options = PythonOptions;
359    type SymbolTable = SymbolTableScopes;
360
361    fn to_rust(
362        self,
363        ctx: Self::Context,
364        options: Self::Options,
365        symbols: Self::SymbolTable,
366    ) -> std::result::Result<TokenStream, Box<dyn std::error::Error>> {
367        match self {
368            ExprType::Attribute(attribute) => attribute.to_rust(ctx, options, symbols),
369            ExprType::Await(func) => func.to_rust(ctx, options, symbols),
370            ExprType::BinOp(binop) => binop.to_rust(ctx, options, symbols),
371            ExprType::Call(call) => call.to_rust(ctx, options, symbols),
372            ExprType::Compare(c) => c.to_rust(ctx, options, symbols),
373            ExprType::Constant(c) => c.to_rust(ctx, options, symbols),
374            ExprType::Lambda(l) => l.to_rust(ctx, options, symbols),
375            ExprType::IfExp(i) => i.to_rust(ctx, options, symbols),
376            ExprType::Dict(d) => d.to_rust(ctx, options, symbols),
377            ExprType::Set(s) => s.to_rust(ctx, options, symbols),
378            ExprType::ListComp(lc) => lc.to_rust(ctx, options, symbols),
379            ExprType::DictComp(dc) => dc.to_rust(ctx, options, symbols),
380            ExprType::SetComp(sc) => sc.to_rust(ctx, options, symbols),
381            ExprType::GeneratorExp(ge) => ge.to_rust(ctx, options, symbols),
382            ExprType::Tuple(t) => t.to_rust(ctx, options, symbols),
383            ExprType::Subscript(s) => s.to_rust(ctx, options, symbols),
384            ExprType::Starred(s) => s.to_rust(ctx, options, symbols),
385            ExprType::Yield(y) => y.to_rust(ctx, options, symbols),
386            ExprType::YieldFrom(yf) => yf.to_rust(ctx, options, symbols),
387            ExprType::JoinedStr(js) => js.to_rust(ctx, options, symbols),
388            ExprType::FormattedValue(fv) => fv.to_rust(ctx, options, symbols),
389            ExprType::List(l) => {
390                let mut ts = TokenStream::new();
391                for li in l {
392                    let code = li
393                        .clone()
394                        .to_rust(ctx.clone(), options.clone(), symbols.clone())
395                        .expect(format!("Extracting list item {:?}", li).as_str());
396                    ts.extend(code);
397                    ts.extend(quote!(,));
398                }
399                Ok(ts)
400            }
401            ExprType::Name(name) => name.to_rust(ctx, options, symbols),
402            ExprType::NoneType(c) => c.to_rust(ctx, options, symbols),
403            ExprType::UnaryOp(operand) => operand.to_rust(ctx, options, symbols),
404
405            _ => {
406                let error = Error::ExprTypeNotYetImplemented(self);
407                Err(error.into())
408            }
409        }
410    }
411}
412
413/// An Expr only contains a single value key, which leads to the actual expression,
414/// which is one of several types.
415#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
416pub struct Expr {
417    pub value: ExprType,
418    pub ctx: Option<String>,
419    pub lineno: Option<usize>,
420    pub col_offset: Option<usize>,
421    pub end_lineno: Option<usize>,
422    pub end_col_offset: Option<usize>,
423}
424
425impl<'a> FromPyObject<'a> for Expr {
426    fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
427        let err_msg = format!("extracting object value {} in expression", dump(ob, None)?);
428
429        let ob_value = ob
430            .getattr("value")
431            .expect(ob.error_message("<unknown>", err_msg.as_str()).as_str());
432        log::debug!("ob_value: {}", dump(&ob_value, None)?);
433
434        // The context is Load, Store, etc. For some types of expressions such as Constants, it does not exist.
435        let ctx: Option<String> = if let Ok(pyany) = ob_value.getattr("ctx") {
436            pyany.get_type().extract().unwrap_or_default()
437        } else {
438            None
439        };
440
441        let mut r = Self {
442            value: ExprType::Unknown,
443            ctx: ctx,
444            lineno: ob.lineno(),
445            col_offset: ob.col_offset(),
446            end_lineno: ob.end_lineno(),
447            end_col_offset: ob.end_col_offset(),
448        };
449
450        let expr_type = ob_value.get_type().name().expect(
451            ob.error_message(
452                "<unknown>",
453                format!("extracting type name {:?} in expression", ob_value),
454            )
455            .as_str(),
456        );
457        log::debug!(
458            "expression type: {}, value: {}",
459            expr_type,
460            dump(&ob_value, None)?
461        );
462        match expr_type.extract::<String>()?.as_str() {
463            "Atribute" => {
464                let a = ob_value.extract().expect(
465                    ob.error_message(
466                        "<unknown>",
467                        format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
468                    )
469                    .as_str(),
470                );
471                r.value = ExprType::Attribute(a);
472                Ok(r)
473            }
474            "Await" => {
475                let a = ob_value.extract().expect(
476                    ob.error_message(
477                        "<unknown>",
478                        format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
479                    )
480                    .as_str(),
481                );
482                r.value = ExprType::Await(a);
483                Ok(r)
484            }
485            "BinOp" => {
486                let c = ob_value.extract().expect(
487                    ob.error_message(
488                        "<unknown>",
489                        format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
490                    )
491                    .as_str(),
492                );
493                r.value = ExprType::BinOp(c);
494                Ok(r)
495            }
496            "BoolOp" => {
497                let c = ob_value.extract().expect(
498                    ob.error_message(
499                        "<unknown>",
500                        format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
501                    )
502                    .as_str(),
503                );
504                r.value = ExprType::BoolOp(c);
505                Ok(r)
506            }
507            "Call" => {
508                let et = ob_value.extract().expect(
509                    ob.error_message(
510                        "<unknown>",
511                        format!("parsing Call expression {:?}", ob_value),
512                    )
513                    .as_str(),
514                );
515                r.value = ExprType::Call(et);
516                Ok(r)
517            }
518            "Constant" => {
519                let c = ob_value.extract().expect(
520                    ob.error_message(
521                        "<unknown>",
522                        format!(
523                            "extracting Constant in expression {:?}",
524                            dump(&ob_value, None)?
525                        ),
526                    )
527                    .as_str(),
528                );
529                r.value = ExprType::Constant(c);
530                Ok(r)
531            }
532            "Compare" => {
533                let c = ob_value.extract().expect(
534                    ob.error_message(
535                        "<unknown>",
536                        format!(
537                            "extracting Compare in expression {:?}",
538                            dump(&ob_value, None)?
539                        ),
540                    )
541                    .as_str(),
542                );
543                r.value = ExprType::Compare(c);
544                Ok(r)
545            }
546            "List" => {
547                // Extract the list elements using the 'elts' attribute
548                let elts_attr = ob_value.getattr("elts")
549                    .expect("getting elts attribute from List");
550                let elts_vec: Vec<Bound<PyAny>> = elts_attr.extract()
551                    .expect("extracting elts as Vec<Bound<PyAny>> from List");
552                
553                // Convert each element to ExprType
554                let mut expr_list = Vec::new();
555                for elt in elts_vec {
556                    let expr: ExprType = elt.extract()
557                        .expect(&format!("extracting list element {}", dump(&elt, None).unwrap_or_else(|_| "unknown".to_string())));
558                    expr_list.push(expr);
559                }
560                
561                r.value = ExprType::List(expr_list);
562                Ok(r)
563            }
564            "Name" => {
565                let name = ob_value.extract().expect(
566                    ob.error_message(
567                        "<unknown>",
568                        format!("parsing Call expression {:?}", ob_value),
569                    )
570                    .as_str(),
571                );
572                r.value = ExprType::Name(name);
573                Ok(r)
574            }
575            "UnaryOp" => {
576                let c = ob_value.extract().expect(
577                    ob.error_message(
578                        "<unknown>",
579                        format!(
580                            "extracting UnaryOp in expression {:?}",
581                            dump(&ob_value, None)?
582                        ),
583                    )
584                    .as_str(),
585                );
586                r.value = ExprType::UnaryOp(c);
587                Ok(r)
588            }
589            "Lambda" => {
590                let l = ob_value.extract().expect(
591                    ob.error_message(
592                        "<unknown>",
593                        format!(
594                            "extracting Lambda in expression {:?}",
595                            dump(&ob_value, None)?
596                        ),
597                    )
598                    .as_str(),
599                );
600                r.value = ExprType::Lambda(l);
601                Ok(r)
602            }
603            "IfExp" => {
604                let i = ob_value.extract().expect(
605                    ob.error_message(
606                        "<unknown>",
607                        format!(
608                            "extracting IfExp in expression {:?}",
609                            dump(&ob_value, None)?
610                        ),
611                    )
612                    .as_str(),
613                );
614                r.value = ExprType::IfExp(i);
615                Ok(r)
616            }
617            "Dict" => {
618                let d = ob_value.extract().expect(
619                    ob.error_message(
620                        "<unknown>",
621                        format!(
622                            "extracting Dict in expression {:?}",
623                            dump(&ob_value, None)?
624                        ),
625                    )
626                    .as_str(),
627                );
628                r.value = ExprType::Dict(d);
629                Ok(r)
630            }
631            "Set" => {
632                let s = ob_value.extract().expect(
633                    ob.error_message(
634                        "<unknown>",
635                        format!(
636                            "extracting Set in expression {:?}",
637                            dump(&ob_value, None)?
638                        ),
639                    )
640                    .as_str(),
641                );
642                r.value = ExprType::Set(s);
643                Ok(r)
644            }
645            "Tuple" => {
646                let t = ob_value.extract().expect(
647                    ob.error_message(
648                        "<unknown>",
649                        format!(
650                            "extracting Tuple in expression {:?}",
651                            dump(&ob_value, None)?
652                        ),
653                    )
654                    .as_str(),
655                );
656                r.value = ExprType::Tuple(t);
657                Ok(r)
658            }
659            "Subscript" => {
660                let s = ob_value.extract().expect(
661                    ob.error_message(
662                        "<unknown>",
663                        format!(
664                            "extracting Subscript in expression {:?}",
665                            dump(&ob_value, None)?
666                        ),
667                    )
668                    .as_str(),
669                );
670                r.value = ExprType::Subscript(s);
671                Ok(r)
672            }
673            "Yield" => {
674                let y = ob_value.extract().expect(
675                    ob.error_message(
676                        "<unknown>",
677                        format!(
678                            "extracting Yield in expression {:?}",
679                            dump(&ob_value, None)?
680                        ),
681                    )
682                    .as_str(),
683                );
684                r.value = ExprType::Yield(y);
685                Ok(r)
686            }
687            "YieldFrom" => {
688                let yf = ob_value.extract().expect(
689                    ob.error_message(
690                        "<unknown>",
691                        format!(
692                            "extracting YieldFrom in expression {:?}",
693                            dump(&ob_value, None)?
694                        ),
695                    )
696                    .as_str(),
697                );
698                r.value = ExprType::YieldFrom(yf);
699                Ok(r)
700            }
701            "JoinedStr" => {
702                let js = ob_value.extract().expect(
703                    ob.error_message(
704                        "<unknown>",
705                        format!(
706                            "extracting JoinedStr in expression {:?}",
707                            dump(&ob_value, None)?
708                        ),
709                    )
710                    .as_str(),
711                );
712                r.value = ExprType::JoinedStr(js);
713                Ok(r)
714            }
715            "FormattedValue" => {
716                let fv = ob_value.extract().expect(
717                    ob.error_message(
718                        "<unknown>",
719                        format!(
720                            "extracting FormattedValue in expression {:?}",
721                            dump(&ob_value, None)?
722                        ),
723                    )
724                    .as_str(),
725                );
726                r.value = ExprType::FormattedValue(fv);
727                Ok(r)
728            }
729            "GeneratorExp" => {
730                let ge = ob_value.extract().expect(
731                    ob.error_message(
732                        "<unknown>",
733                        format!(
734                            "extracting GeneratorExp in expression {:?}",
735                            dump(&ob_value, None)?
736                        ),
737                    )
738                    .as_str(),
739                );
740                r.value = ExprType::GeneratorExp(ge);
741                Ok(r)
742            }
743            // In sitations where an expression is optional, we may see a NoneType expressions.
744            "NoneType" => {
745                r.value = ExprType::NoneType(Constant(None));
746                Ok(r)
747            }
748            _ => {
749                let err_msg = format!(
750                    "Unimplemented expression type {}, {}",
751                    expr_type,
752                    dump(ob, None)?
753                );
754                Err(pyo3::exceptions::PyValueError::new_err(
755                    ob.error_message("<unknown>", err_msg.as_str()),
756                ))
757            }
758        }
759    }
760}
761
762impl CodeGen for Expr {
763    type Context = CodeGenContext;
764    type Options = PythonOptions;
765    type SymbolTable = SymbolTableScopes;
766
767    fn to_rust(
768        self,
769        ctx: Self::Context,
770        options: Self::Options,
771        symbols: Self::SymbolTable,
772    ) -> std::result::Result<TokenStream, Box<dyn std::error::Error>> {
773        let _module_name = match ctx.clone() {
774            CodeGenContext::Module(name) => name,
775            _ => "unknown".to_string(),
776        };
777
778        match self.value.clone() {
779            ExprType::Await(a) => a.to_rust(ctx.clone(), options, symbols),
780            ExprType::BinOp(binop) => binop.to_rust(ctx.clone(), options, symbols),
781            ExprType::BoolOp(boolop) => boolop.to_rust(ctx.clone(), options, symbols),
782            ExprType::Call(call) => call.to_rust(ctx.clone(), options, symbols),
783            ExprType::Constant(constant) => constant.to_rust(ctx, options, symbols),
784            ExprType::Compare(compare) => compare.to_rust(ctx, options, symbols),
785            ExprType::Lambda(l) => l.to_rust(ctx, options, symbols),
786            ExprType::IfExp(i) => i.to_rust(ctx, options, symbols),
787            ExprType::Dict(d) => d.to_rust(ctx, options, symbols),
788            ExprType::Set(s) => s.to_rust(ctx, options, symbols),
789            ExprType::GeneratorExp(ge) => ge.to_rust(ctx, options, symbols),
790            ExprType::Tuple(t) => t.to_rust(ctx, options, symbols),
791            ExprType::Subscript(s) => s.to_rust(ctx, options, symbols),
792            ExprType::UnaryOp(operand) => operand.to_rust(ctx, options, symbols),
793            ExprType::Name(name) => name.to_rust(ctx, options, symbols),
794            ExprType::Yield(y) => y.to_rust(ctx, options, symbols),
795            ExprType::YieldFrom(yf) => yf.to_rust(ctx, options, symbols),
796            ExprType::JoinedStr(js) => js.to_rust(ctx, options, symbols),
797            ExprType::FormattedValue(fv) => fv.to_rust(ctx, options, symbols),
798            // NoneType expressions generate no code.
799            ExprType::NoneType(_c) => Ok(quote!()),
800            _ => {
801                let error = Error::ExprTypeNotYetImplemented(self.value);
802                Err(error.into())
803            }
804        }
805    }
806}
807
808impl Node for Expr {
809    fn lineno(&self) -> Option<usize> {
810        self.lineno
811    }
812
813    fn col_offset(&self) -> Option<usize> {
814        self.col_offset
815    }
816
817    fn end_lineno(&self) -> Option<usize> {
818        self.end_lineno
819    }
820
821    fn end_col_offset(&self) -> Option<usize> {
822        self.end_col_offset
823    }
824}
825
826#[cfg(test)]
827mod tests {
828    use super::*;
829
830    #[test]
831    fn check_call_expression() {
832        let expression = crate::parse("test()", "test.py").unwrap();
833        println!("Python tree: {:#?}", expression);
834        let mut options = PythonOptions::default();
835        options.with_std_python = false;
836        let symbols = SymbolTableScopes::new();
837        let tokens = expression
838            .clone()
839            .to_rust(CodeGenContext::Module("test".to_string()), options, symbols)
840            .unwrap();
841        println!("Rust tokens: {}", tokens.to_string());
842        assert_eq!(tokens.to_string(), quote!(test()).to_string());
843    }
844}