use crate::marshal::register_typed_fn_1;
use crate::module_exports::ModuleExports;
use crate::typed_module_exports::{ConcreteReturn, ConcreteType, TypedReturn};
use arrow_ipc::reader::FileReader;
use std::io::Cursor;
use std::sync::Arc;
pub fn create_arrow_module() -> ModuleExports {
let mut module = ModuleExports::new("std::core::arrow");
module.description = "Arrow IPC columnar file reading".to_string();
register_typed_fn_1::<_, Arc<String>>(
&mut module,
"read_table",
"Read the first record batch from an Arrow IPC file",
"path",
"string",
ConcreteType::Result2(
Box::new(ConcreteType::DataTable),
Box::new(ConcreteType::String),
),
|path, ctx| {
crate::module_exports::check_fs_permission(
ctx,
shape_abi_v1::Permission::FsRead,
path.as_str(),
)?;
let bytes = std::fs::read(path.as_str())
.map_err(|e| format!("arrow.read_table() failed to read '{}': {}", path, e))?;
let dt = crate::wire_conversion::datatable_from_ipc_bytes(&bytes, None, None)?;
Ok(TypedReturn::Ok(ConcreteReturn::DataTable(Arc::new(dt))))
},
);
register_typed_fn_1::<_, Arc<String>>(
&mut module,
"read_tables",
"Read all record batches from an Arrow IPC file",
"path",
"string",
ConcreteType::Result2(
Box::new(ConcreteType::ArrayHeapValue("Array<DataTable>".to_string())),
Box::new(ConcreteType::String),
),
|path, _ctx| {
let _ = path; Err(format!(
"arrow.method read_tables() -> SURFACE — `Array<DataTable>` needs a \
typed-array-data DataTable specialized variant in ADR-006 \
§2.7.24 Q25.A's spec list. Tracked as \
W17-typed-carrier-array-datatable follow-up \
(out of bundle-A-followups scope: new TypedArrayData arm \
cascades through exhaustive matches across ~40 files). \
ADR-006 §2.7.24 Q25.A."
))
},
);
register_typed_fn_1::<_, Arc<String>>(
&mut module,
"metadata",
"Read schema metadata from an Arrow IPC file header",
"path",
"string",
ConcreteType::Result2(
Box::new(ConcreteType::HashMapStringString),
Box::new(ConcreteType::String),
),
|path, ctx| {
crate::module_exports::check_fs_permission(
ctx,
shape_abi_v1::Permission::FsRead,
path.as_str(),
)?;
let bytes = std::fs::read(path.as_str())
.map_err(|e| format!("arrow.metadata() failed to read '{}': {}", path, e))?;
let cursor = Cursor::new(bytes);
let reader = FileReader::try_new(cursor, None)
.map_err(|e| format!("arrow.metadata() invalid IPC file: {}", e))?;
let schema = reader.schema();
let meta = schema.metadata();
let pairs: Vec<(String, String)> = meta
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
Ok(TypedReturn::Ok(ConcreteReturn::HashMapStringString(pairs)))
},
);
module
}