use std::io::Write;
use std::path::Path;
use std::process::{Command, Stdio};
fn launch(command: &mut Command) -> Result<(), String> {
let child = command
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.map_err(|error| format!("no se pudo ejecutar xdg-open: {error}"))?;
crate::core::platform::launch::reap(child)
}
pub fn open_url(url: &str, _background: bool) -> Result<(), String> {
launch(Command::new("xdg-open").arg(url))
}
pub fn reveal(path: &Path) -> Result<(), String> {
let folder = if path.is_dir() { path } else { path.parent().unwrap_or(path) };
launch(Command::new("xdg-open").arg(folder))
}
pub fn trash(path: &Path) -> Result<(), String> {
let run = |mut command: Command| {
command.arg(path).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null()).status()
};
let mut gio = Command::new("gio");
gio.arg("trash");
match run(gio) {
Ok(status) if status.success() => Ok(()),
Ok(status) => Err(format!("gio respondió {status}")),
Err(_) => match run(Command::new("trash-put")) {
Ok(status) if status.success() => Ok(()),
_ => Err("instala gio (GLib) o trash-cli".into()),
},
}
}
pub fn low_priority_command(program: &str) -> Command {
if !Path::new("/usr/bin/nice").is_file() {
return Command::new(program);
}
let mut command = Command::new("/usr/bin/nice");
command.args(["-n", "10", program]);
command
}
const NO_STORE: &str = "no hay Secret Service: instala secret-tool (libsecret-tools)";
pub fn secret_set(service: &str, account: &str, value: &str) -> Result<(), String> {
let mut child = Command::new("secret-tool")
.args(["store", "--label", service, "service", service, "account", account])
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.map_err(|_| NO_STORE.to_owned())?;
let written = child.stdin.take().ok_or("secret-tool no abrió su entrada")?.write_all(value.as_bytes());
let status = child.wait().map_err(|error| format!("secret-tool no terminó: {error}"))?;
match (written, status.success()) {
(Ok(()), true) => Ok(()),
_ => Err(format!("secret-tool no guardó el valor ({status}); ¿hay un servicio de llaveros activo?")),
}
}
pub fn secret_get(service: &str, account: &str) -> Option<String> {
let output = Command::new("secret-tool")
.args(["lookup", "service", service, "account", account])
.stdin(Stdio::null())
.stderr(Stdio::null())
.output()
.ok()?;
output.status.success().then(|| String::from_utf8_lossy(&output.stdout).into_owned())
}
pub fn secret_remove(service: &str, account: &str) -> Result<(), String> {
let _ = Command::new("secret-tool")
.args(["clear", "service", service, "account", account])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
Ok(())
}