use crate::query;
pub(crate) fn first_positional(args: &[String]) -> Option<&str> {
let mut skip_next = false;
for a in args {
if skip_next {
skip_next = false;
continue;
}
if a == "--pick" {
skip_next = true;
continue;
}
if !a.starts_with("--") {
return Some(a.as_str());
}
}
None
}
pub(crate) fn parse_pick(args: &[String]) -> Result<Option<usize>, ()> {
let Some(idx) = args.iter().position(|a| a == "--pick") else {
return Ok(None);
};
let raw = args.get(idx + 1).map(String::as_str).unwrap_or("");
match raw.parse::<usize>() {
Ok(n) if n >= 1 => Ok(Some(n)),
_ => Err(()),
}
}
pub(crate) fn parse_int_js(s: &str) -> Option<i64> {
let s = s.trim_start();
let bytes = s.as_bytes();
let mut idx = 0;
if idx < bytes.len() && (bytes[idx] == b'+' || bytes[idx] == b'-') {
idx += 1;
}
let digits_start = idx;
while idx < bytes.len() && bytes[idx].is_ascii_digit() {
idx += 1;
}
if idx == digits_start {
return None;
}
s[..idx].parse::<i64>().ok()
}
pub(crate) fn index_options(args: &[String]) -> query::IndexOptions {
query::IndexOptions {
include_guesses: !args.iter().any(|a| a == "--no-guess"),
include_dispatch: !args.iter().any(|a| a == "--no-dispatch"),
}
}
pub(crate) fn output_flags(verb: &str, args: &[String]) -> Result<(bool, bool), (i32, String)> {
let json = args.iter().any(|a| a == "--json");
let compact = args.iter().any(|a| a == "--compact");
if json && compact {
return Err((
1,
format!("devscout {verb}: --compact and --json are mutually exclusive"),
));
}
Ok((json, compact))
}