Skip to content

Commit b98c56d

Browse files
committed
List type support added
1 parent 6b25c7e commit b98c56d

File tree

2 files changed

+131
-9
lines changed

2 files changed

+131
-9
lines changed

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub enum Value {
4343
Bool(bool),
4444
Date32(i32),
4545
Date64(i64),
46+
FixedList(Vec<Value>),
47+
List(Vec<Value>),
4648
Null,
4749
Fallback,
4850
}
@@ -71,6 +73,8 @@ impl ToNapiValue for Value {
7173
Value::Time32(value, unit) => ToNapiValue::to_napi_value(env, Ok(format!("{value}_{unit}"))),
7274
Value::Time64(value, unit) => ToNapiValue::to_napi_value(env, Ok(format!("{value}_{unit}"))),
7375
Value::String(s) => ToNapiValue::to_napi_value(env, s),
76+
Value::FixedList(fl) => ToNapiValue::to_napi_value(env, Ok(fl)),
77+
Value::List(l) => ToNapiValue::to_napi_value(env, Ok(l)),
7478
Value::Fallback => ToNapiValue::to_napi_value(env, Ok(FALLBACK_STR)),
7579
}
7680
}

src/serializer/library_serializer.rs

Lines changed: 127 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
use crate::serializer::{FlightResult, SerializerTrait};
22
use crate::Value;
3-
use arrow::array::{
4-
Array, ArrayData, BooleanArray, Date32Array, Date64Array, DurationMicrosecondArray,
5-
DurationMillisecondArray, DurationNanosecondArray, DurationSecondArray, Float16Array,
6-
Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, RecordBatch,
7-
StringArray, StringViewArray, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray,
8-
Time64NanosecondArray, TimestampMicrosecondArray, TimestampMillisecondArray,
9-
TimestampNanosecondArray, TimestampSecondArray, UInt16Array, UInt32Array, UInt64Array,
10-
UInt8Array,
11-
};
3+
use arrow::array::{Array, ArrayData, ArrayRef, BooleanArray, Date32Array, Date64Array, DurationMicrosecondArray, DurationMillisecondArray, DurationNanosecondArray, DurationSecondArray, FixedSizeListArray, Float16Array, Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, LargeListArray, ListArray, RecordBatch, StringArray, StringViewArray, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray, TimestampMicrosecondArray, TimestampMillisecondArray, TimestampNanosecondArray, TimestampSecondArray, UInt16Array, UInt32Array, UInt64Array, UInt8Array};
124
use arrow::datatypes::{DataType, TimeUnit};
135
use napi_derive::napi;
146
use std::collections::HashMap;
@@ -244,6 +236,33 @@ impl LibrarySerializer {
244236
DataType::Time64(time_unit) => {
245237
Self::serialize_time64_column(&array_data, time_unit, row_count, &mut column_values);
246238
}
239+
DataType::FixedSizeList(field, size) => {
240+
let arr = FixedSizeListArray::from(array_data);
241+
let list_size = *size as usize;
242+
243+
for i in 0..row_count {
244+
if arr.is_null(i) {
245+
column_values.push(None);
246+
} else {
247+
let child_array = arr.value(i);
248+
let list_values = Self::extract_fixed_list_values(child_array, field.data_type(), list_size);
249+
column_values.push(Some(Value::FixedList(list_values)));
250+
}
251+
}
252+
}
253+
DataType::List(field) | DataType::LargeList(field) => {
254+
let arr = ListArray::from(array_data);
255+
256+
for i in 0..row_count {
257+
if arr.is_null(i) {
258+
column_values.push(None);
259+
} else {
260+
let child_array = arr.value(i);
261+
let list_values = Self::extract_list_values(child_array, field.data_type());
262+
column_values.push(Some(Value::List(list_values)));
263+
}
264+
}
265+
}
247266
_ => {
248267
column_values.resize(row_count, Some(Value::Fallback));
249268
}
@@ -423,4 +442,103 @@ impl LibrarySerializer {
423442
}
424443
}
425444
}
445+
446+
fn extract_fixed_list_values(array: ArrayRef, data_type: &DataType, size: usize) -> Vec<Value> {
447+
let mut values = Vec::with_capacity(size);
448+
449+
for i in 0..size {
450+
if array.is_null(i) {
451+
values.push(Value::Null);
452+
continue;
453+
}
454+
455+
let value = match data_type {
456+
DataType::Int32 => {
457+
let arr = array.as_any().downcast_ref::<Int32Array>().unwrap();
458+
Value::Int32(arr.value(i))
459+
}
460+
DataType::Int64 => {
461+
let arr = array.as_any().downcast_ref::<Int64Array>().unwrap();
462+
Value::Int64(arr.value(i))
463+
}
464+
DataType::Float32 => {
465+
let arr = array.as_any().downcast_ref::<Float32Array>().unwrap();
466+
Value::F32(arr.value(i))
467+
}
468+
DataType::Float64 => {
469+
let arr = array.as_any().downcast_ref::<Float64Array>().unwrap();
470+
Value::F64(arr.value(i))
471+
}
472+
DataType::Utf8 | DataType::LargeUtf8 => {
473+
let arr = array.as_any().downcast_ref::<StringArray>().unwrap();
474+
Value::String(arr.value(i).to_string())
475+
}
476+
DataType::Boolean => {
477+
let arr = array.as_any().downcast_ref::<BooleanArray>().unwrap();
478+
Value::Bool(arr.value(i))
479+
}
480+
_ => Value::Fallback,
481+
};
482+
483+
values.push(value);
484+
}
485+
486+
values
487+
}
488+
489+
fn extract_list_values(array: ArrayRef, data_type: &DataType) -> Vec<Value> {
490+
let size = array.len();
491+
let mut values = Vec::with_capacity(size);
492+
493+
for i in 0..size {
494+
if array.is_null(i) {
495+
values.push(Value::Null);
496+
continue;
497+
}
498+
499+
let value = match data_type {
500+
DataType::Int32 => {
501+
let arr = array.as_any().downcast_ref::<Int32Array>().unwrap();
502+
Value::Int32(arr.value(i))
503+
}
504+
DataType::Int64 => {
505+
let arr = array.as_any().downcast_ref::<Int64Array>().unwrap();
506+
Value::Int64(arr.value(i))
507+
}
508+
DataType::Float32 => {
509+
let arr = array.as_any().downcast_ref::<Float32Array>().unwrap();
510+
Value::F32(arr.value(i))
511+
}
512+
DataType::Float64 => {
513+
let arr = array.as_any().downcast_ref::<Float64Array>().unwrap();
514+
Value::F64(arr.value(i))
515+
}
516+
DataType::Utf8 | DataType::LargeUtf8 => {
517+
let arr = array.as_any().downcast_ref::<StringArray>().unwrap();
518+
Value::String(arr.value(i).to_string())
519+
}
520+
DataType::Boolean => {
521+
let arr = array.as_any().downcast_ref::<BooleanArray>().unwrap();
522+
Value::Bool(arr.value(i))
523+
}
524+
// Можно добавить рекурсивную обработку вложенных списков
525+
DataType::List(nested_field) => {
526+
let nested_list_array = array.as_any().downcast_ref::<ListArray>().unwrap();
527+
let nested_child = nested_list_array.value(i);
528+
let nested_values = Self::extract_list_values(nested_child, nested_field.data_type());
529+
Value::List(nested_values)
530+
}
531+
DataType::FixedSizeList(nested_field, _) => {
532+
let nested_list_array = array.as_any().downcast_ref::<FixedSizeListArray>().unwrap();
533+
let nested_child = nested_list_array.value(i);
534+
let nested_values = Self::extract_list_values(nested_child, nested_field.data_type());
535+
Value::FixedList(nested_values)
536+
}
537+
_ => Value::Fallback,
538+
};
539+
540+
values.push(value);
541+
}
542+
values
543+
}
426544
}

0 commit comments

Comments
 (0)