use std::time::Instant;
use clap::{Parser, Subcommand};
use tilezz::combinatorics::collect::{self, CollectKind, Envelope};
use tilezz::geom::tileset::TileSetKind;
use tilezz::util::profile::ProfileGuard;
#[derive(Parser)]
#[command(
name = "tileset_collect",
about = "Collect + validate fixed-point classifications over a tileset"
)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Collect {
#[arg(
long,
default_value = "hex",
help = "hex|square|mixed|tetris|spectre|penrose"
)]
tileset: TileSetKind,
#[arg(long, help = "nbhd|jtype|seq")]
kind: CollectKind,
#[arg(long)]
output: Option<String>,
#[arg(long, help = "Flamegraph output path (requires --features debug)")]
pprof: Option<String>,
},
Validate {
#[arg(long)]
input: String,
},
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Collect {
tileset,
kind,
output,
pprof,
} => {
let profile = ProfileGuard::start(pprof.as_deref());
let payload = collect::run_collect(tileset, kind);
if let Some(path) = output {
let env = Envelope { kind, payload };
let t_write = Instant::now();
let file =
std::fs::File::create(&path).unwrap_or_else(|e| panic!("create {path}: {e}"));
serde_json::to_writer(std::io::BufWriter::new(file), &env)
.unwrap_or_else(|e| panic!("serialize {path}: {e}"));
eprintln!(" Wrote {} in {:.2?}", path, t_write.elapsed());
}
profile.finish();
}
Commands::Validate { input } => {
eprintln!("=== Validating: {} ===", input);
let file = std::fs::File::open(&input).unwrap_or_else(|e| {
eprintln!("Open error: {e}");
std::process::exit(1);
});
let env: Envelope = serde_json::from_reader(std::io::BufReader::new(file))
.unwrap_or_else(|e| {
eprintln!("Parse error: {e}");
std::process::exit(1);
});
match collect::run_validate(env) {
Ok(()) => println!("OK"),
Err(e) => {
eprintln!("FAIL: {e}");
std::process::exit(1);
}
}
}
}
}