fn extract_package_name(line: &str, after: &str) -> Option<String> {
let parts: Vec<&str> = line.split_whitespace().collect();
let install_pos = find_install_position(&parts, after)?;
find_package_at_position(&parts, install_pos)
}
fn find_install_position(parts: &[&str], after: &str) -> Option<usize> {
match after {
"cargo install" => find_cargo_install_position(parts),
"npm install" => find_npm_install_position(parts),
"install" => find_simple_install_position(parts),
_ => None,
}
}
fn find_cargo_install_position(parts: &[&str]) -> Option<usize> {
parts.iter().position(|&p| p == "cargo")?;
parts
.iter()
.position(|&p| p == "install")
.map(|pos| pos + 1)
}
fn find_npm_install_position(parts: &[&str]) -> Option<usize> {
parts.iter().position(|&p| p == "npm")?;
parts
.iter()
.position(|&p| p == "install")
.map(|pos| pos + 1)
}
fn find_simple_install_position(parts: &[&str]) -> Option<usize> {
parts
.iter()
.position(|&p| p == "install")
.map(|pos| pos + 1)
}
fn find_package_at_position(parts: &[&str], position: usize) -> Option<String> {
if let Some(pkg) = get_valid_package(parts, position) {
return Some(pkg);
}
get_valid_package(parts, position + 1)
}
fn get_valid_package(parts: &[&str], position: usize) -> Option<String> {
parts
.get(position)
.filter(|pkg| !pkg.starts_with('-') && !pkg.is_empty())
.map(|pkg| (*pkg).to_string())
}