use std::process::Command;
use crate::{extract_stdout, RustupTargetError};
pub type Triple = String;
#[derive(Debug)]
pub struct Target {
pub triple: Triple,
pub installed: bool,
}
impl std::fmt::Display for Target {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} - installed: {}", self.triple, self.installed)
}
}
pub fn list() -> Result<Vec<Target>, RustupTargetError> {
let output = Command::new("rustup")
.arg("target")
.arg("list")
.output()
.map_err(RustupTargetError::ProcessFailed)?;
let out = extract_stdout(&output)?;
parse_rustup_triple_list(&out)
}
pub fn installed() -> Result<Vec<Target>, RustupTargetError> {
let output = Command::new("rustup")
.arg("target")
.arg("list")
.arg("--installed")
.output()
.map_err(RustupTargetError::ProcessFailed)?;
let out = extract_stdout(&output)?;
parse_rustup_triple_list(&out)
}
pub fn install(list: &[Triple]) -> Result<(), RustupTargetError> {
let mut cmd = Command::new("rustup");
cmd.arg("target").arg("add");
for triple in list {
cmd.arg(triple);
}
let output = cmd.output().map_err(RustupTargetError::ProcessFailed)?;
let _out = extract_stdout(&output)?;
Ok(())
}
fn parse_rustup_triple_list(list: &str) -> Result<Vec<Target>, RustupTargetError> {
let mut targets = Vec::new();
for mut line in list.lines() {
let installed = if line.ends_with(" (installed)") {
line = &line[..line.len() - 12];
true
} else {
false
};
let triple = Triple::from(line);
targets.push(Target { triple, installed });
}
Ok(targets)
}
#[test]
fn test_parse_list() {
let list = r###"aarch64-apple-darwin (installed)
aarch64-apple-ios (installed)
aarch64-apple-ios-sim (installed)
aarch64-fuchsiaarch64-linux-android (installed)
aarch64-pc-windows-msvc"###;
let triples = parse_rustup_triple_list(list).unwrap();
let re_composed = triples
.iter()
.map(|t| format!("{t}"))
.collect::<Vec<_>>()
.join("\n");
insta::assert_snapshot!(re_composed, @r###"
aarch64-apple-darwin - installed: true
aarch64-apple-ios - installed: true
aarch64-apple-ios-sim - installed: true
aarch64-fuchsiaarch64-linux-android - installed: true
aarch64-pc-windows-msvc - installed: false
"###
);
}