use std::path::Path;
use crate::{
errors::LoaderError,
orderbooks::{Orderbook, io::ob_parquet::load_parquet_to_ob},
trades::{Trade, io::trades_parquet::read_trades_parquet},
};
pub fn load_orderbooks_from_dir(dir: &Path) -> Result<Vec<Orderbook>, LoaderError> {
let mut paths = collect_parquet_paths(dir)?;
paths.sort();
let mut all_obs: Vec<Orderbook> = Vec::new();
for path in &paths {
let obs = load_parquet_to_ob(path).map_err(|e| {
LoaderError::IoError(format!("Failed to load {}: {}", path.display(), e))
})?;
all_obs.extend(obs);
}
all_obs.sort_by_key(|ob| ob.orderbook_ts);
if all_obs.is_empty() {
return Err(LoaderError::EmptyData);
}
Ok(all_obs)
}
pub fn load_trades_from_dir(dir: &Path) -> Result<Vec<Trade>, LoaderError> {
let mut paths = collect_parquet_paths(dir)?;
paths.sort();
let mut all_trades: Vec<Trade> = Vec::new();
for path in &paths {
let trades = read_trades_parquet(path).map_err(|e| {
LoaderError::IoError(format!("Failed to load {}: {}", path.display(), e))
})?;
all_trades.extend(trades);
}
all_trades.sort_by_key(|t| t.trade_ts);
if all_trades.is_empty() {
return Err(LoaderError::EmptyData);
}
Ok(all_trades)
}
fn collect_parquet_paths(dir: &Path) -> Result<Vec<std::path::PathBuf>, LoaderError> {
if !dir.is_dir() {
return Err(LoaderError::IoError(format!(
"Not a directory: {}",
dir.display()
)));
}
let entries = std::fs::read_dir(dir).map_err(|e| {
LoaderError::IoError(format!("Cannot read directory {}: {}", dir.display(), e))
})?;
let mut paths = Vec::new();
for entry in entries {
let entry = entry
.map_err(|e| LoaderError::IoError(format!("Directory entry error: {}", e)))?;
let path = entry.path();
if path.is_file() {
if let Some(ext) = path.extension() {
if ext == "parquet" {
paths.push(path);
}
}
}
}
Ok(paths)
}