Path: blob/main/crates/polars-core/src/series/implementations/object.rs
6940 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::ops::compare_inner::{IntoTotalEqInner, TotalEqInner};8use crate::prelude::*;9use crate::series::implementations::SeriesWrap;10use crate::series::private::{PrivateSeries, PrivateSeriesNumeric};1112impl<T: PolarsObject> PrivateSeriesNumeric for SeriesWrap<ObjectChunked<T>> {13fn bit_repr(&self) -> Option<BitRepr> {14None15}16}1718impl<T> PrivateSeries for SeriesWrap<ObjectChunked<T>>19where20T: PolarsObject,21{22fn get_list_builder(23&self,24_name: PlSmallStr,25_values_capacity: usize,26_list_capacity: usize,27) -> Box<dyn ListBuilderTrait> {28ObjectChunked::<T>::get_list_builder(_name, _values_capacity, _list_capacity)29}3031fn compute_len(&mut self) {32self.0.compute_len()33}3435fn _field(&self) -> Cow<'_, Field> {36Cow::Borrowed(self.0.ref_field())37}3839fn _dtype(&self) -> &DataType {40self.0.dtype()41}4243fn _set_flags(&mut self, flags: StatisticsFlags) {44self.0.set_flags(flags)45}46fn _get_flags(&self) -> StatisticsFlags {47self.0.get_flags()48}49unsafe fn agg_list(&self, groups: &GroupsType) -> Series {50self.0.agg_list(groups)51}5253fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {54(&self.0).into_total_eq_inner()55}56fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {57invalid_operation_panic!(into_total_ord_inner, self)58}5960fn vec_hash(61&self,62random_state: PlSeedableRandomStateQuality,63buf: &mut Vec<u64>,64) -> PolarsResult<()> {65self.0.vec_hash(random_state, buf)?;66Ok(())67}6869fn vec_hash_combine(70&self,71build_hasher: PlSeedableRandomStateQuality,72hashes: &mut [u64],73) -> PolarsResult<()> {74self.0.vec_hash_combine(build_hasher, hashes)?;75Ok(())76}7778#[cfg(feature = "algorithm_group_by")]79fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {80IntoGroupsType::group_tuples(&self.0, multithreaded, sorted)81}82#[cfg(feature = "zip_with")]83fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {84self.085.zip_with(mask, other.as_ref().as_ref())86.map(|ca| ca.into_series())87}88}89impl<T> SeriesTrait for SeriesWrap<ObjectChunked<T>>90where91T: PolarsObject,92{93fn rename(&mut self, name: PlSmallStr) {94ObjectChunked::rename(&mut self.0, name)95}9697fn chunk_lengths(&self) -> ChunkLenIter<'_> {98ObjectChunked::chunk_lengths(&self.0)99}100101fn name(&self) -> &PlSmallStr {102ObjectChunked::name(&self.0)103}104105fn dtype(&self) -> &DataType {106ObjectChunked::dtype(&self.0)107}108109fn chunks(&self) -> &Vec<ArrayRef> {110ObjectChunked::chunks(&self.0)111}112unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {113self.0.chunks_mut()114}115116fn slice(&self, offset: i64, length: usize) -> Series {117ObjectChunked::slice(&self.0, offset, length).into_series()118}119120fn split_at(&self, offset: i64) -> (Series, Series) {121let (a, b) = ObjectChunked::split_at(&self.0, offset);122(a.into_series(), b.into_series())123}124125fn append(&mut self, other: &Series) -> PolarsResult<()> {126polars_ensure!(self.dtype() == other.dtype(), append);127ObjectChunked::append(&mut self.0, other.as_ref().as_ref())128}129fn append_owned(&mut self, other: Series) -> PolarsResult<()> {130polars_ensure!(self.dtype() == other.dtype(), append);131ObjectChunked::append_owned(&mut self.0, other.take_inner())132}133134fn extend(&mut self, _other: &Series) -> PolarsResult<()> {135polars_bail!(opq = extend, self.dtype());136}137138fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {139ChunkFilter::filter(&self.0, filter).map(|ca| ca.into_series())140}141142fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {143let ca = self.rechunk_object();144Ok(ca.take(indices)?.into_series())145}146147unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {148let ca = self.rechunk_object();149ca.take_unchecked(indices).into_series()150}151152fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {153Ok(self.0.take(indices)?.into_series())154}155156unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {157self.0.take_unchecked(indices).into_series()158}159160fn len(&self) -> usize {161ObjectChunked::len(&self.0)162}163164fn rechunk(&self) -> Series {165// do not call normal rechunk166self.rechunk_object().into_series()167}168169fn new_from_index(&self, index: usize, length: usize) -> Series {170ChunkExpandAtIndex::new_from_index(&self.0, index, length).into_series()171}172173fn cast(&self, dtype: &DataType, _cast_options: CastOptions) -> PolarsResult<Series> {174if matches!(dtype, DataType::Object(_)) {175Ok(self.0.clone().into_series())176} else {177Err(PolarsError::ComputeError(178"cannot cast 'Object' type".into(),179))180}181}182183fn get(&self, index: usize) -> PolarsResult<AnyValue<'_>> {184ObjectChunked::get_any_value(&self.0, index)185}186unsafe fn get_unchecked(&self, index: usize) -> AnyValue<'_> {187ObjectChunked::get_any_value_unchecked(&self.0, index)188}189fn null_count(&self) -> usize {190ObjectChunked::null_count(&self.0)191}192193fn has_nulls(&self) -> bool {194ObjectChunked::has_nulls(&self.0)195}196197fn unique(&self) -> PolarsResult<Series> {198ChunkUnique::unique(&self.0).map(|ca| ca.into_series())199}200201fn n_unique(&self) -> PolarsResult<usize> {202ChunkUnique::n_unique(&self.0)203}204205fn arg_unique(&self) -> PolarsResult<IdxCa> {206ChunkUnique::arg_unique(&self.0)207}208209fn is_null(&self) -> BooleanChunked {210ObjectChunked::is_null(&self.0)211}212213fn is_not_null(&self) -> BooleanChunked {214ObjectChunked::is_not_null(&self.0)215}216217fn reverse(&self) -> Series {218ChunkReverse::reverse(&self.0).into_series()219}220221fn shift(&self, periods: i64) -> Series {222ChunkShift::shift(&self.0, periods).into_series()223}224225fn clone_inner(&self) -> Arc<dyn SeriesTrait> {226Arc::new(SeriesWrap(Clone::clone(&self.0)))227}228229fn get_object(&self, index: usize) -> Option<&dyn PolarsObjectSafe> {230ObjectChunked::<T>::get_object(&self.0, index)231}232233unsafe fn get_object_chunked_unchecked(234&self,235chunk: usize,236index: usize,237) -> Option<&dyn PolarsObjectSafe> {238ObjectChunked::<T>::get_object_chunked_unchecked(&self.0, chunk, index)239}240241fn find_validity_mismatch(&self, other: &Series, idxs: &mut Vec<IdxSize>) {242self.0.find_validity_mismatch(other, idxs)243}244245fn as_any(&self) -> &dyn Any {246&self.0247}248249fn as_any_mut(&mut self) -> &mut dyn Any {250&mut self.0251}252253fn as_phys_any(&self) -> &dyn Any {254self255}256257fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {258self as _259}260}261262#[cfg(test)]263mod test {264use super::*;265266#[test]267fn test_downcast_object() -> PolarsResult<()> {268#[allow(non_local_definitions)]269impl PolarsObject for i32 {270fn type_name() -> &'static str {271"i32"272}273}274275let ca = ObjectChunked::new_from_vec("a".into(), vec![0i32, 1, 2]);276let s = ca.into_series();277278let ca = s.as_any().downcast_ref::<ObjectChunked<i32>>().unwrap();279assert_eq!(*ca.get(0).unwrap(), 0);280assert_eq!(*ca.get(1).unwrap(), 1);281assert_eq!(*ca.get(2).unwrap(), 2);282283Ok(())284}285}286287288