polars-df 0.21.0 → 0.22.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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Cargo.lock +55 -48
  4. data/Cargo.toml +3 -0
  5. data/README.md +12 -0
  6. data/ext/polars/Cargo.toml +22 -11
  7. data/ext/polars/src/batched_csv.rs +4 -4
  8. data/ext/polars/src/catalog/unity.rs +96 -94
  9. data/ext/polars/src/conversion/any_value.rs +26 -30
  10. data/ext/polars/src/conversion/chunked_array.rs +32 -28
  11. data/ext/polars/src/conversion/datetime.rs +11 -0
  12. data/ext/polars/src/conversion/mod.rs +307 -34
  13. data/ext/polars/src/dataframe/construction.rs +4 -3
  14. data/ext/polars/src/dataframe/export.rs +17 -15
  15. data/ext/polars/src/dataframe/general.rs +15 -12
  16. data/ext/polars/src/dataframe/io.rs +1 -2
  17. data/ext/polars/src/dataframe/mod.rs +25 -1
  18. data/ext/polars/src/dataframe/serde.rs +23 -8
  19. data/ext/polars/src/exceptions.rs +8 -4
  20. data/ext/polars/src/expr/array.rs +73 -4
  21. data/ext/polars/src/expr/binary.rs +26 -1
  22. data/ext/polars/src/expr/bitwise.rs +39 -0
  23. data/ext/polars/src/expr/categorical.rs +20 -0
  24. data/ext/polars/src/expr/datatype.rs +24 -1
  25. data/ext/polars/src/expr/datetime.rs +58 -14
  26. data/ext/polars/src/expr/general.rs +87 -15
  27. data/ext/polars/src/expr/list.rs +32 -24
  28. data/ext/polars/src/expr/meta.rs +15 -6
  29. data/ext/polars/src/expr/mod.rs +3 -0
  30. data/ext/polars/src/expr/name.rs +19 -14
  31. data/ext/polars/src/expr/rolling.rs +20 -0
  32. data/ext/polars/src/expr/serde.rs +28 -0
  33. data/ext/polars/src/expr/string.rs +64 -10
  34. data/ext/polars/src/expr/struct.rs +9 -1
  35. data/ext/polars/src/file.rs +15 -9
  36. data/ext/polars/src/functions/business.rs +0 -1
  37. data/ext/polars/src/functions/io.rs +25 -3
  38. data/ext/polars/src/functions/lazy.rs +11 -6
  39. data/ext/polars/src/functions/meta.rs +3 -3
  40. data/ext/polars/src/functions/string_cache.rs +3 -3
  41. data/ext/polars/src/interop/arrow/to_ruby.rs +3 -3
  42. data/ext/polars/src/interop/numo/numo_rs.rs +4 -3
  43. data/ext/polars/src/io/mod.rs +6 -0
  44. data/ext/polars/src/lazyframe/general.rs +59 -9
  45. data/ext/polars/src/lazyframe/mod.rs +16 -1
  46. data/ext/polars/src/lazyframe/optflags.rs +58 -0
  47. data/ext/polars/src/lazyframe/serde.rs +27 -3
  48. data/ext/polars/src/lib.rs +261 -19
  49. data/ext/polars/src/map/dataframe.rs +20 -17
  50. data/ext/polars/src/map/lazy.rs +6 -5
  51. data/ext/polars/src/map/series.rs +8 -7
  52. data/ext/polars/src/on_startup.rs +12 -5
  53. data/ext/polars/src/rb_modules.rs +2 -2
  54. data/ext/polars/src/series/aggregation.rs +85 -28
  55. data/ext/polars/src/series/construction.rs +1 -0
  56. data/ext/polars/src/series/export.rs +37 -33
  57. data/ext/polars/src/series/general.rs +120 -21
  58. data/ext/polars/src/series/mod.rs +29 -4
  59. data/lib/polars/array_expr.rb +382 -3
  60. data/lib/polars/array_name_space.rb +281 -0
  61. data/lib/polars/binary_expr.rb +67 -0
  62. data/lib/polars/binary_name_space.rb +43 -0
  63. data/lib/polars/cat_expr.rb +224 -0
  64. data/lib/polars/cat_name_space.rb +138 -0
  65. data/lib/polars/config.rb +2 -2
  66. data/lib/polars/convert.rb +6 -6
  67. data/lib/polars/data_frame.rb +794 -27
  68. data/lib/polars/data_type_expr.rb +52 -0
  69. data/lib/polars/data_types.rb +26 -5
  70. data/lib/polars/date_time_expr.rb +252 -1
  71. data/lib/polars/date_time_name_space.rb +299 -0
  72. data/lib/polars/expr.rb +1248 -206
  73. data/lib/polars/functions/business.rb +95 -0
  74. data/lib/polars/functions/datatype.rb +21 -0
  75. data/lib/polars/functions/lazy.rb +14 -1
  76. data/lib/polars/io/csv.rb +1 -1
  77. data/lib/polars/io/iceberg.rb +27 -0
  78. data/lib/polars/io/json.rb +4 -4
  79. data/lib/polars/io/ndjson.rb +4 -4
  80. data/lib/polars/io/parquet.rb +32 -7
  81. data/lib/polars/io/scan_options.rb +4 -1
  82. data/lib/polars/lazy_frame.rb +1028 -28
  83. data/lib/polars/list_expr.rb +217 -17
  84. data/lib/polars/list_name_space.rb +231 -22
  85. data/lib/polars/meta_expr.rb +89 -0
  86. data/lib/polars/name_expr.rb +36 -0
  87. data/lib/polars/query_opt_flags.rb +50 -0
  88. data/lib/polars/scan_cast_options.rb +20 -1
  89. data/lib/polars/schema.rb +79 -3
  90. data/lib/polars/selector.rb +72 -0
  91. data/lib/polars/selectors.rb +3 -3
  92. data/lib/polars/series.rb +1053 -54
  93. data/lib/polars/string_expr.rb +436 -32
  94. data/lib/polars/string_name_space.rb +736 -50
  95. data/lib/polars/struct_expr.rb +103 -0
  96. data/lib/polars/struct_name_space.rb +19 -1
  97. data/lib/polars/utils/serde.rb +17 -0
  98. data/lib/polars/utils/various.rb +22 -1
  99. data/lib/polars/utils.rb +5 -1
  100. data/lib/polars/version.rb +1 -1
  101. data/lib/polars.rb +6 -0
  102. metadata +11 -1
