use std::ffi::OsString;
use std::path::PathBuf;
use super::Cli;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Target {
Namespace(&'static str),
SelfBare,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Binary {
Litany,
Bl,
Bz,
Yog,
BlDelivery,
BlTracker,
ToolControl,
}
impl Binary {
const fn env_and_default(self) -> (&'static str, &'static str) {
match self {
Binary::Litany => ("LITANY_BINARY", "litany"),
Binary::Bl => ("BL_BINARY", "bl"),
Binary::Bz => ("BZ_BINARY", "bz"),
Binary::BlDelivery => ("BL_DELIVERY_BINARY", "bl-delivery"),
Binary::BlTracker => ("BL_TRACKER_BINARY", "bl-tracker"),
Binary::ToolControl => ("YOG_TOOL_CONTROL_BINARY", crate::control::SUBCMD),
Binary::Yog => ("YOG_BINARY", "yog"),
}
}
const fn target(self) -> Target {
match self {
Binary::Bl => Target::Namespace("bl"),
Binary::Bz => Target::Namespace("bz"),
Binary::Litany => Target::Namespace("litany"),
Binary::BlDelivery => Target::Namespace("bl-delivery"),
Binary::BlTracker => Target::Namespace("bl-tracker"),
Binary::ToolControl => Target::Namespace(crate::control::SUBCMD),
Binary::Yog => Target::SelfBare,
}
}
}
impl Cli {
pub fn new(binary: impl Into<PathBuf>) -> Self {
Self {
program: binary.into(),
prefix: Vec::new(),
env: Vec::new(),
wrapper: Vec::new(),
client: crate::registry::Client::default(),
}
}
fn self_target(current_exe: PathBuf, namespace: &str) -> Self {
Self {
program: current_exe,
prefix: vec![namespace.to_string()],
env: Vec::new(),
wrapper: Vec::new(),
client: crate::registry::Client::default(),
}
}
pub fn resolve(binary: Binary) -> Self {
Self::resolve_with(binary, |k| std::env::var_os(k), super::self_exe())
}
pub fn resolve_in_world(binary: Binary, overrides: &[(String, String)]) -> Self {
Self::resolve(binary).with_env(overrides.to_vec())
}
pub(crate) fn resolve_with(
binary: Binary,
lookup: impl Fn(&str) -> Option<OsString>,
current_exe: Option<PathBuf>,
) -> Self {
let (env_var, default) = binary.env_and_default();
match lookup(env_var) {
Some(v) if !v.is_empty() => Self::new(PathBuf::from(v)),
_ => Self::default_target(default, binary.target(), current_exe),
}
}
pub(crate) fn default_target(
default: &str,
target: Target,
current_exe: Option<PathBuf>,
) -> Self {
match (target, current_exe) {
(Target::Namespace(ns), Some(exe)) => Self::self_target(exe, ns),
(Target::SelfBare, Some(exe)) => Self::new(exe),
_ => Self::new(PathBuf::from(default)),
}
}
}