use std::{fmt::Display, ops::RangeInclusive};
use clap::Parser;
static RECURSION_RANGE: RangeInclusive<u8> = 1..=31;
static BALANCE_RANGE: RangeInclusive<f64> = 0. ..=0.5;
pub fn recursion_depth_in_range(s: &str) -> Result<u8, String> {
let recursion_depth: u8 = s.parse().map_err(|_| format!("`{s}` isn't a number"))?;
if RECURSION_RANGE.contains(&recursion_depth) {
Ok(recursion_depth)
} else {
Err(format!(
"recursion range not in range {}-{}",
RECURSION_RANGE.start(),
RECURSION_RANGE.end()
))
}
}
pub fn balance_factor_in_range(s: &str) -> Result<f64, String> {
let factor: f64 = s.parse().map_err(|_| format!("`{s}` isn't a number"))?;
if BALANCE_RANGE.contains(&factor) {
Ok(factor)
} else {
Err(format!(
"balance factor not in range {}-{}",
BALANCE_RANGE.start(),
BALANCE_RANGE.end()
))
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct Arguments {
#[clap(short, long, action)]
pub number_of_threads: Option<usize>,
#[clap(short, long, action)]
pub graph: String,
#[clap(short, long, action)]
pub coordinates: String,
#[clap(short = 'o', long, default_value_t = String::new(), action)]
pub cut_csv: String,
#[clap(short, long, default_value_t = String::new(), action)]
pub assignment_csv: String,
#[clap(short, long, value_parser = balance_factor_in_range, default_value_t = 0.25)]
pub b_factor: f64,
#[clap(short, long, value_parser=recursion_depth_in_range, default_value_t = 1)]
pub recursion_depth: u8,
#[clap(short, long, default_value_t = String::new(), action)]
pub partition_file: String,
#[clap(short, long, default_value_t = 50, action)]
pub minimum_cell_size: usize,
}
impl Display for Arguments {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "command line arguments:")?;
if let Some(number_of_threads) = self.number_of_threads {
writeln!(f, "number_of_threads: {number_of_threads}")?;
}
if !self.partition_file.is_empty() {
writeln!(f, "output partition file: {}", self.partition_file)?;
}
if !self.assignment_csv.is_empty() {
writeln!(f, "assignment csv: {}", self.assignment_csv)?;
}
if !self.cut_csv.is_empty() {
writeln!(f, "cut csv: {}", self.cut_csv)?;
}
writeln!(f, "graph: {}", self.graph)?;
writeln!(f, "coordinates: {}", self.coordinates)?;
writeln!(f, "recursion depth: {}", self.recursion_depth)?;
writeln!(f, "balance factor: {}", self.b_factor)?;
writeln!(f, "minimum_cell_size: {}", self.minimum_cell_size)
}
}