@@ -1,7 +1,7 @@
1
1
  use std::str::FromStr;
2
2
 
3
3
  use magnus::value::{Lazy, ReprValue};
4
- use magnus::{IntoValue, Module, RArray, RClass, RHash, RModule, Ruby, Value};
4
+ use magnus::{IntoValue, Module, RClass, RHash, RModule, Ruby, Value};
5
5
  use polars::prelude::{PlHashMap, PlSmallStr, Schema};
6
6
  use polars_io::catalog::unity::client::{CatalogClient, CatalogClientBuilder};
7
7
  use polars_io::catalog::unity::models::{
@@ -85,15 +85,15 @@ impl RbCatalogClient {
85
85
  builder.build().map(RbCatalogClient).map_err(to_rb_err)
86
86
  }
87
87
 
88
- pub fn list_catalogs(&self) -> RbResult<Value> {
88
+ pub fn list_catalogs(ruby: &Ruby, rb_self: &Self) -> RbResult<Value> {
89
89
  let v = pl_async::get_runtime()
90
- .block_in_place_on(self.client().list_catalogs())
90
+ .block_in_place_on(rb_self.client().list_catalogs())
91
91
  .map_err(to_rb_err)?;
92
92
 
93
93
  let mut opt_err = None;
94
94
 
95
- let out = RArray::from_iter(v.into_iter().map(|x| {
96
- let v = catalog_info_to_rbobject(x);
95
+ let out = ruby.ary_from_iter(v.into_iter().map(|x| {
96
+ let v = catalog_info_to_rbobject(ruby, x);
97
97
  if let Ok(v) = v {
98
98
  Some(v)
99
99
  } else {
@@ -104,18 +104,18 @@ impl RbCatalogClient {
104
104
 
105
105
  opt_err.transpose()?;
106
106
 
107
- Ok(out.into_value())
107
+ Ok(out.as_value())
108
108
  }
109
109
 
110
- pub fn list_namespaces(&self, catalog_name: String) -> RbResult<Value> {
110
+ pub fn list_namespaces(ruby: &Ruby, rb_self: &Self, catalog_name: String) -> RbResult<Value> {
111
111
  let v = pl_async::get_runtime()
112
- .block_in_place_on(self.client().list_namespaces(&catalog_name))
112
+ .block_in_place_on(rb_self.client().list_namespaces(&catalog_name))
113
113
  .map_err(to_rb_err)?;
114
114
 
115
115
  let mut opt_err = None;
116
116
 
117
- let out = RArray::from_iter(v.into_iter().map(|x| {
118
- let v = namespace_info_to_rbobject(x);
117
+ let out = ruby.ary_from_iter(v.into_iter().map(|x| {
118
+ let v = namespace_info_to_rbobject(ruby, x);
119
119
  match v {
120
120
  Ok(v) => Some(v),
121
121
  Err(_) => {
@@ -127,27 +127,33 @@ impl RbCatalogClient {
127
127
 
128
128
  opt_err.transpose()?;
129
129
 
130
- Ok(out.into_value())
130
+ Ok(out.as_value())
131
131
  }
132
132
 
133
- pub fn list_tables(&self, catalog_name: String, namespace: String) -> RbResult<Value> {
133
+ pub fn list_tables(
134
+ ruby: &Ruby,
135
+ rb_self: &Self,
136
+ catalog_name: String,
137
+ namespace: String,
138
+ ) -> RbResult<Value> {
134
139
  let v = pl_async::get_runtime()
135
- .block_in_place_on(self.client().list_tables(&catalog_name, &namespace))
140
+ .block_in_place_on(rb_self.client().list_tables(&catalog_name, &namespace))
136
141
  .map_err(to_rb_err)?;
137
142
 
138
143
  let mut opt_err = None;
139
144
 
140
- let out = RArray::from_iter(v.into_iter().map(|table_info| {
141
- let v = table_info_to_rbobject(table_info);
145
+ let out = ruby
146
+ .ary_from_iter(v.into_iter().map(|table_info| {
147
+ let v = table_info_to_rbobject(ruby, table_info);
142
148
 
143
- if let Ok(v) = v {
144
- Some(v)
145
- } else {
146
- opt_err.replace(v);
147
- None
148
- }
149
- }))
150
- .into_value();
149
+ if let Ok(v) = v {
150
+ Some(v)
151
+ } else {
152
+ opt_err.replace(v);
153
+ None
154
+ }
155
+ }))
156
+ .as_value();
151
157
 
152
158
  opt_err.transpose()?;
153
159
 
@@ -155,36 +161,39 @@ impl RbCatalogClient {
155
161
  }
156
162
 
157
163
  pub fn get_table_info(
158
- &self,
164
+ ruby: &Ruby,
165
+ rb_self: &Self,
159
166
  table_name: String,
160
167
  catalog_name: String,
161
168
  namespace: String,
162
169
  ) -> RbResult<Value> {
163
170
  let table_info = pl_async::get_runtime()
164
- .block_in_place_on(
165
- self.client()
166
- .get_table_info(&table_name, &catalog_name, &namespace),
167
- )
171
+ .block_in_place_on(rb_self.client().get_table_info(
172
+ &table_name,
173
+ &catalog_name,
174
+ &namespace,
175
+ ))
168
176
  .map_err(to_rb_err)?;
169
177
 
170
- table_info_to_rbobject(table_info)
178
+ table_info_to_rbobject(ruby, table_info)
171
179
  }
172
180
 
173
181
  pub fn create_catalog(
174
- &self,
182
+ ruby: &Ruby,
183
+ rb_self: &Self,
175
184
  catalog_name: String,
176
185
  comment: Option<String>,
177
186
  storage_root: Option<String>,
178
187
  ) -> RbResult<Value> {
179
188
  let catalog_info = pl_async::get_runtime()
180
- .block_in_place_on(self.client().create_catalog(
189
+ .block_in_place_on(rb_self.client().create_catalog(
181
190
  &catalog_name,
182
191
  comment.as_deref(),
183
192
  storage_root.as_deref(),
184
193
  ))
185
194
  .map_err(to_rb_err)?;
186
195
 
187
- catalog_info_to_rbobject(catalog_info)
196
+ catalog_info_to_rbobject(ruby, catalog_info)
188
197
  }
189
198
 
190
199
  pub fn delete_catalog(&self, catalog_name: String, force: bool) -> RbResult<()> {
@@ -194,14 +203,15 @@ impl RbCatalogClient {
194
203
  }
195
204
 
196
205
  pub fn create_namespace(
197
- &self,
206
+ ruby: &Ruby,
207
+ rb_self: &Self,
198
208
  catalog_name: String,
199
209
  namespace: String,
200
210
  comment: Option<String>,
201
211
  storage_root: Option<String>,
202
212
  ) -> RbResult<Value> {
203
213
  let namespace_info = pl_async::get_runtime()
204
- .block_in_place_on(self.client().create_namespace(
214
+ .block_in_place_on(rb_self.client().create_namespace(
205
215
  &catalog_name,
206
216
  &namespace,
207
217
  comment.as_deref(),
@@ -209,7 +219,7 @@ impl RbCatalogClient {
209
219
  ))
210
220
  .map_err(to_rb_err)?;
211
221
 
212
- namespace_info_to_rbobject(namespace_info)
222
+ namespace_info_to_rbobject(ruby, namespace_info)
213
223
  }
214
224
 
215
225
  pub fn delete_namespace(
@@ -228,7 +238,8 @@ impl RbCatalogClient {
228
238
 
229
239
  #[allow(clippy::too_many_arguments)]
230
240
  pub fn create_table(
231
- &self,
241
+ ruby: &Ruby,
242
+ rb_self: &Self,
232
243
  catalog_name: String,
233
244
  namespace: String,
234
245
  table_name: String,
@@ -241,7 +252,7 @@ impl RbCatalogClient {
241
252
  ) -> RbResult<Value> {
242
253
  let table_info = pl_async::get_runtime()
243
254
  .block_in_place_on(
244
- self.client().create_table(
255
+ rb_self.client().create_table(
245
256
  &catalog_name,
246
257
  &namespace,
247
258
  &table_name,
@@ -261,7 +272,7 @@ impl RbCatalogClient {
261
272
  )
262
273
  .map_err(to_rb_err)?;
263
274
 
264
- table_info_to_rbobject(table_info)
275
+ table_info_to_rbobject(ruby, table_info)
265
276
  }
266
277
 
267
278
  pub fn delete_table(
@@ -278,8 +289,8 @@ impl RbCatalogClient {
278
289
  .map_err(to_rb_err)
279
290
  }
280
291
 
281
- pub fn type_json_to_polars_type(type_json: String) -> RbResult<Value> {
282
- Ok(Wrap(parse_type_json_str(&type_json).map_err(to_rb_err)?).into_value())
292
+ pub fn type_json_to_polars_type(ruby: &Ruby, type_json: String) -> RbResult<Value> {
293
+ Ok(Wrap(parse_type_json_str(&type_json).map_err(to_rb_err)?).into_value_with(ruby))
283
294
  }
284
295
  }
285
296
 
@@ -290,6 +301,7 @@ impl RbCatalogClient {
290
301
  }
291
302
 
292
303
  fn catalog_info_to_rbobject(
304
+ ruby: &Ruby,
293
305
  CatalogInfo {
294
306
  name,
295
307
  comment,
@@ -302,10 +314,10 @@ fn catalog_info_to_rbobject(
302
314
  updated_by,
303
315
  }: CatalogInfo,
304
316
  ) -> RbResult<Value> {
305
- let dict = RHash::new();
317
+ let dict = ruby.hash_new();
306
318
 
307
- let properties = properties_to_rbobject(properties);
308
- let options = properties_to_rbobject(options);
319
+ let properties = properties_to_rbobject(ruby, properties);
320
+ let options = properties_to_rbobject(ruby, options);
309
321
 
310
322
  rbdict_insert_keys!(dict, {
311
323
  name,
@@ -319,13 +331,11 @@ fn catalog_info_to_rbobject(
319
331
  updated_by
320
332
  });
321
333
 
322
- Ruby::get()
323
- .unwrap()
324
- .get_inner(&CATALOG_INFO_CLS)
325
- .funcall("new", (dict,))
334
+ ruby.get_inner(&CATALOG_INFO_CLS).funcall("new", (dict,))
326
335
  }
327
336
 
328
337
  fn namespace_info_to_rbobject(
338
+ ruby: &Ruby,
329
339
  NamespaceInfo {
330
340
  name,
331
341
  comment,
@@ -337,9 +347,9 @@ fn namespace_info_to_rbobject(
337
347
  updated_by,
338
348
  }: NamespaceInfo,
339
349
  ) -> RbResult<Value> {
340
- let dict = RHash::new();
350
+ let dict = ruby.hash_new();
341
351
 
342
- let properties = properties_to_rbobject(properties);
352
+ let properties = properties_to_rbobject(ruby, properties);
343
353
 
344
354
  rbdict_insert_keys!(dict, {
345
355
  name,
@@ -352,13 +362,10 @@ fn namespace_info_to_rbobject(
352
362
  updated_by
353
363
  });
354
364
 
355
- Ruby::get()
356
- .unwrap()
357
- .get_inner(&NAMESPACE_INFO_CLS)
358
- .funcall("new", (dict,))
365
+ ruby.get_inner(&NAMESPACE_INFO_CLS).funcall("new", (dict,))
359
366
  }
360
367
 
361
- fn table_info_to_rbobject(table_info: TableInfo) -> RbResult<Value> {
368
+ fn table_info_to_rbobject(ruby: &Ruby, table_info: TableInfo) -> RbResult<Value> {
362
369
  let TableInfo {
363
370
  name,
364
371
  table_id,
@@ -374,49 +381,47 @@ fn table_info_to_rbobject(table_info: TableInfo) -> RbResult<Value> {
374
381
  updated_by,
375
382
  } = table_info;
376
383
 
377
- let column_info_cls = Ruby::get().unwrap().get_inner(&COLUMN_INFO_CLS);
384
+ let column_info_cls = ruby.get_inner(&COLUMN_INFO_CLS);
378
385
 
379
386
  let columns = columns
380
387
  .map(|columns| {
381
- Ruby::get()
382
- .unwrap()
383
- .ary_try_from_iter(columns.into_iter().map(
384
- |ColumnInfo {
385
- name,
386
- type_name,
387
- type_text,
388
- type_json,
389
- position,
390
- comment,
391
- partition_index,
392
- }| {
393
- let dict = RHash::new();
394
-
395
- let name = name.as_str();
396
- let type_name = type_name.as_str();
397
- let type_text = type_text.as_str();
398
-
399
- rbdict_insert_keys!(dict, {
400
- name,
401
- type_name,
402
- type_text,
403
- type_json,
404
- position,
405
- comment,
406
- partition_index,
407
- });
408
-
409
- column_info_cls.funcall::<_, _, Value>("new", (dict,))
410
- },
411
- ))
388
+ ruby.ary_try_from_iter(columns.into_iter().map(
389
+ |ColumnInfo {
390
+ name,
391
+ type_name,
392
+ type_text,
393
+ type_json,
394
+ position,
395
+ comment,
396
+ partition_index,
397
+ }| {
398
+ let dict = ruby.hash_new();
399
+
400
+ let name = name.as_str();
401
+ let type_name = type_name.as_str();
402
+ let type_text = type_text.as_str();
403
+
404
+ rbdict_insert_keys!(dict, {
405
+ name,
406
+ type_name,
407
+ type_text,
408
+ type_json,
409
+ position,
410
+ comment,
411
+ partition_index,
412
+ });
413
+
414
+ column_info_cls.funcall::<_, _, Value>("new", (dict,))
415
+ },
416
+ ))
412
417
  })
413
418
  .transpose()?;
414
419
 
415
- let dict = RHash::new();
420
+ let dict = ruby.hash_new();
416
421
 
417
422
  let data_source_format = data_source_format.map(|x| x.to_string());
418
423
  let table_type = table_type.to_string();
419
- let properties = properties_to_rbobject(properties);
424
+ let properties = properties_to_rbobject(ruby, properties);
420
425
 
421
426
  rbdict_insert_keys!(dict, {
422
427
  name,
@@ -433,14 +438,11 @@ fn table_info_to_rbobject(table_info: TableInfo) -> RbResult<Value> {
433
438
  updated_by,
434
439
  });
435
440
 
436
- Ruby::get()
437
- .unwrap()
438
- .get_inner(&TABLE_INFO_CLS)
439
- .funcall("new", (dict,))
441
+ ruby.get_inner(&TABLE_INFO_CLS).funcall("new", (dict,))
440
442
  }
441
443
 
442
- fn properties_to_rbobject(properties: PlHashMap<PlSmallStr, String>) -> RHash {
443
- let dict = RHash::new();
444
+ fn properties_to_rbobject(ruby: &Ruby, properties: PlHashMap<PlSmallStr, String>) -> RHash {
445
+ let dict = ruby.hash_new();
444
446
 
445
447
  for (key, value) in properties.into_iter() {
446
448
  dict.aset(key.as_str(), value).unwrap();
@@ -1,14 +1,15 @@
1
- use magnus::encoding::{EncodingCapable, Index};
1
+ use magnus::encoding::EncodingCapable;
2
2
  use magnus::{
3
- IntoValue, RArray, RHash, RString, Ruby, TryConvert, Value, class, prelude::*, r_hash::ForEach,
3
+ IntoValue, RArray, RHash, RString, Ruby, TryConvert, Value, prelude::*, r_hash::ForEach,
4
4
  };
5
5
  use polars::prelude::*;
6
6
  use polars_core::utils::any_values_to_supertype_and_n_dtypes;
7
7
 
8
+ use super::datetime::datetime_to_rb_object;
8
9
  use super::{ObjectValue, Wrap, struct_dict};
9
10
 
10
11
  use crate::exceptions::RbOverflowError;
11
- use crate::rb_modules::utils;
12
+ use crate::rb_modules::pl_utils;
12
13
  use crate::{RbErr, RbPolarsErr, RbResult, RbSeries};
13
14
 
14
15
  impl IntoValue for Wrap<AnyValue<'_>> {
@@ -33,7 +34,7 @@ pub(crate) fn any_value_into_rb_object(av: AnyValue, ruby: &Ruby) -> Value {
33
34
  AnyValue::Int16(v) => ruby.into_value(v),
34
35
  AnyValue::Int32(v) => ruby.into_value(v),
35
36
  AnyValue::Int64(v) => ruby.into_value(v),
36
- AnyValue::Int128(_v) => todo!(),
37
+ AnyValue::Int128(v) => ruby.into_value(v),
37
38
  AnyValue::Float32(v) => ruby.into_value(v),
38
39
  AnyValue::Float64(v) => ruby.into_value(v),
39
40
  AnyValue::Null => ruby.qnil().as_value(),
@@ -41,12 +42,12 @@ pub(crate) fn any_value_into_rb_object(av: AnyValue, ruby: &Ruby) -> Value {
41
42
  AnyValue::String(v) => ruby.into_value(v),
42
43
  AnyValue::StringOwned(v) => ruby.into_value(v.as_str()),
43
44
  AnyValue::Categorical(cat, map) | AnyValue::Enum(cat, map) => unsafe {
44
- map.cat_to_str_unchecked(cat).into_value()
45
+ map.cat_to_str_unchecked(cat).into_value_with(ruby)
45
46
  },
46
47
  AnyValue::CategoricalOwned(cat, map) | AnyValue::EnumOwned(cat, map) => unsafe {
47
- map.cat_to_str_unchecked(cat).into_value()
48
+ map.cat_to_str_unchecked(cat).into_value_with(ruby)
48
49
  },
49
- AnyValue::Date(v) => utils().funcall("_to_ruby_date", (v,)).unwrap(),
50
+ AnyValue::Date(v) => pl_utils().funcall("_to_ruby_date", (v,)).unwrap(),
50
51
  AnyValue::Datetime(v, time_unit, time_zone) => {
51
52
  datetime_to_rb_object(v, time_unit, time_zone)
52
53
  }
@@ -55,14 +56,14 @@ pub(crate) fn any_value_into_rb_object(av: AnyValue, ruby: &Ruby) -> Value {
55
56
  }
56
57
  AnyValue::Duration(v, time_unit) => {
57
58
  let time_unit = time_unit.to_ascii();
58
- utils()
59
+ pl_utils()
59
60
  .funcall("_to_ruby_duration", (v, time_unit))
60
61
  .unwrap()
61
62
  }
62
- AnyValue::Time(v) => utils().funcall("_to_ruby_time", (v,)).unwrap(),
63
- AnyValue::Array(v, _) | AnyValue::List(v) => RbSeries::new(v).to_a().into_value(),
64
- ref av @ AnyValue::Struct(_, _, flds) => struct_dict(av._iter_struct_av(), flds),
65
- AnyValue::StructOwned(payload) => struct_dict(payload.0.into_iter(), &payload.1),
63
+ AnyValue::Time(v) => pl_utils().funcall("_to_ruby_time", (v,)).unwrap(),
64
+ AnyValue::Array(v, _) | AnyValue::List(v) => RbSeries::new(v).to_a().as_value(),
65
+ ref av @ AnyValue::Struct(_, _, flds) => struct_dict(ruby, av._iter_struct_av(), flds),
66
+ AnyValue::StructOwned(payload) => struct_dict(ruby, payload.0.into_iter(), &payload.1),
66
67
  AnyValue::Object(v) => {
67
68
  let object = v.as_any().downcast_ref::<ObjectValue>().unwrap();
68
69
  object.to_value()
@@ -71,21 +72,14 @@ pub(crate) fn any_value_into_rb_object(av: AnyValue, ruby: &Ruby) -> Value {
71
72
  let object = v.0.as_any().downcast_ref::<ObjectValue>().unwrap();
72
73
  object.to_value()
73
74
  }
74
- AnyValue::Binary(v) => RString::from_slice(v).into_value(),
75
- AnyValue::BinaryOwned(v) => RString::from_slice(&v).into_value(),
76
- AnyValue::Decimal(v, scale) => utils()
75
+ AnyValue::Binary(v) => ruby.str_from_slice(v).as_value(),
76
+ AnyValue::BinaryOwned(v) => ruby.str_from_slice(&v).as_value(),
77
+ AnyValue::Decimal(v, scale) => pl_utils()
77
78
  .funcall("_to_ruby_decimal", (v.to_string(), -(scale as i32)))
78
79
  .unwrap(),
79
80
  }
80
81
  }
81
82
 
82
- fn datetime_to_rb_object(v: i64, tu: TimeUnit, tz: Option<&TimeZone>) -> Value {
83
- let tu = tu.to_ascii();
84
- utils()
85
- .funcall("_to_ruby_datetime", (v, tu, tz.map(|v| v.to_string())))
86
- .unwrap()
87
- }
88
-
89
83
  pub(crate) fn rb_object_to_any_value<'s>(ob: Value, strict: bool) -> RbResult<AnyValue<'s>> {
90
84
  // Conversion functions.
91
85
  fn get_null(_ob: Value, _strict: bool) -> RbResult<AnyValue<'static>> {
@@ -117,8 +111,9 @@ pub(crate) fn rb_object_to_any_value<'s>(ob: Value, strict: bool) -> RbResult<An
117
111
  }
118
112
 
119
113
  fn get_str(ob: Value, _strict: bool) -> RbResult<AnyValue<'static>> {
114
+ let ruby = Ruby::get_with(ob);
120
115
  let v = RString::from_value(ob).unwrap();
121
- if v.enc_get() == Index::utf8() {
116
+ if v.enc_get() == ruby.utf8_encindex() {
122
117
  Ok(AnyValue::StringOwned(v.to_string()?.into()))
123
118
  } else {
124
119
  Ok(AnyValue::BinaryOwned(unsafe { v.as_slice() }.to_vec()))
@@ -237,24 +232,25 @@ pub(crate) fn rb_object_to_any_value<'s>(ob: Value, strict: bool) -> RbResult<An
237
232
  Ok(AnyValue::Decimal(v, scale))
238
233
  }
239
234
 
235
+ let ruby = Ruby::get_with(ob);
240
236
  if ob.is_nil() {
241
237
  get_null(ob, strict)
242
- } else if ob.is_kind_of(class::true_class()) || ob.is_kind_of(class::false_class()) {
238
+ } else if ob.is_kind_of(ruby.class_true_class()) || ob.is_kind_of(ruby.class_false_class()) {
243
239
  get_bool(ob, strict)
244
- } else if ob.is_kind_of(class::integer()) {
240
+ } else if ob.is_kind_of(ruby.class_integer()) {
245
241
  get_int(ob, strict)
246
- } else if ob.is_kind_of(class::float()) {
242
+ } else if ob.is_kind_of(ruby.class_float()) {
247
243
  get_float(ob, strict)
248
- } else if ob.is_kind_of(class::string()) {
244
+ } else if ob.is_kind_of(ruby.class_string()) {
249
245
  get_str(ob, strict)
250
- } else if ob.is_kind_of(class::array()) {
246
+ } else if ob.is_kind_of(ruby.class_array()) {
251
247
  get_list(ob, strict)
252
- } else if ob.is_kind_of(class::hash()) {
248
+ } else if ob.is_kind_of(ruby.class_hash()) {
253
249
  get_struct(ob, strict)
254
250
  } else if ob.respond_to("_s", true)? {
255
251
  get_list_from_series(ob, strict)
256
252
  // call is_a? for ActiveSupport::TimeWithZone
257
- } else if ob.funcall::<_, _, bool>("is_a?", (class::time(),))? {
253
+ } else if ob.funcall::<_, _, bool>("is_a?", (ruby.class_time(),))? {
258
254
  get_time(ob, strict)
259
255
  } else if ob.is_kind_of(crate::rb_modules::datetime()) {
260
256
  get_datetime(ob, strict)
@@ -1,10 +1,10 @@
1
- use magnus::{IntoValue, RArray, RString, Ruby, TryConvert, Value, prelude::*};
1
+ use magnus::{IntoValue, RString, Ruby, TryConvert, Value, prelude::*};
2
2
  use polars::prelude::*;
3
3
 
4
4
  use super::{Wrap, get_rbseq, struct_dict};
5
5
 
6
6
  use crate::RbResult;
7
- use crate::rb_modules::utils;
7
+ use crate::rb_modules::pl_utils;
8
8
 
9
9
  impl TryConvert for Wrap<StringChunked> {
10
10
  fn try_convert(obj: Value) -> RbResult<Self> {
@@ -39,19 +39,19 @@ impl TryConvert for Wrap<BinaryChunked> {
39
39
  }
40
40
 
41
41
  impl IntoValue for Wrap<&StringChunked> {
42
- fn into_value_with(self, _: &Ruby) -> Value {
42
+ fn into_value_with(self, ruby: &Ruby) -> Value {
43
43
  let iter = self.0.into_iter();
44
- RArray::from_iter(iter).into_value()
44
+ ruby.ary_from_iter(iter).as_value()
45
45
  }
46
46
  }
47
47
 
48
48
  impl IntoValue for Wrap<&BinaryChunked> {
49
- fn into_value_with(self, _: &Ruby) -> Value {
49
+ fn into_value_with(self, ruby: &Ruby) -> Value {
50
50
  let iter = self
51
51
  .0
52
52
  .into_iter()
53
- .map(|opt_bytes| opt_bytes.map(RString::from_slice));
54
- RArray::from_iter(iter).into_value()
53
+ .map(|opt_bytes| opt_bytes.map(|v| ruby.str_from_slice(v)));
54
+ ruby.ary_from_iter(iter).as_value()
55
55
  }
56
56
  }
57
57
 
@@ -62,19 +62,19 @@ impl IntoValue for Wrap<&StructChunked> {
62
62
  // make series::iter() accept a chunk index.
63
63
  let s = s.rechunk();
64
64
  let iter = s.iter().map(|av| match av {
65
- AnyValue::Struct(_, _, flds) => struct_dict(av._iter_struct_av(), flds),
65
+ AnyValue::Struct(_, _, flds) => struct_dict(ruby, av._iter_struct_av(), flds),
66
66
  AnyValue::Null => ruby.qnil().as_value(),
67
67
  _ => unreachable!(),
68
68
  });
69
69
 
70
- RArray::from_iter(iter).into_value()
70
+ ruby.ary_from_iter(iter).as_value()
71
71
  }
72
72
  }
73
73
 
74
74
  impl IntoValue for Wrap<&DurationChunked> {
75
- fn into_value_with(self, _: &Ruby) -> Value {
76
- let utils = utils();
77
- let time_unit = Wrap(self.0.time_unit()).into_value();
75
+ fn into_value_with(self, ruby: &Ruby) -> Value {
76
+ let utils = pl_utils();
77
+ let time_unit = Wrap(self.0.time_unit()).into_value_with(ruby);
78
78
  let iter = self.0.physical().into_iter().map(|opt_v| {
79
79
  opt_v.map(|v| {
80
80
  utils
@@ -82,15 +82,19 @@ impl IntoValue for Wrap<&DurationChunked> {
82
82
  .unwrap()
83
83
  })
84
84
  });
85
- RArray::from_iter(iter).into_value()
85
+ ruby.ary_from_iter(iter).as_value()
86
86
  }
87
87
  }
88
88
 
89
89
  impl IntoValue for Wrap<&DatetimeChunked> {
90
- fn into_value_with(self, _: &Ruby) -> Value {
91
- let utils = utils();
92
- let time_unit = Wrap(self.0.time_unit()).into_value();
93
- let time_zone = self.0.time_zone().as_deref().map(|v| v.into_value());
90
+ fn into_value_with(self, ruby: &Ruby) -> Value {
91
+ let utils = pl_utils();
92
+ let time_unit = Wrap(self.0.time_unit()).into_value_with(ruby);
93
+ let time_zone = self
94
+ .0
95
+ .time_zone()
96
+ .as_deref()
97
+ .map(|v| v.into_value_with(ruby));
94
98
  let iter = self.0.physical().into_iter().map(|opt_v| {
95
99
  opt_v.map(|v| {
96
100
  utils
@@ -98,34 +102,34 @@ impl IntoValue for Wrap<&DatetimeChunked> {
98
102
  .unwrap()
99
103
  })
100
104
  });
101
- RArray::from_iter(iter).into_value()
105
+ ruby.ary_from_iter(iter).as_value()
102
106
  }
103
107
  }
104
108
 
105
109
  impl IntoValue for Wrap<&TimeChunked> {
106
- fn into_value_with(self, _: &Ruby) -> Value {
107
- let utils = utils();
110
+ fn into_value_with(self, ruby: &Ruby) -> Value {
111
+ let utils = pl_utils();
108
112
  let iter = self.0.physical().into_iter().map(|opt_v| {
109
113
  opt_v.map(|v| utils.funcall::<_, _, Value>("_to_ruby_time", (v,)).unwrap())
110
114
  });
111
- RArray::from_iter(iter).into_value()
115
+ ruby.ary_from_iter(iter).as_value()
112
116
  }
113
117
  }
114
118
 
115
119
  impl IntoValue for Wrap<&DateChunked> {
116
- fn into_value_with(self, _: &Ruby) -> Value {
117
- let utils = utils();
120
+ fn into_value_with(self, ruby: &Ruby) -> Value {
121
+ let utils = pl_utils();
118
122
  let iter = self.0.physical().into_iter().map(|opt_v| {
119
123
  opt_v.map(|v| utils.funcall::<_, _, Value>("_to_ruby_date", (v,)).unwrap())
120
124
  });
121
- RArray::from_iter(iter).into_value()
125
+ ruby.ary_from_iter(iter).as_value()
122
126
  }
123
127
  }
124
128
 
125
129
  impl IntoValue for Wrap<&DecimalChunked> {
126
- fn into_value_with(self, _: &Ruby) -> Value {
127
- let utils = utils();
128
- let rb_scale = (-(self.0.scale() as i32)).into_value();
130
+ fn into_value_with(self, ruby: &Ruby) -> Value {
131
+ let utils = pl_utils();
132
+ let rb_scale = (-(self.0.scale() as i32)).into_value_with(ruby);
129
133
  let iter = self.0.physical().into_iter().map(|opt_v| {
130
134
  opt_v.map(|v| {
131
135
  utils
@@ -133,6 +137,6 @@ impl IntoValue for Wrap<&DecimalChunked> {
133
137
  .unwrap()
134
138
  })
135
139
  });
136
- RArray::from_iter(iter).into_value()
140
+ ruby.ary_from_iter(iter).as_value()
137
141
  }
138
142
  }
@@ -0,0 +1,11 @@
1
+ use magnus::{Value, prelude::*};
2
+ use polars::prelude::*;
3
+
4
+ use crate::rb_modules::pl_utils;
5
+
6
+ pub fn datetime_to_rb_object(v: i64, tu: TimeUnit, tz: Option<&TimeZone>) -> Value {
7
+ let tu = tu.to_ascii();
8
+ pl_utils()
9
+ .funcall("_to_ruby_datetime", (v, tu, tz.map(|v| v.to_string())))
10
+ .unwrap()
11
+ }