ascap/src/main.rs
Hayden Heroux f64e589058 Read and write to Parquet.
Uses `clap` to parse command line arguments.
"REBERGEN WILLEM" query: 105.1s -> 4.45s. 23x improvement.
2026-09-21 11:53:11 -04:00

83 lines
2.2 KiB
Rust

use clap::{Parser, ValueEnum};
use polars::prelude::*;
use polars_lazy::frame::LazyCsvReader;
use std::sync::Arc;
fn read_csv(path: PlRefPath) -> Result<LazyFrame, PolarsError> {
let schema = Schema::from_iter(vec![
Field::new("Title".into(), DataType::String),
Field::new("RoleType".into(), DataType::String),
Field::new("Name".into(), DataType::String),
Field::new("Shares".into(), DataType::String),
Field::new("Note".into(), DataType::String),
]);
let lf = LazyCsvReader::new(path)
.with_has_header(true)
.with_schema(Some(Arc::new(schema)))
.finish()?;
let with_song_id = lf.with_columns([col("RoleType")
.eq(lit("ASCAP"))
.cast(DataType::Int64)
.cum_sum(false)
.alias("SongID")]);
Ok(with_song_id)
}
fn read_parquet(path: PlRefPath) -> Result<LazyFrame, PolarsError> {
LazyFrame::scan_parquet(path, ScanArgsParquet::default())
}
fn write_parquet(lf: &LazyFrame, path: PlRefPath) -> Result<(), PolarsError> {
let sink = lf.clone().sink(
SinkDestination::File {
target: SinkTarget::Path(path),
},
FileWriteFormat::Parquet(Arc::new(ParquetWriteOptions::default())),
UnifiedSinkArgs::default(),
)?;
sink.collect()?;
Ok(())
}
#[derive(Clone, ValueEnum)]
enum SourceKind {
CSV,
Parquet,
}
#[derive(Parser)]
struct Cli {
source: SourceKind,
from: PlRefPath,
name: String,
to: Option<PlRefPath>,
}
fn main() -> Result<(), PolarsError> {
let args = Cli::parse();
let all_data = match args.source {
SourceKind::CSV => read_csv(args.from)?,
SourceKind::Parquet => read_parquet(args.from)?,
};
if let Some(to) = args.to {
write_parquet(&all_data, to)?;
}
let writer_is_name = col("RoleType")
.eq(lit("W"))
.and(col("Name").str().contains_literal(lit(args.name)));
let song_titles = all_data
.filter(writer_is_name)
.unique(None, UniqueKeepStrategy::Any)
.sort(["Title"], Default::default())
.select([col("SongID"), col("Title")])
.collect()?;
println!("{}", song_titles);
Ok(())
}