use std::path::Path;
use ::arrow::datatypes::SchemaRef;
use ::arrow::record_batch::RecordBatch;
pub mod arrow;
pub mod parquet;
mod rebatch;
pub use self::arrow::ArrowFormat;
pub use self::parquet::ParquetFormat;
pub type Chunk = RecordBatch;
pub trait ChunkReader: Send {
fn schema(&self) -> SchemaRef;
fn next_chunk(&mut self) -> anyhow::Result<Option<Chunk>>;
}
pub trait ChunkWriter: Send {
fn write(&mut self, chunk: &Chunk) -> anyhow::Result<()>;
fn finish(self: Box<Self>) -> anyhow::Result<()>;
}
pub trait Format: Send + Sync + 'static {
fn extensions(&self) -> &'static [&'static str];
fn open_reader(&self, path: &Path, chunk_rows: usize) -> anyhow::Result<Box<dyn ChunkReader>>;
fn open_writer(&self, path: &Path, schema: SchemaRef) -> anyhow::Result<Box<dyn ChunkWriter>>;
}
pub fn for_path(path: &Path) -> anyhow::Result<Box<dyn Format>> {
let ext = path
.extension()
.and_then(|e| e.to_str())
.unwrap_or_default();
let formats: [Box<dyn Format>; 2] = [Box::new(ArrowFormat), Box::new(ParquetFormat)];
for format in formats {
if format.extensions().contains(&ext) {
return Ok(format);
}
}
anyhow::bail!("no format registered for extension {ext:?}")
}