use crate::config::{ARM64_TARGET, X64_TARGET};
use std::{
any::{Any, TypeId},
error::Error,
process::Command,
};
pub trait Param {
fn set(&mut self, s: String);
}
impl Param for String {
fn set(&mut self, s: String) {
*self = s;
}
}
impl Param for Option<bool> {
fn set(&mut self, s: String) {
*self = match s.as_str() {
"true" | "1" | "on" => Some(true),
"false" | "0" | "off" => Some(false),
_ => *self,
};
}
}
impl Param for bool {
fn set(&mut self, _: String) {
*self = !*self;
}
}
impl Param for Option<String> {
fn set(&mut self, s: String) {
*self = Some(s);
}
}
pub fn get_param<T: Any + Param + Clone>(
args: &mut Vec<String>,
key: &str,
default: T,
remove: bool,
) -> T {
let mut value = default.clone();
match args.iter().position(|x| x == key) {
Some(idx) => {
if value.type_id() == TypeId::of::<bool>() {
value.set(String::new());
if remove {
args.remove(idx);
}
} else {
if idx + 1 < args.len() {
value.set(args[idx + 1].clone());
if remove {
args.remove(idx);
args.remove(idx);
}
} else {
panic!("Missing value for {key}");
}
}
}
None => (),
}
value
}
pub fn get_channel_and_target(args: &mut Vec<String>) -> Result<(String, String), Box<dyn Error>> {
let line = String::from_utf8_lossy(
&Command::new("rustup")
.args(["show", "active-toolchain"])
.output()?
.stdout,
)
.trim()
.to_string();
let active_channel = line.split("-").next().unwrap().to_string();
let mut active_target =
get_param(args, "--target", X64_TARGET.to_string(), true).to_lowercase();
if active_target == "x86_64" || active_target == "x64" {
active_target = X64_TARGET.to_string();
}
if active_target == "arm64" || active_target == "aarch64" {
active_target = ARM64_TARGET.to_string();
}
if active_target != X64_TARGET && active_target != ARM64_TARGET {
panic!("Unsupported Target: {}", active_target);
}
Ok((active_channel, active_target))
}