Path: blob/main/crates/polars-core/src/series/implementations/object.rs
8422 views
use std::any::Any;1use std::borrow::Cow;23use self::compare_inner::TotalOrdInner;4use super::{BitRepr, StatisticsFlags, *};5use crate::chunked_array::cast::CastOptions;6use crate::chunked_array::object::PolarsObjectSafe;7use crate::chunked_array::object::registry::run_with_gil;8use crate::chunked_array::ops::compare_inner::{IntoTotalEqInner, TotalEqInner};9use crate::prelude::*;10use crate::series::implementations::SeriesWrap;11use crate::series::private::{PrivateSeries, PrivateSeriesNumeric};1213impl<T: PolarsObject> PrivateSeriesNumeric for SeriesWrap<ObjectChunked<T>> {14fn bit_repr(&self) -> Option<BitRepr> {15None16}17}1819impl<T> PrivateSeries for SeriesWrap<ObjectChunked<T>>20where21T: PolarsObject,22{23fn get_list_builder(24&self,25_name: PlSmallStr,26_values_capacity: usize,27_list_capacity: usize,28) -> Box<dyn ListBuilderTrait> {29ObjectChunked::<T>::get_list_builder(_name, _values_capacity, _list_capacity)30}3132fn compute_len(&mut self) {33self.0.compute_len()34}3536fn _field(&self) -> Cow<'_, Field> {37Cow::Borrowed(self.0.ref_field())38}3940fn _dtype(&self) -> &DataType {41self.0.dtype()42}4344fn _set_flags(&mut self, flags: StatisticsFlags) {45self.0.set_flags(flags)46}47fn _get_flags(&self) -> StatisticsFlags {48self.0.get_flags()49}50unsafe fn agg_list(&self, groups: &GroupsType) -> Series {51self.0.agg_list(groups)52}5354fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {55(&self.0).into_total_eq_inner()56}57fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {58invalid_operation_panic!(into_total_ord_inner, self)59}6061fn vec_hash(62&self,63random_state: PlSeedableRandomStateQuality,64buf: &mut Vec<u64>,65) -> PolarsResult<()> {66self.0.vec_hash(random_state, buf)?;67Ok(())68}6970fn vec_hash_combine(71&self,72build_hasher: PlSeedableRandomStateQuality,73hashes: &mut [u64],74) -> PolarsResult<()> {75self.0.vec_hash_combine(build_hasher, hashes)?;76Ok(())77}7879#[cfg(feature = "algorithm_group_by")]80fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {81IntoGroupsType::group_tuples(&self.0, multithreaded, sorted)82}83#[cfg(feature = "zip_with")]84fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {85self.086.zip_with(mask, other.as_ref().as_ref())87.map(|ca| ca.into_series())88}89}90impl<T> SeriesTrait for SeriesWrap<ObjectChunked<T>>91where92T: PolarsObject,93{94fn rename(&mut self, name: PlSmallStr) {95ObjectChunked::rename(&mut self.0, name)96}9798fn chunk_lengths(&self) -> ChunkLenIter<'_> {99ObjectChunked::chunk_lengths(&self.0)100}101102fn name(&self) -> &PlSmallStr {103ObjectChunked::name(&self.0)104}105106fn dtype(&self) -> &DataType {107ObjectChunked::dtype(&self.0)108}109110fn chunks(&self) -> &Vec<ArrayRef> {111ObjectChunked::chunks(&self.0)112}113unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {114self.0.chunks_mut()115}116117fn slice(&self, offset: i64, length: usize) -> Series {118ObjectChunked::slice(&self.0, offset, length).into_series()119}120121fn split_at(&self, offset: i64) -> (Series, Series) {122let (a, b) = ObjectChunked::split_at(&self.0, offset);123(a.into_series(), b.into_series())124}125126fn append(&mut self, other: &Series) -> PolarsResult<()> {127polars_ensure!(self.dtype() == other.dtype(), append);128ObjectChunked::append(&mut self.0, other.as_ref().as_ref())129}130fn append_owned(&mut self, other: Series) -> PolarsResult<()> {131polars_ensure!(self.dtype() == other.dtype(), append);132ObjectChunked::append_owned(&mut self.0, other.take_inner())133}134135fn extend(&mut self, _other: &Series) -> PolarsResult<()> {136polars_bail!(opq = extend, self.dtype());137}138139fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {140run_with_gil(|| ChunkFilter::filter(&self.0, filter).map(|ca| ca.into_series()))141}142143fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {144run_with_gil(|| {145let ca = self.rechunk_object();146Ok(ca.take(indices)?.into_series())147})148}149150unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {151run_with_gil(|| {152let ca = self.rechunk_object();153ca.take_unchecked(indices).into_series()154})155}156157fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {158run_with_gil(|| {159let ca = self.rechunk_object();160Ok(ca.take(indices)?.into_series())161})162}163164unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {165run_with_gil(|| {166let ca = self.rechunk_object();167ca.take_unchecked(indices).into_series()168})169}170171fn deposit(&self, validity: &Bitmap) -> Series {172self.0.deposit(validity).into_series()173}174175fn len(&self) -> usize {176ObjectChunked::len(&self.0)177}178179fn rechunk(&self) -> Series {180// do not call normal rechunk181self.rechunk_object().into_series()182}183184fn new_from_index(&self, index: usize, length: usize) -> Series {185ChunkExpandAtIndex::new_from_index(&self.0, index, length).into_series()186}187188fn cast(&self, dtype: &DataType, _cast_options: CastOptions) -> PolarsResult<Series> {189if matches!(dtype, DataType::Object(_)) {190Ok(self.0.clone().into_series())191} else {192Err(PolarsError::ComputeError(193"cannot cast 'Object' type".into(),194))195}196}197198fn get(&self, index: usize) -> PolarsResult<AnyValue<'_>> {199ObjectChunked::get_any_value(&self.0, index)200}201unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {202ObjectChunked::get_any_value_unchecked(&self.0, index)203}204fn null_count(&self) -> usize {205ObjectChunked::null_count(&self.0)206}207208fn has_nulls(&self) -> bool {209ObjectChunked::has_nulls(&self.0)210}211212fn unique(&self) -> PolarsResult<Series> {213ChunkUnique::unique(&self.0).map(|ca| ca.into_series())214}215216fn n_unique(&self) -> PolarsResult<usize> {217ChunkUnique::n_unique(&self.0)218}219220fn arg_unique(&self) -> PolarsResult<IdxCa> {221ChunkUnique::arg_unique(&self.0)222}223224fn unique_id(&self) -> PolarsResult<(IdxSize, Vec<IdxSize>)> {225polars_bail!(opq = unique_id, self.dtype());226}227228fn is_null(&self) -> BooleanChunked {229ObjectChunked::is_null(&self.0)230}231232fn is_not_null(&self) -> BooleanChunked {233ObjectChunked::is_not_null(&self.0)234}235236fn reverse(&self) -> Series {237ChunkReverse::reverse(&self.0).into_series()238}239240fn shift(&self, periods: i64) -> Series {241ChunkShift::shift(&self.0, periods).into_series()242}243244fn clone_inner(&self) -> Arc<dyn SeriesTrait> {245Arc::new(SeriesWrap(Clone::clone(&self.0)))246}247248fn get_object(&self, index: usize) -> Option<&dyn PolarsObjectSafe> {249ObjectChunked::<T>::get_object(&self.0, index)250}251252unsafe fn get_object_chunked_unchecked(253&self,254chunk: usize,255index: usize,256) -> Option<&dyn PolarsObjectSafe> {257ObjectChunked::<T>::get_object_chunked_unchecked(&self.0, chunk, index)258}259260fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {261self.0.find_validity_mismatch(other, idxs)262}263264fn as_any(&self) -> &dyn Any {265&self.0266}267268fn as_any_mut(&mut self) -> &mut dyn Any {269&mut self.0270}271272fn as_phys_any(&self) -> &dyn Any {273self274}275276fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {277self as _278}279}280281#[cfg(test)]282mod test {283use super::*;284285#[test]286fn test_downcast_object() -> PolarsResult<()> {287#[allow(non_local_definitions)]288impl PolarsObject for i32 {289fn type_name() -> &'static str {290"i32"291}292}293294let ca = ObjectChunked::new_from_vec("a".into(), vec![0i32, 1, 2]);295let s = ca.into_series();296297let ca = s.as_any().downcast_ref::<ObjectChunked<i32>>().unwrap();298assert_eq!(*ca.get(0).unwrap(), 0);299assert_eq!(*ca.get(1).unwrap(), 1);300assert_eq!(*ca.get(2).unwrap(), 2);301302Ok(())303}304}305306307