|
| 1 | +use crate::builtins::{PyList, PyStr, PyTuple, PyTypeRef}; |
| 2 | +use crate::function::FuncArgs; |
| 3 | +use crate::types::GetAttr; |
| 4 | +use crate::{AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine}; |
| 5 | +use rustpython_common::lock::PyRwLock; |
| 6 | +use rustpython_vm::types::Constructor; |
| 7 | +use std::collections::HashMap; |
| 8 | +use std::fmt::Debug; |
| 9 | + |
1 | 10 | #[pyclass(name = "Structure", module = "_ctypes")]
|
2 |
| -pub struct PyCStructure {} |
| 11 | +#[derive(PyPayload, Debug)] |
| 12 | +pub struct PyCStructure { |
| 13 | + #[allow(dead_code)] |
| 14 | + field_data: PyRwLock<HashMap<String, PyObjectRef>>, |
| 15 | + data: PyRwLock<HashMap<String, PyObjectRef>>, |
| 16 | +} |
| 17 | + |
| 18 | +impl Constructor for PyCStructure { |
| 19 | + type Args = FuncArgs; |
| 20 | + |
| 21 | + fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { |
| 22 | + let fields_attr = cls |
| 23 | + .get_class_attr(vm.ctx.interned_str("_fields_").unwrap()) |
| 24 | + .ok_or_else(|| { |
| 25 | + vm.new_attribute_error("Structure must have a _fields_ attribute".to_string()) |
| 26 | + })?; |
| 27 | + // downcast into list |
| 28 | + let fields = fields_attr.downcast_ref::<PyList>().ok_or_else(|| { |
| 29 | + vm.new_type_error("Structure _fields_ attribute must be a list".to_string()) |
| 30 | + })?; |
| 31 | + let fields = fields.borrow_vec(); |
| 32 | + let mut field_data = HashMap::new(); |
| 33 | + for field in fields.iter() { |
| 34 | + let field = field |
| 35 | + .downcast_ref::<PyTuple>() |
| 36 | + .ok_or_else(|| vm.new_type_error("Field must be a tuple".to_string()))?; |
| 37 | + let name = field |
| 38 | + .first() |
| 39 | + .unwrap() |
| 40 | + .downcast_ref::<PyStr>() |
| 41 | + .ok_or_else(|| vm.new_type_error("Field name must be a string".to_string()))?; |
| 42 | + let typ = field.get(1).unwrap().clone(); |
| 43 | + field_data.insert(name.as_str().to_string(), typ); |
| 44 | + } |
| 45 | + todo!("Implement PyCStructure::py_new") |
| 46 | + } |
| 47 | +} |
| 48 | + |
| 49 | +impl GetAttr for PyCStructure { |
| 50 | + fn getattro(zelf: &Py<Self>, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult { |
| 51 | + let name = name.to_string(); |
| 52 | + let data = zelf.data.read(); |
| 53 | + match data.get(&name) { |
| 54 | + Some(value) => Ok(value.clone()), |
| 55 | + None => Err(vm.new_attribute_error(format!("No attribute named {}", name))), |
| 56 | + } |
| 57 | + } |
| 58 | +} |
3 | 59 |
|
4 | 60 | #[pyclass(flags(BASETYPE, IMMUTABLETYPE))]
|
5 | 61 | impl PyCStructure {}
|
0 commit comments