pub(crate) const RENAMES: &[(&str, &str)] = &[
("max_model_len", "max-seq-len"),
("tensor_parallel", "tp-size"),
("host", "bind"),
];
const NOT_FLAGS: &[&str] = &[];
pub fn flag_for(key: &str) -> Option<String> {
if NOT_FLAGS.contains(&key) {
return None;
}
if let Some((_, flag)) = RENAMES.iter().find(|(k, _)| *k == key) {
return Some((*flag).to_string());
}
Some(key.replace('_', "-"))
}
pub fn argv_for(key: &str, value: &str) -> Option<Vec<String>> {
let flag = flag_for(key)?;
let dashed = format!("--{flag}");
match value {
"true" if presence_only(&flag) => Some(vec![dashed]),
"false" if presence_only(&flag) => None,
other => Some(vec![dashed, other.to_string()]),
}
}
pub fn check_recipe_default(key: &str, value: &str) -> Result<(), String> {
let Some(flag) = flag_for(key) else {
return Ok(());
};
if !presence_only(&flag) {
return Ok(());
}
match value {
"true" => Ok(()),
"false" => Err(format!(
"defaults.{key}: false restates the default of --{flag}; a boolean flag is \
off unless given, so delete the line (write `{key}: true` to turn it on)"
)),
other => Err(format!(
"defaults.{key}: --{flag} takes no value, so {other:?} means nothing; write \
`{key}: true` to set it or delete the line"
)),
}
}
fn presence_only(flag: &str) -> bool {
use std::sync::OnceLock;
static SET_TRUE: OnceLock<std::collections::HashSet<String>> = OnceLock::new();
SET_TRUE
.get_or_init(|| {
use clap::CommandFactory as _;
crate::cli::ServeArgs::command()
.get_arguments()
.filter(|a| matches!(a.get_action(), clap::ArgAction::SetTrue))
.filter_map(|a| a.get_long().map(str::to_string))
.collect()
})
.contains(flag)
}
#[cfg(test)]
#[path = "schema_tests.rs"]
mod tests;