use std::env;
use std::ffi::OsString;
pub mod app;
pub mod quirk;
pub mod shape;
mod convert;
mod format_message;
mod interface;
mod legacy;
mod replay;
mod tui;
pub use quirk::QuirkArgs;
pub use shape::ShapeArgs;
pub use crate::engine::{CANBOAT_JSON_VERSION, COPYRIGHT_ID};
pub fn help_footer() -> String {
format!("canboat.json v{CANBOAT_JSON_VERSION}\n{COPYRIGHT_ID}")
}
pub fn log_startup(name: &str, version: &str) {
log::info!("{name} v{version} (canboat.json v{CANBOAT_JSON_VERSION}) {COPYRIGHT_ID}");
}
pub fn canboat_argv() -> Vec<OsString> {
normalize(env::args_os())
}
pub fn normalize<I: IntoIterator<Item = OsString>>(args: I) -> Vec<OsString> {
args.into_iter().map(rewrite_one).collect()
}
fn rewrite_one(arg: OsString) -> OsString {
let Some(s) = arg.to_str() else {
return arg;
};
if !s.starts_with('-') || s.starts_with("--") {
return arg;
}
if s.len() <= 2 {
return arg;
}
let mut chars = s[1..].chars();
let Some(c) = chars.next() else {
return arg;
};
if !c.is_ascii_alphabetic() {
return arg;
}
OsString::from(format!("-{s}"))
}
#[cfg(test)]
mod tests {
use super::*;
fn norm(input: &[&str]) -> Vec<String> {
normalize(input.iter().map(|s| OsString::from(*s)))
.into_iter()
.map(|s| s.to_string_lossy().into_owned())
.collect()
}
#[test]
fn translates_canboat_long_options() {
assert_eq!(
norm(&["analyzer", "-json", "-nv", "-fixtime", "pgn-test"]),
vec!["analyzer", "--json", "--nv", "--fixtime", "pgn-test"]
);
}
#[test]
fn leaves_short_options_alone() {
assert_eq!(
norm(&["bin", "-r", "-w", "-d"]),
vec!["bin", "-r", "-w", "-d"]
);
}
#[test]
fn leaves_double_dash_alone() {
assert_eq!(
norm(&["bin", "--rx", "12,34", "--"]),
vec!["bin", "--rx", "12,34", "--"]
);
}
#[test]
fn leaves_single_dash_alone() {
assert_eq!(norm(&["bin", "-"]), vec!["bin", "-"]);
}
#[test]
fn leaves_negative_numbers_alone() {
assert_eq!(norm(&["bin", "-42", "-0.5"]), vec!["bin", "-42", "-0.5"]);
}
#[test]
fn translates_with_equals() {
assert_eq!(norm(&["bin", "-fixtime=foo"]), vec!["bin", "--fixtime=foo"]);
}
}