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::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#[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 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 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 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 "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 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}