use std::path::PathBuf;
use clap::{Args, Parser, Subcommand};
use slideforge::ExtractionOptions;
#[derive(Parser)]
#[command(
name = "slideforge",
version,
about = "Whole-slide image tile extraction"
)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand)]
pub enum Command {
Extract(ExtractArgs),
Dataset(DatasetArgs),
}
#[derive(Args)]
#[group(required = true, multiple = false)]
pub struct LevelSelect {
#[arg(long)]
pub level: Option<usize>,
#[arg(long)]
pub target_mpp: Option<f64>,
}
#[derive(Args)]
#[group(multiple = false)]
pub struct ParallelismArgs {
#[arg(long)]
pub threads: Option<usize>,
#[arg(long)]
pub sequential: bool,
}
#[derive(Args)]
pub struct PipelineArgs {
#[command(flatten)]
pub level: LevelSelect,
#[command(flatten)]
pub parallelism: ParallelismArgs,
#[arg(long)]
pub min_tissue_fraction: Option<f32>,
#[arg(long)]
pub stain_normalize: bool,
#[arg(long, short = 'q')]
pub quiet: bool,
}
impl PipelineArgs {
pub fn build(&self) -> ExtractionOptions {
let mut options = if self.parallelism.sequential {
ExtractionOptions::sequential()
} else if let Some(threads) = self.parallelism.threads {
ExtractionOptions::parallel_with_threads(threads)
} else {
ExtractionOptions::parallel()
};
if let Some(level) = self.level.level {
options = options.with_level(level);
} else if let Some(target_mpp) = self.level.target_mpp {
options = options.with_target_mpp(target_mpp);
}
if let Some(min_fraction) = self.min_tissue_fraction {
options = options.with_min_tissue_fraction(min_fraction);
}
if self.stain_normalize {
options = options.with_stain_normalization();
}
if !self.quiet {
options = options.with_progress_bar();
}
options
}
}
#[derive(Args)]
pub struct ExtractArgs {
pub slide: PathBuf,
#[command(flatten)]
pub pipeline: PipelineArgs,
#[arg(long)]
pub tile_dir: Option<PathBuf>,
#[arg(long)]
pub tfrecord_file: Option<PathBuf>,
#[arg(long)]
pub report: Option<PathBuf>,
}
#[derive(Args)]
pub struct DatasetArgs {
pub dataset_dir: PathBuf,
pub output_root: PathBuf,
#[command(flatten)]
pub pipeline: PipelineArgs,
#[arg(long)]
pub tiles: bool,
#[arg(long)]
pub tile_subdir: Option<PathBuf>,
#[arg(long)]
pub report: Option<PathBuf>,
}