mod traits;
use crate::data::{PyData, PyArrayData};
use pyo3::prelude::*;
use pyo3_polars::PySeries;
use traits::{ElemTrait, ArrayElemTrait, DataFrameElemTrait, AxisArrayTrait};
use anyhow::Result;
use self::traits::{ElemCollectionTrait, ChunkedArrayTrait};
#[pyclass]
#[repr(transparent)]
pub struct PyElem(Box<dyn ElemTrait>);
impl<T: ElemTrait + 'static> From<T> for PyElem {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}
#[pymethods]
impl PyElem {
fn enable_cache(&self) {
self.0.enable_cache();
}
fn disable_cache(&self) {
self.0.disable_cache();
}
fn is_scalar(&self) -> bool {
self.0.is_scalar()
}
fn __getitem__<'py>(&self, subscript: &Bound<'py, PyAny>) -> Result<PyData> {
self.0.get(subscript)
}
fn __repr__(&self) -> String {
self.0.show()
}
fn __str__(&self) -> String {
self.0.show()
}
}
#[pyclass]
#[repr(transparent)]
pub struct PyArrayElem(Box<dyn ArrayElemTrait>);
impl<T: ArrayElemTrait + 'static> From<T> for PyArrayElem {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}
#[pymethods]
impl PyArrayElem {
#[pyo3(text_signature = "($self)")]
fn enable_cache(&self) {
self.0.enable_cache();
}
#[pyo3(text_signature = "($self)")]
fn disable_cache(&self) {
self.0.disable_cache();
}
#[getter]
fn shape(&self) -> Vec<usize> {
self.0.shape()
}
fn __getitem__(&self, subscript: &Bound<'_, PyAny>) -> Result<PyArrayData> {
self.0.get(subscript)
}
#[pyo3(
signature = (size, replace=true, seed=2022),
text_signature = "($self, size, replace=True, seed=2022)",
)]
fn chunk(
&self,
size: usize,
replace: bool,
seed: u64,
) -> Result<PyArrayData> {
self.0.chunk(size, replace, seed).map(PyArrayData::from)
}
#[pyo3(text_signature = "($self, chunk_size)")]
pub fn chunked(&self, chunk_size: usize) -> PyChunkedArray {
self.0.chunked(chunk_size)
}
fn __repr__(&self) -> String {
self.0.show()
}
fn __str__(&self) -> String {
self.0.show()
}
}
#[pyclass]
#[repr(transparent)]
pub struct PyDataFrameElem(Box<dyn DataFrameElemTrait>);
impl<T: DataFrameElemTrait + 'static> From<T> for PyDataFrameElem {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}
#[pymethods]
impl PyDataFrameElem {
fn __getitem__(&self, subscript: &Bound<'_, PyAny>) -> Result<PyObject> {
self.0.get(subscript)
}
fn __setitem__(&self, key: &str, data: &Bound<'_, PyAny>) -> Result<()> {
let data: PySeries = data.py().import_bound("polars")?.call_method1("Series", (data, ))?.extract()?;
self.0.set(key, data.into())
}
fn __contains__(&self, key: &str) -> bool {
self.0.contains(key)
}
fn __repr__(&self) -> String {
self.0.show()
}
fn __str__(&self) -> String {
self.0.show()
}
}
#[pyclass]
#[repr(transparent)]
pub struct PyAxisArrays(Box<dyn AxisArrayTrait>);
impl<T: AxisArrayTrait + 'static> From<T> for PyAxisArrays {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}
#[pymethods]
impl PyAxisArrays {
#[pyo3(text_signature = "($self)")]
pub fn keys(&self) -> Vec<String> {
self.0.keys()
}
fn __contains__(&self, key: &str) -> bool {
self.0.contains(key)
}
fn __getitem__(&self, key: &str) -> Result<PyArrayData> {
self.0.get(key)
}
#[pyo3(text_signature = "($self, key)")]
fn el(&self, key: &str) -> Result<PyArrayElem> {
self.0.el(key)
}
fn __setitem__(&self, key: &str, data: PyArrayData) -> Result<()> {
self.0.set(key, data)
}
fn __repr__(&self) -> String {
self.0.show()
}
fn __str__(&self) -> String {
self.0.show()
}
}
#[pyclass]
#[repr(transparent)]
pub struct PyElemCollection(Box<dyn ElemCollectionTrait>);
impl<T: ElemCollectionTrait + 'static> From<T> for PyElemCollection {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}
#[pymethods]
impl PyElemCollection {
pub fn keys(&self) -> Vec<String> {
self.0.keys()
}
fn __contains__(&self, key: &str) -> bool {
self.0.contains(key)
}
fn __getitem__(&self, key: &str) -> Result<PyData> {
self.0.get(key)
}
fn __setitem__(&self, key: &str, data: PyData) -> Result<()> {
self.0.set(key, data)
}
fn __repr__(&self) -> String {
self.0.show()
}
fn __str__(&self) -> String {
self.0.show()
}
}
#[pyclass]
#[repr(transparent)]
pub struct PyChunkedArray(Box<dyn ChunkedArrayTrait>);
#[pymethods]
impl PyChunkedArray {
fn n_chunks(&self) -> usize {
self.0.len()
}
fn __iter__(slf: PyRef<Self>) -> PyRef<Self> {
slf
}
fn __next__(mut slf: PyRefMut<Self>) -> Option<(PyArrayData, usize, usize)> {
slf.0.next().map(|(data, start, end)| (data.into(), start, end))
}
}
impl<T: ChunkedArrayTrait + 'static> From<T> for PyChunkedArray {
fn from(elem: T) -> Self {
Self(Box::new(elem))
}
}