This repository was archived by the owner on Jul 27, 2023. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathwrapper.rs
More file actions
141 lines (123 loc) · 3.79 KB
/
Copy pathwrapper.rs
File metadata and controls
141 lines (123 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::PyNode;
use num_complex::Complex64;
use pyo3::prelude::*;
use pyo3::types::{PyBytes, PyList, PyTuple};
use rustpython_ast::{
self as ast, source_code::SourceRange, text_size::TextRange, ConversionFlag, Node,
};
pub trait ToPyWrapper {
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>>;
}
impl<T: ToPyWrapper> ToPyWrapper for Box<T> {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
(**self).to_py_wrapper(py)
}
}
impl<T: ToPyWrapper> ToPyWrapper for Option<T> {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
match self {
Some(ast) => ast.to_py_wrapper(py),
None => Ok(py.None()),
}
}
}
impl ToPyWrapper for ast::Identifier {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
Ok(self.as_str().to_object(py))
}
}
impl ToPyWrapper for ast::String {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
Ok(self.as_str().to_object(py))
}
}
impl ToPyWrapper for ast::Int {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
Ok((self.to_u32()).to_object(py))
}
}
impl ToPyWrapper for bool {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
Ok((*self as u32).to_object(py))
}
}
impl ToPyWrapper for ConversionFlag {
#[inline]
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
Ok((*self as i8).to_object(py))
}
}
impl ToPyWrapper for ast::Constant {
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
let value = match self {
ast::Constant::None => py.None(),
ast::Constant::Bool(bool) => bool.to_object(py),
ast::Constant::Str(string) => string.to_object(py),
ast::Constant::Bytes(bytes) => PyBytes::new(py, bytes).into(),
ast::Constant::Int(int) => int.to_object(py),
ast::Constant::Tuple(elts) => {
let elts: PyResult<Vec<_>> = elts.iter().map(|c| c.to_py_wrapper(py)).collect();
PyTuple::new(py, elts?).into()
}
ast::Constant::Float(f64) => f64.to_object(py),
ast::Constant::Complex { real, imag } => Complex64::new(*real, *imag).to_object(py),
ast::Constant::Ellipsis => py.Ellipsis(),
};
Ok(value)
}
}
impl<T: ToPyWrapper> ToPyWrapper for Vec<T> {
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
let list = PyList::empty(py);
for item in self {
let py_item = item.to_py_wrapper(py)?;
list.append(py_item)?;
}
Ok(list.into())
}
}
#[pyclass(module = "rustpython_ast", name = "AST", subclass)]
pub struct Ast;
#[pymethods]
impl Ast {
#[new]
fn new() -> Self {
Self
}
}
pub mod located {
pub use super::Ast;
use super::*;
include!("gen/wrapper_located.rs");
}
pub mod ranged {
pub use super::Ast;
use super::*;
include!("gen/wrapper_ranged.rs");
}
fn init_type<P: pyo3::PyClass, N: PyNode + Node>(py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<P>()?;
let node = m.getattr(P::NAME)?;
if P::NAME != N::NAME {
// TODO: no idea how to escape rust keyword on #[pyclass]
m.setattr(P::NAME, node)?;
}
let names: Vec<&'static str> = N::FIELD_NAMES.to_vec();
let fields = PyTuple::new(py, names);
node.setattr("_fields", fields)?;
Ok(())
}
/// A Python module implemented in Rust.
fn init_module(py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Ast>()?;
let ast = m.getattr("AST")?;
let fields = PyTuple::empty(py);
ast.setattr("_fields", fields)?;
Ok(())
}