use crate::dsl::Source;
use anyhow::Result;
use polars::lazy::frame::LazyFrame;
use polars::prelude::*;
#[cfg(feature = "csv-support")]
use polars::prelude::LazyCsvReader;
pub struct DataReader;
impl DataReader {
pub fn read_source(source: &Source) -> Result<LazyFrame> {
let path = &source.path;
if !path.exists() {
return Err(anyhow::anyhow!("File not found: {}", path.display()));
}
match source.format.as_str() {
"csv" => Self::read_csv(&path.to_string_lossy()),
"tsv" => Self::read_tsv(&path.to_string_lossy()),
"xlsx" => Self::read_xlsx(&path.to_string_lossy()),
"sqlite" => Self::read_sqlite(&path.to_string_lossy()),
_ => Err(anyhow::anyhow!("Unsupported format: {}", source.format)),
}
}
fn read_csv(path: &str) -> Result<LazyFrame> {
#[cfg(feature = "csv-support")]
{
let df = LazyCsvReader::new(PlPath::new(path)).finish().unwrap();
Ok(df)
}
#[cfg(not(feature = "csv-support"))]
{
Err(anyhow::anyhow!("CSV support not enabled for WASM build"))
}
}
fn read_tsv(_path: &str) -> Result<LazyFrame> {
Err(anyhow::anyhow!("TSV support not yet implemented"))
}
fn read_xlsx(_path: &str) -> Result<LazyFrame> {
Err(anyhow::anyhow!("XLSX support not yet implemented"))
}
fn read_sqlite(_path: &str) -> Result<LazyFrame> {
Err(anyhow::anyhow!("SQLite support not yet implemented"))
}
pub fn get_schema(source: &Source) -> Result<Schema> {
let mut df = Self::read_source(source)?;
Ok((*df.collect_schema()?).clone())
}
pub fn infer_types(source: &Source) -> Result<Vec<(String, DataType)>> {
let schema = Self::get_schema(source)?;
let types: Vec<(String, DataType)> = schema
.iter()
.map(|(name, dtype)| (name.to_string(), dtype.clone()))
.collect();
Ok(types)
}
}