1use crate::dsl::Source;
2use anyhow::Result;
3use polars::lazy::frame::LazyFrame;
4use polars::prelude::*;
5
6#[cfg(feature = "csv-support")]
7use polars::prelude::LazyCsvReader;
8
9pub struct DataReader;
10
11impl DataReader {
12 pub fn read_source(source: &Source) -> Result<LazyFrame> {
13 let path = &source.path;
14
15 if !path.exists() {
16 return Err(anyhow::anyhow!("File not found: {}", path.display()));
17 }
18
19 match source.format.as_str() {
20 "csv" => Self::read_csv(&path.to_string_lossy()),
21 "tsv" => Self::read_tsv(&path.to_string_lossy()),
22 "xlsx" => Self::read_xlsx(&path.to_string_lossy()),
23 "sqlite" => Self::read_sqlite(&path.to_string_lossy()),
24 _ => Err(anyhow::anyhow!("Unsupported format: {}", source.format)),
25 }
26 }
27
28 fn read_csv(path: &str) -> Result<LazyFrame> {
29 #[cfg(feature = "csv-support")]
30 {
31 let df = LazyCsvReader::new(PlPath::new(path)).finish().unwrap();
32 Ok(df)
33 }
34 #[cfg(not(feature = "csv-support"))]
35 {
36 Err(anyhow::anyhow!("CSV support not enabled for WASM build"))
37 }
38 }
39
40 fn read_tsv(_path: &str) -> Result<LazyFrame> {
41 Err(anyhow::anyhow!("TSV support not yet implemented"))
42 }
43
44 fn read_xlsx(_path: &str) -> Result<LazyFrame> {
45 Err(anyhow::anyhow!("XLSX support not yet implemented"))
48 }
49
50 fn read_sqlite(_path: &str) -> Result<LazyFrame> {
51 Err(anyhow::anyhow!("SQLite support not yet implemented"))
54 }
55
56 pub fn get_schema(source: &Source) -> Result<Schema> {
57 let mut df = Self::read_source(source)?;
58 Ok((*df.collect_schema()?).clone())
59 }
60
61 pub fn infer_types(source: &Source) -> Result<Vec<(String, DataType)>> {
62 let schema = Self::get_schema(source)?;
63 let types: Vec<(String, DataType)> = schema
64 .iter()
65 .map(|(name, dtype)| (name.to_string(), dtype.clone()))
66 .collect();
67 Ok(types)
68 }
69}