Skip to main content

f_ck/engine/
reader.rs

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        // For now, we'll implement basic XLSX support
46        // This is a simplified implementation - in practice you'd want more robust Excel handling
47        Err(anyhow::anyhow!("XLSX support not yet implemented"))
48    }
49
50    fn read_sqlite(_path: &str) -> Result<LazyFrame> {
51        // SQLite support would require additional SQL parsing or table specification
52        // For now, we'll defer this implementation
53        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}