python_ast/ast/tree/
yield_expr.rs1use proc_macro2::TokenStream;
2use pyo3::{Bound, FromPyObject, PyAny, PyResult, prelude::PyAnyMethods};
3use quote::quote;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 CodeGen, CodeGenContext, ExprType, Node, PythonOptions, SymbolTableScopes,
8};
9
10#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
12pub struct Yield {
13 pub value: Option<Box<ExprType>>,
15 pub lineno: Option<usize>,
17 pub col_offset: Option<usize>,
18 pub end_lineno: Option<usize>,
19 pub end_col_offset: Option<usize>,
20}
21
22#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
24pub struct YieldFrom {
25 pub value: Box<ExprType>,
27 pub lineno: Option<usize>,
29 pub col_offset: Option<usize>,
30 pub end_lineno: Option<usize>,
31 pub end_col_offset: Option<usize>,
32}
33
34impl<'a> FromPyObject<'a> for Yield {
35 fn extract_bound(ob: &Bound<'a, PyAny>) -> PyResult<Self> {
36 let value: Option<Box<ExprType>> = if let Ok(value_attr) = ob.getattr("value") {
38 if value_attr.is_none() {
39 None
40 } else {
41 Some(Box::new(value_attr.extract()?))
42 }
43 } else {
44 None
45 };
46
47 Ok(Yield {
48 value,
49 lineno: ob.lineno(),
50 col_offset: ob.col_offset(),
51 end_lineno: ob.end_lineno(),
52 end_col_offset: ob.end_col_offset(),
53 })
54 }
55}
56
57impl<'a> FromPyObject<'a> for YieldFrom {
58 fn extract_bound(ob: &Bound<'a, PyAny>) -> PyResult<Self> {
59 let value: ExprType = ob.getattr("value")?.extract()?;
61
62 Ok(YieldFrom {
63 value: Box::new(value),
64 lineno: ob.lineno(),
65 col_offset: ob.col_offset(),
66 end_lineno: ob.end_lineno(),
67 end_col_offset: ob.end_col_offset(),
68 })
69 }
70}
71
72impl Node for Yield {
73 fn lineno(&self) -> Option<usize> { self.lineno }
74 fn col_offset(&self) -> Option<usize> { self.col_offset }
75 fn end_lineno(&self) -> Option<usize> { self.end_lineno }
76 fn end_col_offset(&self) -> Option<usize> { self.end_col_offset }
77}
78
79impl Node for YieldFrom {
80 fn lineno(&self) -> Option<usize> { self.lineno }
81 fn col_offset(&self) -> Option<usize> { self.col_offset }
82 fn end_lineno(&self) -> Option<usize> { self.end_lineno }
83 fn end_col_offset(&self) -> Option<usize> { self.end_col_offset }
84}
85
86impl CodeGen for Yield {
87 type Context = CodeGenContext;
88 type Options = PythonOptions;
89 type SymbolTable = SymbolTableScopes;
90
91 fn find_symbols(self, symbols: Self::SymbolTable) -> Self::SymbolTable {
92 if let Some(value) = self.value {
93 (*value).find_symbols(symbols)
94 } else {
95 symbols
96 }
97 }
98
99 fn to_rust(
100 self,
101 ctx: Self::Context,
102 options: Self::Options,
103 symbols: Self::SymbolTable,
104 ) -> Result<TokenStream, Box<dyn std::error::Error>> {
105 if let Some(value) = self.value {
106 let value_tokens = (*value).to_rust(ctx, options, symbols)?;
107 Ok(quote! {
110 #value_tokens
113 })
114 } else {
115 Ok(quote! {
116 ()
118 })
119 }
120 }
121}
122
123impl CodeGen for YieldFrom {
124 type Context = CodeGenContext;
125 type Options = PythonOptions;
126 type SymbolTable = SymbolTableScopes;
127
128 fn find_symbols(self, symbols: Self::SymbolTable) -> Self::SymbolTable {
129 (*self.value).find_symbols(symbols)
130 }
131
132 fn to_rust(
133 self,
134 ctx: Self::Context,
135 options: Self::Options,
136 symbols: Self::SymbolTable,
137 ) -> Result<TokenStream, Box<dyn std::error::Error>> {
138 let value_tokens = (*self.value).to_rust(ctx, options, symbols)?;
139 Ok(quote! {
141 #value_tokens
143 })
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 }