use std::process::Command;
pub async fn which(command: &str) -> Option<String> {
which_impl(command).await
}
pub fn which_sync(command: &str) -> Option<String> {
which_impl_sync(command)
}
async fn which_impl(command: &str) -> Option<String> {
#[cfg(target_os = "windows")]
{
let output = Command::new("where.exe").arg(command).output().ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8_lossy(&output.stdout);
let trimmed = stdout.trim();
if trimmed.is_empty() {
return None;
}
trimmed.split('\n').next().map(|s| s.trim().to_string())
}
#[cfg(not(target_os = "windows"))]
{
let output = Command::new("which").arg(command).output().ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8_lossy(&output.stdout);
let trimmed = stdout.trim();
if trimmed.is_empty() {
return None;
}
Some(trimmed.to_string())
}
}
fn which_impl_sync(command: &str) -> Option<String> {
#[cfg(target_os = "windows")]
{
let output = Command::new("where.exe").arg(command).output().ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8_lossy(&output.stdout);
let trimmed = stdout.trim();
if trimmed.is_empty() {
return None;
}
trimmed.split('\n').next().map(|s| s.trim().to_string())
}
#[cfg(not(target_os = "windows"))]
{
let output = Command::new("which").arg(command).output().ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8_lossy(&output.stdout);
let trimmed = stdout.trim();
if trimmed.is_empty() {
return None;
}
Some(trimmed.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_which_sync_existing_command() {
let result = which_sync("ls");
assert!(result.is_some());
}
#[test]
fn test_which_sync_nonexistent_command() {
let result = which_sync("nonexistent_command_xyz123");
assert!(result.is_none());
}
#[tokio::test]
async fn test_which_async_existing_command() {
let result = which("ls").await;
assert!(result.is_some());
}
#[tokio::test]
async fn test_which_async_nonexistent_command() {
let result = which("nonexistent_command_xyz123").await;
assert!(result.is_none());
}
}