xdg-termfilechooser-bridge 0.2.6

The bridge between xdg-desktop-portal-termfilechooser and your favorite terminal based filepicker
use std::{process::Command, str::FromStr};

use log::info;
use serde::{Deserialize, Serialize};
use which::which;

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
pub enum Terminal {
    Alacritty,
    Foot,
    Ghostty,
    Kitty,
    Xterm,
}

fn command_name(term: &Terminal) -> Option<String> {
    match term {
        Terminal::Alacritty => String::from_str("alacritty").map_or(None, Some),
        Terminal::Ghostty => String::from_str("ghostty").map_or(None, Some),
        Terminal::Kitty => String::from_str("kitty").map_or(None, Some),
        Terminal::Xterm => String::from_str("xterm").map_or(None, Some),
        Terminal::Foot => String::from_str("foot").map_or(None, Some),
    }
}

pub fn terminal_from_env() -> Terminal {
    if let Ok(_) = which("ghostty") {
        return Terminal::Ghostty;
    }

    if let Ok(_) = which("kitty") {
        return Terminal::Kitty;
    }

    if let Ok(_) = which("alacritty") {
        return Terminal::Alacritty;
    }

    if let Ok(_) = which("foot") {
        return Terminal::Foot;
    }

    return Terminal::Xterm;
}

pub fn run_command(term: Terminal, run_cmd: &str) {
    let command = command_name(&term)
        .map_or(None, |command| which(command).map_or(None, Some))
        .expect(format!("could not determine command for terminal: {:?}", &term).as_str());

    info!("determined terminal command: {:?}", &command);

    Command::new(command)
        .arg("-e")
        .arg("/bin/sh")
        .arg("-c")
        .arg(run_cmd)
        .output()
        .expect(format!("failed to execute command {:?}", run_cmd).as_str());
}