use polars::prelude::*;
use RustQuant_error::RustQuantError;
pub struct Data {
pub format: DataFormat,
pub path: String,
pub data: DataFrame,
}
pub enum DataFormat {
CSV,
JSON,
PARQUET,
}
pub trait DataReader {
fn read(&mut self) -> Result<(), RustQuantError>;
}
pub trait DataWriter {
fn write(&mut self) -> Result<(), RustQuantError>;
}
pub trait DataScanner {
fn scan(&mut self) -> Result<LazyFrame, RustQuantError>;
}
impl Data {
pub fn new(format: DataFormat, path: String) -> Self {
Self {
format,
path,
data: DataFrame::default(),
}
}
}
impl DataReader for Data {
fn read(&mut self) -> Result<(), RustQuantError> {
match self.format {
DataFormat::CSV => {
let df = CsvReadOptions::default()
.try_into_reader_with_file_path(Some(self.path.clone().into()))?
.finish()?;
self.data = df;
Ok(())
}
DataFormat::JSON => {
let mut file = std::fs::File::open(&self.path)?;
let df = JsonReader::new(&mut file).finish()?;
self.data = df;
Ok(())
}
DataFormat::PARQUET => {
let mut file = std::fs::File::open(&self.path)?;
let df = ParquetReader::new(&mut file).finish()?;
self.data = df;
Ok(())
}
}
}
}
impl DataWriter for Data {
fn write(&mut self) -> Result<(), RustQuantError> {
match self.format {
DataFormat::CSV => {
let mut file = std::fs::File::create(&self.path)?;
CsvWriter::new(&mut file).finish(&mut self.data)?;
Ok(())
}
DataFormat::JSON => {
let mut file = std::fs::File::create(&self.path)?;
JsonWriter::new(&mut file)
.with_json_format(JsonFormat::Json)
.finish(&mut self.data)?;
Ok(())
}
DataFormat::PARQUET => {
let mut file = std::fs::File::create(&self.path)?;
ParquetWriter::new(&mut file).finish(&mut self.data)?;
Ok(())
}
}
}
}
impl DataScanner for Data {
fn scan(&mut self) -> Result<LazyFrame, RustQuantError> {
match self.format {
DataFormat::CSV => Ok(LazyCsvReader::new(&self.path).finish()?),
DataFormat::JSON => Ok(LazyJsonLineReader::new(self.path.clone()).finish()?),
DataFormat::PARQUET => Ok(LazyFrame::scan_parquet(
&self.path,
ScanArgsParquet::default(),
)?),
}
}
}
#[cfg(test)]
mod test_io {
use super::*;
const READ_PATH: &str = "./src/examples/read";
const WRITE_PATH: &str = "./src/examples/write";
#[test]
fn test_read_write_csv() -> Result<(), RustQuantError> {
let mut data = Data {
format: DataFormat::CSV,
path: format!("{}.csv", READ_PATH), data: DataFrame::default(),
};
data.read()?;
data.path = format!("{}.csv", WRITE_PATH);
data.write()?;
println!("{:?}", data.data);
Ok(())
}
#[test]
fn test_read_write_json() -> Result<(), RustQuantError> {
let mut data = Data {
format: DataFormat::JSON,
path: format!("{}.json", READ_PATH),
data: DataFrame::default(),
};
data.read()?;
data.path = format!("{}.json", WRITE_PATH);
data.write()?;
println!("{:?}", data.data);
Ok(())
}
#[test]
fn test_read_write_parquet() -> Result<(), RustQuantError> {
let mut data = Data {
format: DataFormat::PARQUET,
path: format!("{}.parquet", READ_PATH),
data: DataFrame::default(),
};
data.read()?;
data.path = format!("{}.parquet", WRITE_PATH);
data.write()?;
println!("{:?}", data.data);
Ok(())
}
}