python_ast/ast/tree/
import.rs

1use log::debug;
2use proc_macro2::TokenStream;
3use pyo3::FromPyObject;
4use quote::{format_ident, quote};
5use serde::{Deserialize, Serialize};
6
7use crate::{CodeGen, CodeGenContext, PythonOptions, SymbolTableNode, SymbolTableScopes};
8
9#[derive(Clone, Debug, FromPyObject, Serialize, Deserialize, PartialEq)]
10pub struct Alias {
11    pub name: String,
12    pub asname: Option<String>,
13}
14
15#[derive(Clone, Debug, FromPyObject, Serialize, Deserialize, PartialEq)]
16pub struct Import {
17    pub names: Vec<Alias>,
18}
19
20/// An Import (or FromImport) statement causes 2 things to occur:
21/// 1. Declares the imported object within the existing scope.
22/// 2. Causes the referenced module to be compiled into the program (only once).
23
24impl CodeGen for Import {
25    type Context = CodeGenContext;
26    type Options = PythonOptions;
27    type SymbolTable = SymbolTableScopes;
28
29    fn find_symbols(self, symbols: Self::SymbolTable) -> Self::SymbolTable {
30        let mut symbols = symbols;
31        for alias in self.names.iter() {
32            symbols.insert(alias.name.clone(), SymbolTableNode::Import(self.clone()));
33            if let Some(a) = alias.asname.clone() {
34                symbols.insert(a, SymbolTableNode::Alias(alias.name.clone()))
35            }
36        }
37        symbols
38    }
39
40    fn to_rust(
41        self,
42        ctx: Self::Context,
43        options: Self::Options,
44        _symbols: Self::SymbolTable,
45    ) -> Result<TokenStream, Box<dyn std::error::Error>> {
46        let mut tokens = TokenStream::new();
47        for alias in self.names.iter() {
48            let names = format_ident!("{}", alias.name.replace(".", "::"));
49            let code = match &alias.asname {
50                None => {
51                    //options.clone().import(names, name);
52                    quote! {use #names;}
53                }
54                Some(n) => {
55                    //options.clone().import(&full_mod_name, &String::from(n));
56
57                    let name = format_ident!("{}", n);
58                    quote! {use #names as #name;}
59                }
60            };
61            tokens.extend(code);
62        }
63        debug!("context: {:?}", ctx);
64        debug!("options: {:?}", options);
65        debug!("tokens: {}", tokens);
66        Ok(tokens)
67    }
68}
69
70#[derive(Clone, Debug, FromPyObject, Serialize, Deserialize, PartialEq)]
71pub struct ImportFrom {
72    pub module: String,
73    pub names: Vec<Alias>,
74    pub level: usize,
75}
76
77impl CodeGen for ImportFrom {
78    type Context = CodeGenContext;
79    type Options = PythonOptions;
80    type SymbolTable = SymbolTableScopes;
81
82    fn find_symbols(self, symbols: Self::SymbolTable) -> Self::SymbolTable {
83        let mut symbols = symbols;
84        for alias in self.names.iter() {
85            symbols.insert(
86                alias.name.clone(),
87                SymbolTableNode::ImportFrom(self.clone()),
88            );
89        }
90        symbols
91    }
92
93    fn to_rust(
94        self,
95        ctx: Self::Context,
96        _options: Self::Options,
97        _symbols: Self::SymbolTable,
98    ) -> Result<TokenStream, Box<dyn std::error::Error>> {
99        debug!("ctx: {:?}", ctx);
100        Ok(quote! {})
101    }
102}