use crate::model::World;
use std::process::Command;
pub mod apt;
pub mod dnf;
pub mod flatpak;
pub mod pacman;
pub trait Backend {
fn name(&self) -> &'static str;
fn build_world(&self) -> Result<World, String>;
}
pub fn detect() -> Option<Box<dyn Backend>> {
if have("dpkg-query") || have("apt") {
return Some(Box::new(apt::Apt));
}
if have("dnf") || have("rpm") {
return Some(Box::new(dnf::Dnf));
}
if have("pacman") {
return Some(Box::new(pacman::Pacman));
}
None
}
fn have(bin: &str) -> bool {
Command::new("sh")
.args(["-c", &format!("command -v {bin}")])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
pub fn capture(bin: &str, args: &[&str]) -> Result<String, String> {
let out = Command::new(bin)
.args(args)
.env("LC_ALL", "C")
.env("LANG", "C")
.output()
.map_err(|e| format!("could not run `{bin}`: {e}"))?;
Ok(String::from_utf8_lossy(&out.stdout).into_owned())
}