python_ast/ast/tree/
named_expression.rs1use proc_macro2::TokenStream;
2use pyo3::FromPyObject;
3use quote::quote;
4use serde::{Deserialize, Serialize};
5
6use crate::{CodeGen, CodeGenContext, ExprType, PythonOptions, SymbolTableScopes};
7
8#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
10pub struct NamedExpr {
11 left: Box<ExprType>,
12 right: Box<ExprType>,
13}
14
15impl<'a> FromPyObject<'a> for NamedExpr {
16 fn extract(ob: &pyo3::PyAny) -> pyo3::PyResult<Self> {
17 let left = ob.getattr("left")?.extract::<ExprType>()?;
18 let right = ob.getattr("right")?.extract::<ExprType>()?;
19 Ok(NamedExpr {
20 left: Box::new(left),
21 right: Box::new(right),
22 })
23 }
24}
25
26impl CodeGen for NamedExpr {
27 type Context = CodeGenContext;
28 type Options = PythonOptions;
29 type SymbolTable = SymbolTableScopes;
30
31 fn to_rust(
32 self,
33 ctx: Self::Context,
34 options: Self::Options,
35 symbols: Self::SymbolTable,
36 ) -> Result<TokenStream, Box<dyn std::error::Error>> {
37 let left = self
38 .left
39 .clone()
40 .to_rust(ctx.clone(), options.clone(), symbols.clone())
41 .expect(format!("parsing left side of named expression {:?}", self.left).as_str());
42 let right =
43 self.right.clone().to_rust(ctx, options, symbols).expect(
44 format!("parsing right side of named expression {:?}", self.right).as_str(),
45 );
46 Ok(quote!(#left = #right))
47 }
48}
49
50#[cfg(test)]
51mod test {
52 use super::*;
53 use crate::{Constant, ExprType, Name};
54 use litrs::*;
55
56 #[test]
57 fn test_named_expression() {
58 let named_expression = NamedExpr {
59 left: Box::new(ExprType::Name(Name {
60 id: "a".to_string(),
61 })),
62 right: Box::new(ExprType::Constant(Constant(Some(Literal::Integer(
63 IntegerLit::parse("1".to_string()).unwrap(),
64 ))))),
65 };
66 let rust = named_expression
67 .to_rust(
68 CodeGenContext::Module("test".to_string()),
69 PythonOptions::default(),
70 SymbolTableScopes::new(),
71 )
72 .unwrap();
73 assert_eq!(rust.to_string(), "a = 1");
74 }
75}