polars-df 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,
|