python_ast/ast/tree/
call.rs1use proc_macro2::TokenStream;
2use pyo3::{FromPyObject, PyAny, PyResult};
3use quote::quote;
4use serde::{Deserialize, Serialize};
5
6use crate::{Arg, CodeGen, CodeGenContext, ExprType, Keyword, PythonOptions, SymbolTableScopes};
7
8#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
9pub struct Call {
10 pub func: Box<ExprType>,
11 pub args: Vec<Arg>,
12 pub keywords: Vec<Keyword>,
13}
14
15impl<'a> FromPyObject<'a> for Call {
16 fn extract(ob: &'a PyAny) -> PyResult<Self> {
17 let func = ob.getattr("func").expect("Call.func");
18 let args = ob.getattr("args").expect("Call.args");
19 let keywords = ob.getattr("keywords").expect("Call.keywords");
20 Ok(Call {
21 func: Box::new(func.extract().expect("Call.func")),
22 args: args.extract().expect("Call.args"),
23 keywords: keywords.extract().expect("Call.keywords"),
24 })
25 }
26}
27
28impl<'a> CodeGen for Call {
29 type Context = CodeGenContext;
30 type Options = PythonOptions;
31 type SymbolTable = SymbolTableScopes;
32
33 fn to_rust(
34 self,
35 ctx: Self::Context,
36 options: Self::Options,
37 symbols: Self::SymbolTable,
38 ) -> Result<TokenStream, Box<dyn std::error::Error>> {
39 let name = self
40 .func
41 .to_rust(ctx.clone(), options.clone(), symbols.clone())
42 .expect("Call.func");
43 let mut args = TokenStream::new();
47 for arg in self.args {
48 let arg = arg
49 .clone()
50 .to_rust(ctx.clone(), options.clone(), symbols.clone())
51 .expect(format!("Call.args {:?}", arg).as_str());
52 args.extend(arg);
53 args.extend(quote!(,));
54 }
55 Ok(quote!(#name(#args)))
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_lookup_of_function() {
65 let options = PythonOptions::default();
66 let result = crate::parse(
67 "def foo(a = 7):
68 pass
69
70foo(b=9)",
71 "test.py",
72 )
73 .unwrap();
74 println!("Python tree: {:#?}", result);
75 let code = result
76 .to_rust(
77 CodeGenContext::Module("test".to_string()),
78 options,
79 SymbolTableScopes::new(),
80 )
81 .unwrap();
82 println!("Rust code: {}", code);
83 }
84}