polars-df 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Cargo.lock +468 -538
- data/Cargo.toml +1 -0
- data/README.md +8 -7
- data/ext/polars/Cargo.toml +17 -10
- data/ext/polars/src/batched_csv.rs +26 -26
- data/ext/polars/src/conversion.rs +121 -93
- data/ext/polars/src/dataframe.rs +116 -71
- data/ext/polars/src/error.rs +0 -5
- data/ext/polars/src/expr/binary.rs +18 -6
- data/ext/polars/src/expr/datetime.rs +10 -12
- data/ext/polars/src/expr/general.rs +68 -284
- data/ext/polars/src/expr/list.rs +17 -9
- data/ext/polars/src/{expr.rs → expr/mod.rs} +4 -2
- data/ext/polars/src/expr/name.rs +44 -0
- data/ext/polars/src/expr/rolling.rs +196 -0
- data/ext/polars/src/expr/string.rs +85 -58
- data/ext/polars/src/file.rs +3 -3
- data/ext/polars/src/functions/aggregation.rs +35 -0
- data/ext/polars/src/functions/eager.rs +7 -31
- data/ext/polars/src/functions/io.rs +10 -10
- data/ext/polars/src/functions/lazy.rs +66 -41
- data/ext/polars/src/functions/meta.rs +30 -0
- data/ext/polars/src/functions/misc.rs +8 -0
- data/ext/polars/src/functions/mod.rs +5 -0
- data/ext/polars/src/functions/random.rs +6 -0
- data/ext/polars/src/functions/range.rs +46 -0
- data/ext/polars/src/functions/string_cache.rs +11 -0
- data/ext/polars/src/functions/whenthen.rs +7 -7
- data/ext/polars/src/lazyframe.rs +47 -42
- data/ext/polars/src/lib.rs +156 -72
- data/ext/polars/src/{apply → map}/dataframe.rs +28 -33
- data/ext/polars/src/{apply → map}/mod.rs +3 -3
- data/ext/polars/src/{apply → map}/series.rs +12 -16
- data/ext/polars/src/object.rs +1 -1
- data/ext/polars/src/rb_modules.rs +22 -7
- data/ext/polars/src/series/construction.rs +4 -4
- data/ext/polars/src/series/export.rs +2 -2
- data/ext/polars/src/series/set_at_idx.rs +33 -17
- data/ext/polars/src/series.rs +7 -27
- data/ext/polars/src/sql.rs +46 -0
- data/lib/polars/config.rb +530 -0
- data/lib/polars/data_frame.rb +115 -82
- data/lib/polars/date_time_expr.rb +13 -18
- data/lib/polars/date_time_name_space.rb +5 -25
- data/lib/polars/dynamic_group_by.rb +2 -2
- data/lib/polars/expr.rb +177 -94
- data/lib/polars/functions.rb +29 -37
- data/lib/polars/group_by.rb +38 -55
- data/lib/polars/io.rb +37 -2
- data/lib/polars/lazy_frame.rb +93 -66
- data/lib/polars/lazy_functions.rb +36 -48
- data/lib/polars/lazy_group_by.rb +7 -8
- data/lib/polars/list_expr.rb +12 -8
- data/lib/polars/list_name_space.rb +2 -2
- data/lib/polars/name_expr.rb +198 -0
- data/lib/polars/rolling_group_by.rb +2 -2
- data/lib/polars/series.rb +26 -13
- data/lib/polars/sql_context.rb +194 -0
- data/lib/polars/string_expr.rb +114 -60
- data/lib/polars/string_name_space.rb +19 -4
- data/lib/polars/utils.rb +12 -0
- data/lib/polars/version.rb +1 -1
- data/lib/polars.rb +3 -0
- metadata +18 -7
- /data/ext/polars/src/{apply → map}/lazy.rs +0 -0
@@ -1,10 +1,10 @@
|
|
1
|
-
use std::fmt::{Display, Formatter};
|
1
|
+
use std::fmt::{Debug, Display, Formatter};
|
2
2
|
use std::hash::{Hash, Hasher};
|
3
3
|
|
4
4
|
use magnus::encoding::{EncodingCapable, Index};
|
5
5
|
use magnus::{
|
6
|
-
class, exception, r_hash::ForEach,
|
7
|
-
RArray, RHash, RString, Symbol, TryConvert, Value,
|
6
|
+
class, exception, prelude::*, r_hash::ForEach, value::Opaque, Float, Integer, IntoValue,
|
7
|
+
Module, RArray, RHash, RString, Ruby, Symbol, TryConvert, Value,
|
8
8
|
};
|
9
9
|
use polars::chunked_array::object::PolarsObjectSafe;
|
10
10
|
use polars::chunked_array::ops::{FillNullLimit, FillNullStrategy};
|
@@ -14,6 +14,7 @@ use polars::frame::NullStrategy;
|
|
14
14
|
use polars::io::avro::AvroCompression;
|
15
15
|
use polars::prelude::*;
|
16
16
|
use polars::series::ops::NullBehavior;
|
17
|
+
use polars_core::utils::arrow::util::total_ord::TotalEq;
|
17
18
|
use smartstring::alias::String as SmartString;
|
18
19
|
|
19
20
|
use crate::object::OBJECT_NAME;
|
@@ -57,7 +58,7 @@ impl<T> From<T> for Wrap<T> {
|
|
57
58
|
}
|
58
59
|
|
59
60
|
pub(crate) fn get_rbseq(obj: Value) -> RbResult<(RArray, usize)> {
|
60
|
-
let seq
|
61
|
+
let seq = RArray::try_convert(obj)?;
|
61
62
|
let len = seq.len();
|
62
63
|
Ok((seq, len))
|
63
64
|
}
|
@@ -84,7 +85,7 @@ impl TryConvert for Wrap<Utf8Chunked> {
|
|
84
85
|
|
85
86
|
for res in seq.each() {
|
86
87
|
let item = res?;
|
87
|
-
match
|
88
|
+
match String::try_convert(item) {
|
88
89
|
Ok(val) => builder.append_value(&val),
|
89
90
|
Err(_) => builder.append_null(),
|
90
91
|
}
|
@@ -100,7 +101,7 @@ impl TryConvert for Wrap<BinaryChunked> {
|
|
100
101
|
|
101
102
|
for res in seq.each() {
|
102
103
|
let item = res?;
|
103
|
-
match
|
104
|
+
match RString::try_convert(item) {
|
104
105
|
Ok(val) => builder.append_value(unsafe { val.as_slice() }),
|
105
106
|
Err(_) => builder.append_null(),
|
106
107
|
}
|
@@ -111,11 +112,11 @@ impl TryConvert for Wrap<BinaryChunked> {
|
|
111
112
|
|
112
113
|
impl TryConvert for Wrap<NullValues> {
|
113
114
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
114
|
-
if let Ok(s) =
|
115
|
+
if let Ok(s) = String::try_convert(ob) {
|
115
116
|
Ok(Wrap(NullValues::AllColumnsSingle(s)))
|
116
|
-
} else if let Ok(s) =
|
117
|
+
} else if let Ok(s) = Vec::<String>::try_convert(ob) {
|
117
118
|
Ok(Wrap(NullValues::AllColumns(s)))
|
118
|
-
} else if let Ok(s) =
|
119
|
+
} else if let Ok(s) = Vec::<(String, String)>::try_convert(ob) {
|
119
120
|
Ok(Wrap(NullValues::Named(s)))
|
120
121
|
} else {
|
121
122
|
Err(RbPolarsErr::other(
|
@@ -134,22 +135,22 @@ fn struct_dict<'a>(vals: impl Iterator<Item = AnyValue<'a>>, flds: &[Field]) ->
|
|
134
135
|
}
|
135
136
|
|
136
137
|
impl IntoValue for Wrap<AnyValue<'_>> {
|
137
|
-
fn into_value_with(self,
|
138
|
+
fn into_value_with(self, ruby: &Ruby) -> Value {
|
138
139
|
match self.0 {
|
139
|
-
AnyValue::UInt8(v) =>
|
140
|
-
AnyValue::UInt16(v) =>
|
141
|
-
AnyValue::UInt32(v) =>
|
142
|
-
AnyValue::UInt64(v) =>
|
143
|
-
AnyValue::Int8(v) =>
|
144
|
-
AnyValue::Int16(v) =>
|
145
|
-
AnyValue::Int32(v) =>
|
146
|
-
AnyValue::Int64(v) =>
|
147
|
-
AnyValue::Float32(v) =>
|
148
|
-
AnyValue::Float64(v) =>
|
149
|
-
AnyValue::Null =>
|
150
|
-
AnyValue::Boolean(v) =>
|
151
|
-
AnyValue::Utf8(v) =>
|
152
|
-
AnyValue::Utf8Owned(v) =>
|
140
|
+
AnyValue::UInt8(v) => ruby.into_value(v),
|
141
|
+
AnyValue::UInt16(v) => ruby.into_value(v),
|
142
|
+
AnyValue::UInt32(v) => ruby.into_value(v),
|
143
|
+
AnyValue::UInt64(v) => ruby.into_value(v),
|
144
|
+
AnyValue::Int8(v) => ruby.into_value(v),
|
145
|
+
AnyValue::Int16(v) => ruby.into_value(v),
|
146
|
+
AnyValue::Int32(v) => ruby.into_value(v),
|
147
|
+
AnyValue::Int64(v) => ruby.into_value(v),
|
148
|
+
AnyValue::Float32(v) => ruby.into_value(v),
|
149
|
+
AnyValue::Float64(v) => ruby.into_value(v),
|
150
|
+
AnyValue::Null => ruby.qnil().as_value(),
|
151
|
+
AnyValue::Boolean(v) => ruby.into_value(v),
|
152
|
+
AnyValue::Utf8(v) => ruby.into_value(v),
|
153
|
+
AnyValue::Utf8Owned(v) => ruby.into_value(v.as_str()),
|
153
154
|
AnyValue::Categorical(idx, rev, arr) => {
|
154
155
|
let s = if arr.is_null() {
|
155
156
|
rev.get(idx)
|
@@ -177,11 +178,11 @@ impl IntoValue for Wrap<AnyValue<'_>> {
|
|
177
178
|
AnyValue::StructOwned(payload) => struct_dict(payload.0.into_iter(), &payload.1),
|
178
179
|
AnyValue::Object(v) => {
|
179
180
|
let object = v.as_any().downcast_ref::<ObjectValue>().unwrap();
|
180
|
-
object.
|
181
|
+
object.to_object()
|
181
182
|
}
|
182
183
|
AnyValue::ObjectOwned(v) => {
|
183
184
|
let object = v.0.as_any().downcast_ref::<ObjectValue>().unwrap();
|
184
|
-
object.
|
185
|
+
object.to_object()
|
185
186
|
}
|
186
187
|
AnyValue::Binary(v) => RString::from_slice(v).into_value(),
|
187
188
|
AnyValue::BinaryOwned(v) => RString::from_slice(&v).into_value(),
|
@@ -193,7 +194,7 @@ impl IntoValue for Wrap<AnyValue<'_>> {
|
|
193
194
|
}
|
194
195
|
|
195
196
|
impl IntoValue for Wrap<DataType> {
|
196
|
-
fn into_value_with(self, _: &
|
197
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
197
198
|
let pl = crate::rb_modules::polars();
|
198
199
|
|
199
200
|
match self.0 {
|
@@ -266,7 +267,7 @@ impl IntoValue for Wrap<DataType> {
|
|
266
267
|
}
|
267
268
|
|
268
269
|
impl IntoValue for Wrap<TimeUnit> {
|
269
|
-
fn into_value_with(self, _: &
|
270
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
270
271
|
let tu = match self.0 {
|
271
272
|
TimeUnit::Nanoseconds => "ns",
|
272
273
|
TimeUnit::Microseconds => "us",
|
@@ -277,14 +278,14 @@ impl IntoValue for Wrap<TimeUnit> {
|
|
277
278
|
}
|
278
279
|
|
279
280
|
impl IntoValue for Wrap<&Utf8Chunked> {
|
280
|
-
fn into_value_with(self, _: &
|
281
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
281
282
|
let iter = self.0.into_iter();
|
282
283
|
RArray::from_iter(iter).into_value()
|
283
284
|
}
|
284
285
|
}
|
285
286
|
|
286
287
|
impl IntoValue for Wrap<&BinaryChunked> {
|
287
|
-
fn into_value_with(self, _: &
|
288
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
288
289
|
let iter = self
|
289
290
|
.0
|
290
291
|
.into_iter()
|
@@ -294,7 +295,7 @@ impl IntoValue for Wrap<&BinaryChunked> {
|
|
294
295
|
}
|
295
296
|
|
296
297
|
impl IntoValue for Wrap<&StructChunked> {
|
297
|
-
fn into_value_with(self, _: &
|
298
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
298
299
|
let s = self.0.clone().into_series();
|
299
300
|
// todo! iterate its chunks and flatten.
|
300
301
|
// make series::iter() accept a chunk index.
|
@@ -312,7 +313,7 @@ impl IntoValue for Wrap<&StructChunked> {
|
|
312
313
|
}
|
313
314
|
|
314
315
|
impl IntoValue for Wrap<&DurationChunked> {
|
315
|
-
fn into_value_with(self, _: &
|
316
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
316
317
|
let utils = utils();
|
317
318
|
let time_unit = Wrap(self.0.time_unit()).into_value();
|
318
319
|
let iter = self.0.into_iter().map(|opt_v| {
|
@@ -327,7 +328,7 @@ impl IntoValue for Wrap<&DurationChunked> {
|
|
327
328
|
}
|
328
329
|
|
329
330
|
impl IntoValue for Wrap<&DatetimeChunked> {
|
330
|
-
fn into_value_with(self, _: &
|
331
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
331
332
|
let utils = utils();
|
332
333
|
let time_unit = Wrap(self.0.time_unit()).into_value();
|
333
334
|
let time_zone = self.0.time_zone().clone().into_value();
|
@@ -343,7 +344,7 @@ impl IntoValue for Wrap<&DatetimeChunked> {
|
|
343
344
|
}
|
344
345
|
|
345
346
|
impl IntoValue for Wrap<&TimeChunked> {
|
346
|
-
fn into_value_with(self, _: &
|
347
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
347
348
|
let utils = utils();
|
348
349
|
let iter = self.0.into_iter().map(|opt_v| {
|
349
350
|
opt_v.map(|v| utils.funcall::<_, _, Value>("_to_ruby_time", (v,)).unwrap())
|
@@ -353,7 +354,7 @@ impl IntoValue for Wrap<&TimeChunked> {
|
|
353
354
|
}
|
354
355
|
|
355
356
|
impl IntoValue for Wrap<&DateChunked> {
|
356
|
-
fn into_value_with(self, _: &
|
357
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
357
358
|
let utils = utils();
|
358
359
|
let iter = self.0.into_iter().map(|opt_v| {
|
359
360
|
opt_v.map(|v| utils.funcall::<_, _, Value>("_to_ruby_date", (v,)).unwrap())
|
@@ -363,7 +364,7 @@ impl IntoValue for Wrap<&DateChunked> {
|
|
363
364
|
}
|
364
365
|
|
365
366
|
impl IntoValue for Wrap<&DecimalChunked> {
|
366
|
-
fn into_value_with(self, _: &
|
367
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
367
368
|
let utils = utils();
|
368
369
|
let rb_scale = (-(self.0.scale() as i32)).into_value();
|
369
370
|
let iter = self.0.into_iter().map(|opt_v| {
|
@@ -427,36 +428,35 @@ impl TryConvert for Wrap<DataType> {
|
|
427
428
|
}
|
428
429
|
}
|
429
430
|
// TODO improve
|
430
|
-
} else if
|
431
|
+
} else if String::try_convert(ob).is_err() {
|
431
432
|
let name = unsafe { ob.class().name() }.into_owned();
|
432
433
|
match name.as_str() {
|
433
434
|
"Polars::Duration" => {
|
434
435
|
let time_unit: Value = ob.funcall("time_unit", ()).unwrap();
|
435
|
-
let time_unit =
|
436
|
+
let time_unit = Wrap::<TimeUnit>::try_convert(time_unit)?.0;
|
436
437
|
DataType::Duration(time_unit)
|
437
438
|
}
|
438
439
|
"Polars::Datetime" => {
|
439
440
|
let time_unit: Value = ob.funcall("time_unit", ()).unwrap();
|
440
|
-
let time_unit =
|
441
|
-
let time_zone
|
442
|
-
let time_zone = time_zone.try_convert()?;
|
441
|
+
let time_unit = Wrap::<TimeUnit>::try_convert(time_unit)?.0;
|
442
|
+
let time_zone = ob.funcall("time_zone", ())?;
|
443
443
|
DataType::Datetime(time_unit, time_zone)
|
444
444
|
}
|
445
445
|
"Polars::Decimal" => {
|
446
|
-
let precision = ob.funcall
|
447
|
-
let scale = ob.funcall
|
446
|
+
let precision = ob.funcall("precision", ())?;
|
447
|
+
let scale = ob.funcall("scale", ())?;
|
448
448
|
DataType::Decimal(precision, Some(scale))
|
449
449
|
}
|
450
450
|
"Polars::List" => {
|
451
451
|
let inner: Value = ob.funcall("inner", ()).unwrap();
|
452
|
-
let inner =
|
452
|
+
let inner = Wrap::<DataType>::try_convert(inner)?;
|
453
453
|
DataType::List(Box::new(inner.0))
|
454
454
|
}
|
455
455
|
"Polars::Struct" => {
|
456
456
|
let arr: RArray = ob.funcall("fields", ())?;
|
457
457
|
let mut fields = Vec::with_capacity(arr.len());
|
458
458
|
for v in arr.each() {
|
459
|
-
fields.push(
|
459
|
+
fields.push(Wrap::<Field>::try_convert(v?)?.0);
|
460
460
|
}
|
461
461
|
DataType::Struct(fields)
|
462
462
|
}
|
@@ -468,7 +468,7 @@ impl TryConvert for Wrap<DataType> {
|
|
468
468
|
}
|
469
469
|
}
|
470
470
|
} else {
|
471
|
-
match
|
471
|
+
match String::try_convert(ob)?.as_str() {
|
472
472
|
"u8" => DataType::UInt8,
|
473
473
|
"u16" => DataType::UInt16,
|
474
474
|
"u32" => DataType::UInt32,
|
@@ -487,7 +487,7 @@ impl TryConvert for Wrap<DataType> {
|
|
487
487
|
"time" => DataType::Time,
|
488
488
|
"dur" => DataType::Duration(TimeUnit::Microseconds),
|
489
489
|
"f64" => DataType::Float64,
|
490
|
-
|
490
|
+
"obj" => DataType::Object(OBJECT_NAME),
|
491
491
|
"list" => DataType::List(Box::new(DataType::Boolean)),
|
492
492
|
"null" => DataType::Null,
|
493
493
|
"unk" => DataType::Unknown,
|
@@ -506,7 +506,7 @@ impl TryConvert for Wrap<DataType> {
|
|
506
506
|
impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
507
507
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
508
508
|
if ob.is_kind_of(class::true_class()) || ob.is_kind_of(class::false_class()) {
|
509
|
-
Ok(AnyValue::Boolean(
|
509
|
+
Ok(AnyValue::Boolean(bool::try_convert(ob)?).into())
|
510
510
|
} else if let Some(v) = Integer::from_value(ob) {
|
511
511
|
Ok(AnyValue::Int64(v.to_i64()?).into())
|
512
512
|
} else if let Some(v) = Float::from_value(ob) {
|
@@ -532,8 +532,8 @@ impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
|
532
532
|
let mut keys = Vec::with_capacity(len);
|
533
533
|
let mut vals = Vec::with_capacity(len);
|
534
534
|
dict.foreach(|k: Value, v: Value| {
|
535
|
-
let key =
|
536
|
-
let val =
|
535
|
+
let key = String::try_convert(k)?;
|
536
|
+
let val = Wrap::<AnyValue>::try_convert(v)?.0;
|
537
537
|
let dtype = DataType::from(&val);
|
538
538
|
keys.push(Field::new(&key, dtype));
|
539
539
|
vals.push(val);
|
@@ -550,7 +550,7 @@ impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
|
550
550
|
let mut iter = list.each();
|
551
551
|
|
552
552
|
for item in (&mut iter).take(25) {
|
553
|
-
avs.push(
|
553
|
+
avs.push(Wrap::<AnyValue>::try_convert(item?)?.0)
|
554
554
|
}
|
555
555
|
|
556
556
|
let (dtype, _n_types) = any_values_to_dtype(&avs).map_err(RbPolarsErr::from)?;
|
@@ -558,7 +558,7 @@ impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
|
558
558
|
// push the rest
|
559
559
|
avs.reserve(list.len());
|
560
560
|
for item in iter {
|
561
|
-
avs.push(
|
561
|
+
avs.push(Wrap::<AnyValue>::try_convert(item?)?.0)
|
562
562
|
}
|
563
563
|
|
564
564
|
let s = Series::from_any_values_and_dtype("", &avs, &dtype, true)
|
@@ -581,11 +581,7 @@ impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
|
581
581
|
.funcall::<_, _, i64>("to_i", ())?;
|
582
582
|
Ok(Wrap(AnyValue::Date((v / 86400) as i32)))
|
583
583
|
} else if ob.is_kind_of(crate::rb_modules::bigdecimal()) {
|
584
|
-
let (sign, digits, _, exp): (i8, String, i32, i32) = ob
|
585
|
-
.funcall::<_, _, Value>("split", ())
|
586
|
-
.unwrap()
|
587
|
-
.try_convert()
|
588
|
-
.unwrap();
|
584
|
+
let (sign, digits, _, exp): (i8, String, i32, i32) = ob.funcall("split", ()).unwrap();
|
589
585
|
let (mut v, scale) = abs_decimal_from_digits(digits, exp).ok_or_else(|| {
|
590
586
|
RbPolarsErr::other("BigDecimal is too large to fit in Decimal128".into())
|
591
587
|
})?;
|
@@ -606,8 +602,8 @@ impl<'s> TryConvert for Wrap<AnyValue<'s>> {
|
|
606
602
|
impl<'s> TryConvert for Wrap<Row<'s>> {
|
607
603
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
608
604
|
let mut vals: Vec<Wrap<AnyValue<'s>>> = Vec::new();
|
609
|
-
for item in
|
610
|
-
vals.push(
|
605
|
+
for item in RArray::try_convert(ob)?.each() {
|
606
|
+
vals.push(Wrap::<AnyValue<'s>>::try_convert(item?)?);
|
611
607
|
}
|
612
608
|
let vals: Vec<AnyValue> = unsafe { std::mem::transmute(vals) };
|
613
609
|
Ok(Wrap(Row(vals)))
|
@@ -616,7 +612,7 @@ impl<'s> TryConvert for Wrap<Row<'s>> {
|
|
616
612
|
|
617
613
|
impl TryConvert for Wrap<Schema> {
|
618
614
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
619
|
-
let dict =
|
615
|
+
let dict = RHash::try_convert(ob)?;
|
620
616
|
|
621
617
|
let mut schema = Vec::new();
|
622
618
|
dict.foreach(|key: String, val: Wrap<DataType>| {
|
@@ -629,15 +625,23 @@ impl TryConvert for Wrap<Schema> {
|
|
629
625
|
}
|
630
626
|
}
|
631
627
|
|
632
|
-
#[derive(Clone
|
628
|
+
#[derive(Clone)]
|
633
629
|
pub struct ObjectValue {
|
634
|
-
pub inner: Value
|
630
|
+
pub inner: Opaque<Value>,
|
631
|
+
}
|
632
|
+
|
633
|
+
impl Debug for ObjectValue {
|
634
|
+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
635
|
+
f.debug_struct("ObjectValue")
|
636
|
+
.field("inner", &self.to_object())
|
637
|
+
.finish()
|
638
|
+
}
|
635
639
|
}
|
636
640
|
|
637
641
|
impl Hash for ObjectValue {
|
638
642
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
639
643
|
let h = self
|
640
|
-
.
|
644
|
+
.to_object()
|
641
645
|
.funcall::<_, _, isize>("hash", ())
|
642
646
|
.expect("should be hashable");
|
643
647
|
state.write_isize(h)
|
@@ -648,13 +652,19 @@ impl Eq for ObjectValue {}
|
|
648
652
|
|
649
653
|
impl PartialEq for ObjectValue {
|
650
654
|
fn eq(&self, other: &Self) -> bool {
|
651
|
-
self.
|
655
|
+
self.to_object().eql(other.to_object()).unwrap_or(false)
|
656
|
+
}
|
657
|
+
}
|
658
|
+
|
659
|
+
impl TotalEq for ObjectValue {
|
660
|
+
fn tot_eq(&self, other: &Self) -> bool {
|
661
|
+
self == other
|
652
662
|
}
|
653
663
|
}
|
654
664
|
|
655
665
|
impl Display for ObjectValue {
|
656
666
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
657
|
-
write!(f, "{}", self.
|
667
|
+
write!(f, "{}", self.to_object())
|
658
668
|
}
|
659
669
|
}
|
660
670
|
|
@@ -666,13 +676,13 @@ impl PolarsObject for ObjectValue {
|
|
666
676
|
|
667
677
|
impl From<Value> for ObjectValue {
|
668
678
|
fn from(v: Value) -> Self {
|
669
|
-
Self { inner: v }
|
679
|
+
Self { inner: v.into() }
|
670
680
|
}
|
671
681
|
}
|
672
682
|
|
673
683
|
impl TryConvert for ObjectValue {
|
674
684
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
675
|
-
Ok(ObjectValue { inner: ob })
|
685
|
+
Ok(ObjectValue { inner: ob.into() })
|
676
686
|
}
|
677
687
|
}
|
678
688
|
|
@@ -685,19 +695,21 @@ impl From<&dyn PolarsObjectSafe> for &ObjectValue {
|
|
685
695
|
// TODO remove
|
686
696
|
impl ObjectValue {
|
687
697
|
pub fn to_object(&self) -> Value {
|
688
|
-
self.inner
|
698
|
+
Ruby::get().unwrap().get_inner(self.inner)
|
689
699
|
}
|
690
700
|
}
|
691
701
|
|
692
702
|
impl IntoValue for ObjectValue {
|
693
|
-
fn into_value_with(self, _: &
|
694
|
-
self.
|
703
|
+
fn into_value_with(self, _: &Ruby) -> Value {
|
704
|
+
self.to_object()
|
695
705
|
}
|
696
706
|
}
|
697
707
|
|
698
708
|
impl Default for ObjectValue {
|
699
709
|
fn default() -> Self {
|
700
|
-
ObjectValue {
|
710
|
+
ObjectValue {
|
711
|
+
inner: Ruby::get().unwrap().qnil().as_value().into(),
|
712
|
+
}
|
701
713
|
}
|
702
714
|
}
|
703
715
|
|
@@ -710,13 +722,13 @@ pub(crate) fn dicts_to_rows(
|
|
710
722
|
let mut key_names = PlIndexSet::new();
|
711
723
|
for d in dicts.each().take(infer_schema_len) {
|
712
724
|
let d = d?;
|
713
|
-
let d =
|
725
|
+
let d = RHash::try_convert(d)?;
|
714
726
|
|
715
727
|
d.foreach(|name: Value, _value: Value| {
|
716
728
|
if let Some(v) = Symbol::from_value(name) {
|
717
729
|
key_names.insert(v.name()?.into());
|
718
730
|
} else {
|
719
|
-
key_names.insert(
|
731
|
+
key_names.insert(String::try_convert(name)?);
|
720
732
|
};
|
721
733
|
Ok(ForEach::Continue)
|
722
734
|
})?;
|
@@ -726,7 +738,7 @@ pub(crate) fn dicts_to_rows(
|
|
726
738
|
|
727
739
|
for d in dicts.each() {
|
728
740
|
let d = d?;
|
729
|
-
let d =
|
741
|
+
let d = RHash::try_convert(d)?;
|
730
742
|
|
731
743
|
let mut row = Vec::with_capacity(key_names.len());
|
732
744
|
|
@@ -734,7 +746,7 @@ pub(crate) fn dicts_to_rows(
|
|
734
746
|
// TODO improve performance
|
735
747
|
let val = match d.get(k.clone()).or_else(|| d.get(Symbol::new(k))) {
|
736
748
|
None => AnyValue::Null,
|
737
|
-
Some(val) =>
|
749
|
+
Some(val) => Wrap::<AnyValue>::try_convert(val)?.0,
|
738
750
|
};
|
739
751
|
row.push(val)
|
740
752
|
}
|
@@ -745,7 +757,7 @@ pub(crate) fn dicts_to_rows(
|
|
745
757
|
|
746
758
|
impl TryConvert for Wrap<AsofStrategy> {
|
747
759
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
748
|
-
let parsed = match
|
760
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
749
761
|
"backward" => AsofStrategy::Backward,
|
750
762
|
"forward" => AsofStrategy::Forward,
|
751
763
|
v => {
|
@@ -761,7 +773,7 @@ impl TryConvert for Wrap<AsofStrategy> {
|
|
761
773
|
|
762
774
|
impl TryConvert for Wrap<InterpolationMethod> {
|
763
775
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
764
|
-
let parsed = match
|
776
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
765
777
|
"linear" => InterpolationMethod::Linear,
|
766
778
|
"nearest" => InterpolationMethod::Nearest,
|
767
779
|
v => {
|
@@ -776,7 +788,7 @@ impl TryConvert for Wrap<InterpolationMethod> {
|
|
776
788
|
|
777
789
|
impl TryConvert for Wrap<Option<AvroCompression>> {
|
778
790
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
779
|
-
let parsed = match
|
791
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
780
792
|
"uncompressed" => None,
|
781
793
|
"snappy" => Some(AvroCompression::Snappy),
|
782
794
|
"deflate" => Some(AvroCompression::Deflate),
|
@@ -793,7 +805,7 @@ impl TryConvert for Wrap<Option<AvroCompression>> {
|
|
793
805
|
|
794
806
|
impl TryConvert for Wrap<CategoricalOrdering> {
|
795
807
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
796
|
-
let parsed = match
|
808
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
797
809
|
"physical" => CategoricalOrdering::Physical,
|
798
810
|
"lexical" => CategoricalOrdering::Lexical,
|
799
811
|
v => {
|
@@ -809,7 +821,7 @@ impl TryConvert for Wrap<CategoricalOrdering> {
|
|
809
821
|
|
810
822
|
impl TryConvert for Wrap<StartBy> {
|
811
823
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
812
|
-
let parsed = match
|
824
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
813
825
|
"window" => StartBy::WindowBound,
|
814
826
|
"datapoint" => StartBy::DataPoint,
|
815
827
|
"monday" => StartBy::Monday,
|
@@ -825,7 +837,7 @@ impl TryConvert for Wrap<StartBy> {
|
|
825
837
|
|
826
838
|
impl TryConvert for Wrap<ClosedWindow> {
|
827
839
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
828
|
-
let parsed = match
|
840
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
829
841
|
"left" => ClosedWindow::Left,
|
830
842
|
"right" => ClosedWindow::Right,
|
831
843
|
"both" => ClosedWindow::Both,
|
@@ -843,7 +855,7 @@ impl TryConvert for Wrap<ClosedWindow> {
|
|
843
855
|
|
844
856
|
impl TryConvert for Wrap<CsvEncoding> {
|
845
857
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
846
|
-
let parsed = match
|
858
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
847
859
|
"utf8" => CsvEncoding::Utf8,
|
848
860
|
"utf8-lossy" => CsvEncoding::LossyUtf8,
|
849
861
|
v => {
|
@@ -859,7 +871,7 @@ impl TryConvert for Wrap<CsvEncoding> {
|
|
859
871
|
|
860
872
|
impl TryConvert for Wrap<Option<IpcCompression>> {
|
861
873
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
862
|
-
let parsed = match
|
874
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
863
875
|
"uncompressed" => None,
|
864
876
|
"lz4" => Some(IpcCompression::LZ4),
|
865
877
|
"zstd" => Some(IpcCompression::ZSTD),
|
@@ -876,7 +888,7 @@ impl TryConvert for Wrap<Option<IpcCompression>> {
|
|
876
888
|
|
877
889
|
impl TryConvert for Wrap<JoinType> {
|
878
890
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
879
|
-
let parsed = match
|
891
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
880
892
|
"inner" => JoinType::Inner,
|
881
893
|
"left" => JoinType::Left,
|
882
894
|
"outer" => JoinType::Outer,
|
@@ -895,9 +907,25 @@ impl TryConvert for Wrap<JoinType> {
|
|
895
907
|
}
|
896
908
|
}
|
897
909
|
|
910
|
+
impl TryConvert for Wrap<Label> {
|
911
|
+
fn try_convert(ob: Value) -> RbResult<Self> {
|
912
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
913
|
+
"left" => Label::Left,
|
914
|
+
"right" => Label::Right,
|
915
|
+
"datapoint" => Label::DataPoint,
|
916
|
+
v => {
|
917
|
+
return Err(RbValueError::new_err(format!(
|
918
|
+
"`label` must be one of {{'left', 'right', 'datapoint'}}, got {v}",
|
919
|
+
)))
|
920
|
+
}
|
921
|
+
};
|
922
|
+
Ok(Wrap(parsed))
|
923
|
+
}
|
924
|
+
}
|
925
|
+
|
898
926
|
impl TryConvert for Wrap<ListToStructWidthStrategy> {
|
899
927
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
900
|
-
let parsed = match
|
928
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
901
929
|
"first_non_null" => ListToStructWidthStrategy::FirstNonNull,
|
902
930
|
"max_width" => ListToStructWidthStrategy::MaxWidth,
|
903
931
|
v => {
|
@@ -913,7 +941,7 @@ impl TryConvert for Wrap<ListToStructWidthStrategy> {
|
|
913
941
|
|
914
942
|
impl TryConvert for Wrap<NullBehavior> {
|
915
943
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
916
|
-
let parsed = match
|
944
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
917
945
|
"drop" => NullBehavior::Drop,
|
918
946
|
"ignore" => NullBehavior::Ignore,
|
919
947
|
v => {
|
@@ -929,7 +957,7 @@ impl TryConvert for Wrap<NullBehavior> {
|
|
929
957
|
|
930
958
|
impl TryConvert for Wrap<NullStrategy> {
|
931
959
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
932
|
-
let parsed = match
|
960
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
933
961
|
"ignore" => NullStrategy::Ignore,
|
934
962
|
"propagate" => NullStrategy::Propagate,
|
935
963
|
v => {
|
@@ -945,7 +973,7 @@ impl TryConvert for Wrap<NullStrategy> {
|
|
945
973
|
|
946
974
|
impl TryConvert for Wrap<ParallelStrategy> {
|
947
975
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
948
|
-
let parsed = match
|
976
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
949
977
|
"auto" => ParallelStrategy::Auto,
|
950
978
|
"columns" => ParallelStrategy::Columns,
|
951
979
|
"row_groups" => ParallelStrategy::RowGroups,
|
@@ -963,7 +991,7 @@ impl TryConvert for Wrap<ParallelStrategy> {
|
|
963
991
|
|
964
992
|
impl TryConvert for Wrap<QuantileInterpolOptions> {
|
965
993
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
966
|
-
let parsed = match
|
994
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
967
995
|
"lower" => QuantileInterpolOptions::Lower,
|
968
996
|
"higher" => QuantileInterpolOptions::Higher,
|
969
997
|
"nearest" => QuantileInterpolOptions::Nearest,
|
@@ -982,7 +1010,7 @@ impl TryConvert for Wrap<QuantileInterpolOptions> {
|
|
982
1010
|
|
983
1011
|
impl TryConvert for Wrap<RankMethod> {
|
984
1012
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
985
|
-
let parsed = match
|
1013
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
986
1014
|
"min" => RankMethod::Min,
|
987
1015
|
"max" => RankMethod::Max,
|
988
1016
|
"average" => RankMethod::Average,
|
@@ -1002,7 +1030,7 @@ impl TryConvert for Wrap<RankMethod> {
|
|
1002
1030
|
|
1003
1031
|
impl TryConvert for Wrap<TimeUnit> {
|
1004
1032
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
1005
|
-
let parsed = match
|
1033
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
1006
1034
|
"ns" => TimeUnit::Nanoseconds,
|
1007
1035
|
"us" => TimeUnit::Microseconds,
|
1008
1036
|
"ms" => TimeUnit::Milliseconds,
|
@@ -1019,7 +1047,7 @@ impl TryConvert for Wrap<TimeUnit> {
|
|
1019
1047
|
|
1020
1048
|
impl TryConvert for Wrap<UniqueKeepStrategy> {
|
1021
1049
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
1022
|
-
let parsed = match
|
1050
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
1023
1051
|
"first" => UniqueKeepStrategy::First,
|
1024
1052
|
"last" => UniqueKeepStrategy::Last,
|
1025
1053
|
v => {
|
@@ -1035,7 +1063,7 @@ impl TryConvert for Wrap<UniqueKeepStrategy> {
|
|
1035
1063
|
|
1036
1064
|
impl TryConvert for Wrap<SearchSortedSide> {
|
1037
1065
|
fn try_convert(ob: Value) -> RbResult<Self> {
|
1038
|
-
let parsed = match
|
1066
|
+
let parsed = match String::try_convert(ob)?.as_str() {
|
1039
1067
|
"any" => SearchSortedSide::Any,
|
1040
1068
|
"left" => SearchSortedSide::Left,
|
1041
1069
|
"right" => SearchSortedSide::Right,
|