use std::env;
use std::path::Path;
use std::process::ExitCode;
use tabkit::{Engine, ReadOptions};
fn main() -> ExitCode {
let Some(path) = env::args().nth(1) else {
eprintln!("usage: inspect <path-to-tabular-file>");
eprintln!();
eprintln!("Supports: .xlsx, .xls, .xlsb, .xlsm, .ods, .csv, .tsv");
eprintln!("With --features parquet: also .parquet");
return ExitCode::FAILURE;
};
let engine = Engine::with_defaults();
let options = ReadOptions::default().max_sample_rows(5);
match engine.read(Path::new(&path), &options) {
Ok(table) => {
print_table(&table);
ExitCode::SUCCESS
}
Err(e) => {
eprintln!("error: {e}");
ExitCode::FAILURE
}
}
}
fn print_table(table: &tabkit::Table) {
println!("Schema:");
if table.columns.is_empty() {
println!(" (empty)");
} else {
let max_name_len = table
.columns
.iter()
.map(|c| c.name.len())
.max()
.unwrap_or(0);
for col in &table.columns {
let null_marker = if col.nullable { " ?" } else { "" };
println!(
" {:<width$} {:?}{}",
col.name,
col.data_type,
null_marker,
width = max_name_len,
);
}
}
if !table.metadata.is_empty() {
println!();
println!("Metadata:");
let mut keys: Vec<&String> = table.metadata.keys().collect();
keys.sort();
for key in keys {
println!(" {key}: {}", table.metadata[key]);
}
}
if let Some(n) = table.row_count {
println!();
println!("Row count: {n} (excluding header)");
}
if !table.sample_rows.is_empty() {
println!();
println!("Sample rows ({}):", table.sample_rows.len());
for (idx, row) in table.sample_rows.iter().enumerate() {
println!(" [{idx}] {row:?}");
}
}
}