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#[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 Attribute(Attribute),
55 Subscript(Subscript),
56 Starred(Starred),
57 Name(Name),
58 List(Vec<ExprType>),
59 Tuple(Tuple),
60 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 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 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 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::BoolOp(boolop) => boolop.to_rust(ctx, options, symbols),
372 ExprType::Call(call) => call.to_rust(ctx, options, symbols),
373 ExprType::Compare(c) => c.to_rust(ctx, options, symbols),
374 ExprType::Constant(c) => c.to_rust(ctx, options, symbols),
375 ExprType::Lambda(l) => l.to_rust(ctx, options, symbols),
376 ExprType::IfExp(i) => i.to_rust(ctx, options, symbols),
377 ExprType::Dict(d) => d.to_rust(ctx, options, symbols),
378 ExprType::Set(s) => s.to_rust(ctx, options, symbols),
379 ExprType::ListComp(lc) => lc.to_rust(ctx, options, symbols),
380 ExprType::DictComp(dc) => dc.to_rust(ctx, options, symbols),
381 ExprType::SetComp(sc) => sc.to_rust(ctx, options, symbols),
382 ExprType::GeneratorExp(ge) => ge.to_rust(ctx, options, symbols),
383 ExprType::Tuple(t) => t.to_rust(ctx, options, symbols),
384 ExprType::Subscript(s) => s.to_rust(ctx, options, symbols),
385 ExprType::Starred(s) => s.to_rust(ctx, options, symbols),
386 ExprType::Yield(y) => y.to_rust(ctx, options, symbols),
387 ExprType::YieldFrom(yf) => yf.to_rust(ctx, options, symbols),
388 ExprType::JoinedStr(js) => js.to_rust(ctx, options, symbols),
389 ExprType::FormattedValue(fv) => fv.to_rust(ctx, options, symbols),
390 ExprType::List(l) => {
391 let mut elements = Vec::new();
392 let mut has_starred = false;
393
394 for li in l {
395 let code = li
396 .clone()
397 .to_rust(ctx.clone(), options.clone(), symbols.clone())
398 .expect(format!("Extracting list item {:?}", li).as_str());
399
400 if matches!(li, ExprType::Starred(_)) {
402 has_starred = true;
403 let code_str = code.to_string();
404 if code_str.contains("sys :: argv") {
406 elements.push(quote! { __STARRED_ARGV_MARKER__ });
408 } else {
409 elements.push(code);
410 }
411 } else {
412 elements.push(code);
413 }
414 }
415
416 if has_starred {
418 let mut final_elements = Vec::new();
419 let mut has_argv_starred = false;
420
421 for element in elements {
422 let elem_str = element.to_string();
423 if elem_str.contains("__STARRED_ARGV_MARKER__") {
424 has_argv_starred = true;
425 continue; } else {
427 final_elements.push(element);
428 }
429 }
430
431 if has_argv_starred {
433 if final_elements.is_empty() {
434 Ok(quote! {
436 (*sys::argv).clone()
437 })
438 } else {
439 Ok(quote! {
442 {
443 let mut vec = Vec::new();
444 #(vec.push((#final_elements).clone().to_string());)*
445 vec.extend((*sys::argv).iter().cloned());
446 vec
447 }
448 })
449 }
450 } else {
451 Ok(quote! {
453 vec![#(#final_elements.to_string()),*]
454 })
455 }
456 } else {
457 Ok(quote! {
461 vec![#((#elements).clone().to_string()),*]
462 })
463 }
464 }
465 ExprType::Name(name) => name.to_rust(ctx, options, symbols),
466 ExprType::NoneType(c) => c.to_rust(ctx, options, symbols),
467 ExprType::UnaryOp(operand) => operand.to_rust(ctx, options, symbols),
468
469 _ => {
470 let error = Error::ExprTypeNotYetImplemented(self);
471 Err(error.into())
472 }
473 }
474 }
475}
476
477#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
480pub struct Expr {
481 pub value: ExprType,
482 pub ctx: Option<String>,
483 pub lineno: Option<usize>,
484 pub col_offset: Option<usize>,
485 pub end_lineno: Option<usize>,
486 pub end_col_offset: Option<usize>,
487}
488
489impl<'a> FromPyObject<'a> for Expr {
490 fn extract_bound(ob: &Bound<'_, PyAny>) -> PyResult<Self> {
491 let err_msg = format!("extracting object value {} in expression", dump(ob, None)?);
492
493 let ob_value = ob
494 .getattr("value")
495 .expect(ob.error_message("<unknown>", err_msg.as_str()).as_str());
496 log::debug!("ob_value: {}", dump(&ob_value, None)?);
497
498 let ctx: Option<String> = if let Ok(pyany) = ob_value.getattr("ctx") {
500 pyany.get_type().extract().unwrap_or_default()
501 } else {
502 None
503 };
504
505 let mut r = Self {
506 value: ExprType::Unknown,
507 ctx: ctx,
508 lineno: ob.lineno(),
509 col_offset: ob.col_offset(),
510 end_lineno: ob.end_lineno(),
511 end_col_offset: ob.end_col_offset(),
512 };
513
514 let expr_type = ob_value.get_type().name().expect(
515 ob.error_message(
516 "<unknown>",
517 format!("extracting type name {:?} in expression", ob_value),
518 )
519 .as_str(),
520 );
521 log::debug!(
522 "expression type: {}, value: {}",
523 expr_type,
524 dump(&ob_value, None)?
525 );
526 match expr_type.extract::<String>()?.as_str() {
527 "Atribute" => {
528 let a = ob_value.extract().expect(
529 ob.error_message(
530 "<unknown>",
531 format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
532 )
533 .as_str(),
534 );
535 r.value = ExprType::Attribute(a);
536 Ok(r)
537 }
538 "Await" => {
539 let a = ob_value.extract().expect(
540 ob.error_message(
541 "<unknown>",
542 format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
543 )
544 .as_str(),
545 );
546 r.value = ExprType::Await(a);
547 Ok(r)
548 }
549 "BinOp" => {
550 let c = ob_value.extract().expect(
551 ob.error_message(
552 "<unknown>",
553 format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
554 )
555 .as_str(),
556 );
557 r.value = ExprType::BinOp(c);
558 Ok(r)
559 }
560 "BoolOp" => {
561 let c = ob_value.extract().expect(
562 ob.error_message(
563 "<unknown>",
564 format!("extracting BinOp in expression {:?}", dump(&ob_value, None)?),
565 )
566 .as_str(),
567 );
568 r.value = ExprType::BoolOp(c);
569 Ok(r)
570 }
571 "Call" => {
572 let et = ob_value.extract().expect(
573 ob.error_message(
574 "<unknown>",
575 format!("parsing Call expression {:?}", ob_value),
576 )
577 .as_str(),
578 );
579 r.value = ExprType::Call(et);
580 Ok(r)
581 }
582 "Constant" => {
583 let c = ob_value.extract().expect(
584 ob.error_message(
585 "<unknown>",
586 format!(
587 "extracting Constant in expression {:?}",
588 dump(&ob_value, None)?
589 ),
590 )
591 .as_str(),
592 );
593 r.value = ExprType::Constant(c);
594 Ok(r)
595 }
596 "Compare" => {
597 let c = ob_value.extract().expect(
598 ob.error_message(
599 "<unknown>",
600 format!(
601 "extracting Compare in expression {:?}",
602 dump(&ob_value, None)?
603 ),
604 )
605 .as_str(),
606 );
607 r.value = ExprType::Compare(c);
608 Ok(r)
609 }
610 "List" => {
611 let elts_attr = ob_value.getattr("elts")
613 .expect("getting elts attribute from List");
614 let elts_vec: Vec<Bound<PyAny>> = elts_attr.extract()
615 .expect("extracting elts as Vec<Bound<PyAny>> from List");
616
617 let mut expr_list = Vec::new();
619 for elt in elts_vec {
620 let expr: ExprType = elt.extract()
621 .expect(&format!("extracting list element {}", dump(&elt, None).unwrap_or_else(|_| "unknown".to_string())));
622 expr_list.push(expr);
623 }
624
625 r.value = ExprType::List(expr_list);
626 Ok(r)
627 }
628 "Name" => {
629 let name = ob_value.extract().expect(
630 ob.error_message(
631 "<unknown>",
632 format!("parsing Call expression {:?}", ob_value),
633 )
634 .as_str(),
635 );
636 r.value = ExprType::Name(name);
637 Ok(r)
638 }
639 "UnaryOp" => {
640 let c = ob_value.extract().expect(
641 ob.error_message(
642 "<unknown>",
643 format!(
644 "extracting UnaryOp in expression {:?}",
645 dump(&ob_value, None)?
646 ),
647 )
648 .as_str(),
649 );
650 r.value = ExprType::UnaryOp(c);
651 Ok(r)
652 }
653 "Lambda" => {
654 let l = ob_value.extract().expect(
655 ob.error_message(
656 "<unknown>",
657 format!(
658 "extracting Lambda in expression {:?}",
659 dump(&ob_value, None)?
660 ),
661 )
662 .as_str(),
663 );
664 r.value = ExprType::Lambda(l);
665 Ok(r)
666 }
667 "IfExp" => {
668 let i = ob_value.extract().expect(
669 ob.error_message(
670 "<unknown>",
671 format!(
672 "extracting IfExp in expression {:?}",
673 dump(&ob_value, None)?
674 ),
675 )
676 .as_str(),
677 );
678 r.value = ExprType::IfExp(i);
679 Ok(r)
680 }
681 "Dict" => {
682 let d = ob_value.extract().expect(
683 ob.error_message(
684 "<unknown>",
685 format!(
686 "extracting Dict in expression {:?}",
687 dump(&ob_value, None)?
688 ),
689 )
690 .as_str(),
691 );
692 r.value = ExprType::Dict(d);
693 Ok(r)
694 }
695 "Set" => {
696 let s = ob_value.extract().expect(
697 ob.error_message(
698 "<unknown>",
699 format!(
700 "extracting Set in expression {:?}",
701 dump(&ob_value, None)?
702 ),
703 )
704 .as_str(),
705 );
706 r.value = ExprType::Set(s);
707 Ok(r)
708 }
709 "Tuple" => {
710 let t = ob_value.extract().expect(
711 ob.error_message(
712 "<unknown>",
713 format!(
714 "extracting Tuple in expression {:?}",
715 dump(&ob_value, None)?
716 ),
717 )
718 .as_str(),
719 );
720 r.value = ExprType::Tuple(t);
721 Ok(r)
722 }
723 "Subscript" => {
724 let s = ob_value.extract().expect(
725 ob.error_message(
726 "<unknown>",
727 format!(
728 "extracting Subscript in expression {:?}",
729 dump(&ob_value, None)?
730 ),
731 )
732 .as_str(),
733 );
734 r.value = ExprType::Subscript(s);
735 Ok(r)
736 }
737 "Yield" => {
738 let y = ob_value.extract().expect(
739 ob.error_message(
740 "<unknown>",
741 format!(
742 "extracting Yield in expression {:?}",
743 dump(&ob_value, None)?
744 ),
745 )
746 .as_str(),
747 );
748 r.value = ExprType::Yield(y);
749 Ok(r)
750 }
751 "YieldFrom" => {
752 let yf = ob_value.extract().expect(
753 ob.error_message(
754 "<unknown>",
755 format!(
756 "extracting YieldFrom in expression {:?}",
757 dump(&ob_value, None)?
758 ),
759 )
760 .as_str(),
761 );
762 r.value = ExprType::YieldFrom(yf);
763 Ok(r)
764 }
765 "JoinedStr" => {
766 let js = ob_value.extract().expect(
767 ob.error_message(
768 "<unknown>",
769 format!(
770 "extracting JoinedStr in expression {:?}",
771 dump(&ob_value, None)?
772 ),
773 )
774 .as_str(),
775 );
776 r.value = ExprType::JoinedStr(js);
777 Ok(r)
778 }
779 "FormattedValue" => {
780 let fv = ob_value.extract().expect(
781 ob.error_message(
782 "<unknown>",
783 format!(
784 "extracting FormattedValue in expression {:?}",
785 dump(&ob_value, None)?
786 ),
787 )
788 .as_str(),
789 );
790 r.value = ExprType::FormattedValue(fv);
791 Ok(r)
792 }
793 "GeneratorExp" => {
794 let ge = ob_value.extract().expect(
795 ob.error_message(
796 "<unknown>",
797 format!(
798 "extracting GeneratorExp in expression {:?}",
799 dump(&ob_value, None)?
800 ),
801 )
802 .as_str(),
803 );
804 r.value = ExprType::GeneratorExp(ge);
805 Ok(r)
806 }
807 "NoneType" => {
809 r.value = ExprType::NoneType(Constant(None));
810 Ok(r)
811 }
812 _ => {
813 let err_msg = format!(
814 "Unimplemented expression type {}, {}",
815 expr_type,
816 dump(ob, None)?
817 );
818 Err(pyo3::exceptions::PyValueError::new_err(
819 ob.error_message("<unknown>", err_msg.as_str()),
820 ))
821 }
822 }
823 }
824}
825
826impl CodeGen for Expr {
827 type Context = CodeGenContext;
828 type Options = PythonOptions;
829 type SymbolTable = SymbolTableScopes;
830
831 fn to_rust(
832 self,
833 ctx: Self::Context,
834 options: Self::Options,
835 symbols: Self::SymbolTable,
836 ) -> std::result::Result<TokenStream, Box<dyn std::error::Error>> {
837 let _module_name = match ctx.clone() {
838 CodeGenContext::Module(name) => name,
839 _ => "unknown".to_string(),
840 };
841
842 match self.value.clone() {
843 ExprType::Await(a) => a.to_rust(ctx.clone(), options, symbols),
844 ExprType::BinOp(binop) => binop.to_rust(ctx.clone(), options, symbols),
845 ExprType::BoolOp(boolop) => boolop.to_rust(ctx.clone(), options, symbols),
846 ExprType::Call(call) => call.to_rust(ctx.clone(), options, symbols),
847 ExprType::Constant(constant) => constant.to_rust(ctx, options, symbols),
848 ExprType::Compare(compare) => compare.to_rust(ctx, options, symbols),
849 ExprType::Lambda(l) => l.to_rust(ctx, options, symbols),
850 ExprType::IfExp(i) => i.to_rust(ctx, options, symbols),
851 ExprType::Dict(d) => d.to_rust(ctx, options, symbols),
852 ExprType::Set(s) => s.to_rust(ctx, options, symbols),
853 ExprType::GeneratorExp(ge) => ge.to_rust(ctx, options, symbols),
854 ExprType::Tuple(t) => t.to_rust(ctx, options, symbols),
855 ExprType::Subscript(s) => s.to_rust(ctx, options, symbols),
856 ExprType::UnaryOp(operand) => operand.to_rust(ctx, options, symbols),
857 ExprType::List(l) => {
858 let expr_type = ExprType::List(l);
860 expr_type.to_rust(ctx, options, symbols)
861 }
862 ExprType::Name(name) => name.to_rust(ctx, options, symbols),
863 ExprType::Yield(y) => y.to_rust(ctx, options, symbols),
864 ExprType::YieldFrom(yf) => yf.to_rust(ctx, options, symbols),
865 ExprType::JoinedStr(js) => js.to_rust(ctx, options, symbols),
866 ExprType::FormattedValue(fv) => fv.to_rust(ctx, options, symbols),
867 ExprType::NoneType(_c) => Ok(quote!()),
869 _ => {
870 let error = Error::ExprTypeNotYetImplemented(self.value);
871 Err(error.into())
872 }
873 }
874 }
875}
876
877impl Node for Expr {
878 fn lineno(&self) -> Option<usize> {
879 self.lineno
880 }
881
882 fn col_offset(&self) -> Option<usize> {
883 self.col_offset
884 }
885
886 fn end_lineno(&self) -> Option<usize> {
887 self.end_lineno
888 }
889
890 fn end_col_offset(&self) -> Option<usize> {
891 self.end_col_offset
892 }
893}
894
895#[cfg(test)]
896mod tests {
897 use super::*;
898
899 #[test]
900 fn check_call_expression() {
901 let expression = crate::parse("test()", "test.py").unwrap();
902 let mut options = PythonOptions::default();
903 options.with_std_python = false;
904 let symbols = SymbolTableScopes::new();
905 let tokens = expression
906 .clone()
907 .to_rust(CodeGenContext::Module("test".to_string()), options, symbols)
908 .unwrap();
909 assert_eq!(tokens.to_string(), "fn __module_init__ () { test () } fn main () { __module_init__ () ; }");
910 }
911}